LLVM  6.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 #include <sstream>
26 
27 #define DEBUG_TYPE "legalizer"
28 
29 using namespace llvm;
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 Action = LI.getAction(MI, MRI);
41  switch (std::get<0>(Action)) {
43  DEBUG(dbgs() << ".. Already legal\n");
44  return AlreadyLegal;
46  DEBUG(dbgs() << ".. Convert to libcall\n");
47  return libcall(MI);
49  DEBUG(dbgs() << ".. Narrow scalar\n");
50  return narrowScalar(MI, std::get<1>(Action), std::get<2>(Action));
52  DEBUG(dbgs() << ".. Widen scalar\n");
53  return widenScalar(MI, std::get<1>(Action), std::get<2>(Action));
55  DEBUG(dbgs() << ".. Lower\n");
56  return lower(MI, std::get<1>(Action), std::get<2>(Action));
58  DEBUG(dbgs() << ".. Reduce number of elements\n");
59  return fewerElementsVector(MI, std::get<1>(Action), std::get<2>(Action));
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_FREM:
98  return Size == 64 ? RTLIB::REM_F64 : RTLIB::REM_F32;
99  case TargetOpcode::G_FPOW:
100  return Size == 64 ? RTLIB::POW_F64 : RTLIB::POW_F32;
101  }
102  llvm_unreachable("Unknown libcall function");
103 }
104 
107  const CallLowering::ArgInfo &Result,
109  auto &CLI = *MIRBuilder.getMF().getSubtarget().getCallLowering();
110  auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
111  const char *Name = TLI.getLibcallName(Libcall);
112 
113  MIRBuilder.getMF().getFrameInfo().setHasCalls(true);
114  if (!CLI.lowerCall(MIRBuilder, TLI.getLibcallCallingConv(Libcall),
115  MachineOperand::CreateES(Name), Result, Args))
117 
119 }
120 
123  Type *OpType) {
124  auto Libcall = getRTLibDesc(MI.getOpcode(), Size);
125  return createLibcall(MIRBuilder, Libcall, {MI.getOperand(0).getReg(), OpType},
126  {{MI.getOperand(1).getReg(), OpType},
127  {MI.getOperand(2).getReg(), OpType}});
128 }
129 
132  LLT LLTy = MRI.getType(MI.getOperand(0).getReg());
133  unsigned Size = LLTy.getSizeInBits();
134  auto &Ctx = MIRBuilder.getMF().getFunction()->getContext();
135 
136  MIRBuilder.setInstr(MI);
137 
138  switch (MI.getOpcode()) {
139  default:
140  return UnableToLegalize;
141  case TargetOpcode::G_SDIV:
142  case TargetOpcode::G_UDIV:
143  case TargetOpcode::G_SREM:
144  case TargetOpcode::G_UREM: {
145  Type *HLTy = Type::getInt32Ty(Ctx);
146  auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy);
147  if (Status != Legalized)
148  return Status;
149  break;
150  }
151  case TargetOpcode::G_FADD:
152  case TargetOpcode::G_FSUB:
153  case TargetOpcode::G_FPOW:
154  case TargetOpcode::G_FREM: {
155  Type *HLTy = Size == 64 ? Type::getDoubleTy(Ctx) : Type::getFloatTy(Ctx);
156  auto Status = simpleLibcall(MI, MIRBuilder, Size, HLTy);
157  if (Status != Legalized)
158  return Status;
159  break;
160  }
161  }
162 
163  MI.eraseFromParent();
164  return Legalized;
165 }
166 
168  unsigned TypeIdx,
169  LLT NarrowTy) {
170  // FIXME: Don't know how to handle secondary types yet.
171  if (TypeIdx != 0 && MI.getOpcode() != TargetOpcode::G_EXTRACT)
172  return UnableToLegalize;
173 
174  MIRBuilder.setInstr(MI);
175 
176  int64_t SizeOp0 = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits();
177  int64_t NarrowSize = NarrowTy.getSizeInBits();
178 
179  switch (MI.getOpcode()) {
180  default:
181  return UnableToLegalize;
182  case TargetOpcode::G_IMPLICIT_DEF: {
183  // FIXME: add support for when SizeOp0 isn't an exact multiple of
184  // NarrowSize.
185  if (SizeOp0 % NarrowSize != 0)
186  return UnableToLegalize;
187  int NumParts = SizeOp0 / NarrowSize;
188 
189  SmallVector<unsigned, 2> DstRegs;
190  for (int i = 0; i < NumParts; ++i) {
191  unsigned Dst = MRI.createGenericVirtualRegister(NarrowTy);
192  MIRBuilder.buildUndef(Dst);
193  DstRegs.push_back(Dst);
194  }
195  MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs);
196  MI.eraseFromParent();
197  return Legalized;
198  }
199  case TargetOpcode::G_ADD: {
200  // FIXME: add support for when SizeOp0 isn't an exact multiple of
201  // NarrowSize.
202  if (SizeOp0 % NarrowSize != 0)
203  return UnableToLegalize;
204  // Expand in terms of carry-setting/consuming G_ADDE instructions.
205  int NumParts = SizeOp0 / NarrowTy.getSizeInBits();
206 
207  SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
208  extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
209  extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
210 
211  unsigned CarryIn = MRI.createGenericVirtualRegister(LLT::scalar(1));
212  MIRBuilder.buildConstant(CarryIn, 0);
213 
214  for (int i = 0; i < NumParts; ++i) {
215  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
216  unsigned CarryOut = MRI.createGenericVirtualRegister(LLT::scalar(1));
217 
218  MIRBuilder.buildUAdde(DstReg, CarryOut, Src1Regs[i],
219  Src2Regs[i], CarryIn);
220 
221  DstRegs.push_back(DstReg);
222  CarryIn = CarryOut;
223  }
224  unsigned DstReg = MI.getOperand(0).getReg();
225  MIRBuilder.buildMerge(DstReg, DstRegs);
226  MI.eraseFromParent();
227  return Legalized;
228  }
229  case TargetOpcode::G_EXTRACT: {
230  if (TypeIdx != 1)
231  return UnableToLegalize;
232 
233  int64_t SizeOp1 = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits();
234  // FIXME: add support for when SizeOp1 isn't an exact multiple of
235  // NarrowSize.
236  if (SizeOp1 % NarrowSize != 0)
237  return UnableToLegalize;
238  int NumParts = SizeOp1 / NarrowSize;
239 
240  SmallVector<unsigned, 2> SrcRegs, DstRegs;
241  SmallVector<uint64_t, 2> Indexes;
242  extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
243 
244  unsigned OpReg = MI.getOperand(0).getReg();
245  int64_t OpStart = MI.getOperand(2).getImm();
246  int64_t OpSize = MRI.getType(OpReg).getSizeInBits();
247  for (int i = 0; i < NumParts; ++i) {
248  unsigned SrcStart = i * NarrowSize;
249 
250  if (SrcStart + NarrowSize <= OpStart || SrcStart >= OpStart + OpSize) {
251  // No part of the extract uses this subregister, ignore it.
252  continue;
253  } else if (SrcStart == OpStart && NarrowTy == MRI.getType(OpReg)) {
254  // The entire subregister is extracted, forward the value.
255  DstRegs.push_back(SrcRegs[i]);
256  continue;
257  }
258 
259  // OpSegStart is where this destination segment would start in OpReg if it
260  // extended infinitely in both directions.
261  int64_t ExtractOffset, SegSize;
262  if (OpStart < SrcStart) {
263  ExtractOffset = 0;
264  SegSize = std::min(NarrowSize, OpStart + OpSize - SrcStart);
265  } else {
266  ExtractOffset = OpStart - SrcStart;
267  SegSize = std::min(SrcStart + NarrowSize - OpStart, OpSize);
268  }
269 
270  unsigned SegReg = SrcRegs[i];
271  if (ExtractOffset != 0 || SegSize != NarrowSize) {
272  // A genuine extract is needed.
273  SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
274  MIRBuilder.buildExtract(SegReg, SrcRegs[i], ExtractOffset);
275  }
276 
277  DstRegs.push_back(SegReg);
278  }
279 
280  MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs);
281  MI.eraseFromParent();
282  return Legalized;
283  }
284  case TargetOpcode::G_INSERT: {
285  // FIXME: add support for when SizeOp0 isn't an exact multiple of
286  // NarrowSize.
287  if (SizeOp0 % NarrowSize != 0)
288  return UnableToLegalize;
289 
290  int NumParts = SizeOp0 / NarrowSize;
291 
292  SmallVector<unsigned, 2> SrcRegs, DstRegs;
293  SmallVector<uint64_t, 2> Indexes;
294  extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, SrcRegs);
295 
296  unsigned OpReg = MI.getOperand(2).getReg();
297  int64_t OpStart = MI.getOperand(3).getImm();
298  int64_t OpSize = MRI.getType(OpReg).getSizeInBits();
299  for (int i = 0; i < NumParts; ++i) {
300  unsigned DstStart = i * NarrowSize;
301 
302  if (DstStart + NarrowSize <= OpStart || DstStart >= OpStart + OpSize) {
303  // No part of the insert affects this subregister, forward the original.
304  DstRegs.push_back(SrcRegs[i]);
305  continue;
306  } else if (DstStart == OpStart && NarrowTy == MRI.getType(OpReg)) {
307  // The entire subregister is defined by this insert, forward the new
308  // value.
309  DstRegs.push_back(OpReg);
310  continue;
311  }
312 
313  // OpSegStart is where this destination segment would start in OpReg if it
314  // extended infinitely in both directions.
315  int64_t ExtractOffset, InsertOffset, SegSize;
316  if (OpStart < DstStart) {
317  InsertOffset = 0;
318  ExtractOffset = DstStart - OpStart;
319  SegSize = std::min(NarrowSize, OpStart + OpSize - DstStart);
320  } else {
321  InsertOffset = OpStart - DstStart;
322  ExtractOffset = 0;
323  SegSize =
324  std::min(NarrowSize - InsertOffset, OpStart + OpSize - DstStart);
325  }
326 
327  unsigned SegReg = OpReg;
328  if (ExtractOffset != 0 || SegSize != OpSize) {
329  // A genuine extract is needed.
330  SegReg = MRI.createGenericVirtualRegister(LLT::scalar(SegSize));
331  MIRBuilder.buildExtract(SegReg, OpReg, ExtractOffset);
332  }
333 
334  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
335  MIRBuilder.buildInsert(DstReg, SrcRegs[i], SegReg, InsertOffset);
336  DstRegs.push_back(DstReg);
337  }
338 
339  assert(DstRegs.size() == (unsigned)NumParts && "not all parts covered");
340  MIRBuilder.buildMerge(MI.getOperand(0).getReg(), DstRegs);
341  MI.eraseFromParent();
342  return Legalized;
343  }
344  case TargetOpcode::G_LOAD: {
345  // FIXME: add support for when SizeOp0 isn't an exact multiple of
346  // NarrowSize.
347  if (SizeOp0 % NarrowSize != 0)
348  return UnableToLegalize;
349  int NumParts = SizeOp0 / NarrowSize;
350  LLT OffsetTy = LLT::scalar(
351  MRI.getType(MI.getOperand(1).getReg()).getScalarSizeInBits());
352 
353  SmallVector<unsigned, 2> DstRegs;
354  for (int i = 0; i < NumParts; ++i) {
355  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
356  unsigned SrcReg = 0;
357  unsigned Adjustment = i * NarrowSize / 8;
358 
359  MIRBuilder.materializeGEP(SrcReg, MI.getOperand(1).getReg(), OffsetTy,
360  Adjustment);
361 
362  // TODO: This is conservatively correct, but we probably want to split the
363  // memory operands in the future.
364  MIRBuilder.buildLoad(DstReg, SrcReg, **MI.memoperands_begin());
365 
366  DstRegs.push_back(DstReg);
367  }
368  unsigned DstReg = MI.getOperand(0).getReg();
369  MIRBuilder.buildMerge(DstReg, DstRegs);
370  MI.eraseFromParent();
371  return Legalized;
372  }
373  case TargetOpcode::G_STORE: {
374  // FIXME: add support for when SizeOp0 isn't an exact multiple of
375  // NarrowSize.
376  if (SizeOp0 % NarrowSize != 0)
377  return UnableToLegalize;
378  int NumParts = SizeOp0 / NarrowSize;
379  LLT OffsetTy = LLT::scalar(
380  MRI.getType(MI.getOperand(1).getReg()).getScalarSizeInBits());
381 
382  SmallVector<unsigned, 2> SrcRegs;
383  extractParts(MI.getOperand(0).getReg(), NarrowTy, NumParts, SrcRegs);
384 
385  for (int i = 0; i < NumParts; ++i) {
386  unsigned DstReg = 0;
387  unsigned Adjustment = i * NarrowSize / 8;
388 
389  MIRBuilder.materializeGEP(DstReg, MI.getOperand(1).getReg(), OffsetTy,
390  Adjustment);
391 
392  // TODO: This is conservatively correct, but we probably want to split the
393  // memory operands in the future.
394  MIRBuilder.buildStore(SrcRegs[i], DstReg, **MI.memoperands_begin());
395  }
396  MI.eraseFromParent();
397  return Legalized;
398  }
399  case TargetOpcode::G_CONSTANT: {
400  // FIXME: add support for when SizeOp0 isn't an exact multiple of
401  // NarrowSize.
402  if (SizeOp0 % NarrowSize != 0)
403  return UnableToLegalize;
404  int NumParts = SizeOp0 / NarrowSize;
405  const APInt &Cst = MI.getOperand(1).getCImm()->getValue();
407 
408  SmallVector<unsigned, 2> DstRegs;
409  for (int i = 0; i < NumParts; ++i) {
410  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
411  ConstantInt *CI =
412  ConstantInt::get(Ctx, Cst.lshr(NarrowSize * i).trunc(NarrowSize));
413  MIRBuilder.buildConstant(DstReg, *CI);
414  DstRegs.push_back(DstReg);
415  }
416  unsigned DstReg = MI.getOperand(0).getReg();
417  MIRBuilder.buildMerge(DstReg, DstRegs);
418  MI.eraseFromParent();
419  return Legalized;
420  }
421  case TargetOpcode::G_OR: {
422  // Legalize bitwise operation:
423  // A = BinOp<Ty> B, C
424  // into:
425  // B1, ..., BN = G_UNMERGE_VALUES B
426  // C1, ..., CN = G_UNMERGE_VALUES C
427  // A1 = BinOp<Ty/N> B1, C2
428  // ...
429  // AN = BinOp<Ty/N> BN, CN
430  // A = G_MERGE_VALUES A1, ..., AN
431 
432  // FIXME: add support for when SizeOp0 isn't an exact multiple of
433  // NarrowSize.
434  if (SizeOp0 % NarrowSize != 0)
435  return UnableToLegalize;
436  int NumParts = SizeOp0 / NarrowSize;
437 
438  // List the registers where the destination will be scattered.
439  SmallVector<unsigned, 2> DstRegs;
440  // List the registers where the first argument will be split.
441  SmallVector<unsigned, 2> SrcsReg1;
442  // List the registers where the second argument will be split.
443  SmallVector<unsigned, 2> SrcsReg2;
444  // Create all the temporary registers.
445  for (int i = 0; i < NumParts; ++i) {
446  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
447  unsigned SrcReg1 = MRI.createGenericVirtualRegister(NarrowTy);
448  unsigned SrcReg2 = MRI.createGenericVirtualRegister(NarrowTy);
449 
450  DstRegs.push_back(DstReg);
451  SrcsReg1.push_back(SrcReg1);
452  SrcsReg2.push_back(SrcReg2);
453  }
454  // Explode the big arguments into smaller chunks.
455  MIRBuilder.buildUnmerge(SrcsReg1, MI.getOperand(1).getReg());
456  MIRBuilder.buildUnmerge(SrcsReg2, MI.getOperand(2).getReg());
457 
458  // Do the operation on each small part.
459  for (int i = 0; i < NumParts; ++i)
460  MIRBuilder.buildOr(DstRegs[i], SrcsReg1[i], SrcsReg2[i]);
461 
462  // Gather the destination registers into the final destination.
463  unsigned DstReg = MI.getOperand(0).getReg();
464  MIRBuilder.buildMerge(DstReg, DstRegs);
465  MI.eraseFromParent();
466  return Legalized;
467  }
468  }
469 }
470 
472 LegalizerHelper::widenScalar(MachineInstr &MI, unsigned TypeIdx, LLT WideTy) {
473  MIRBuilder.setInstr(MI);
474 
475  switch (MI.getOpcode()) {
476  default:
477  return UnableToLegalize;
478  case TargetOpcode::G_ADD:
479  case TargetOpcode::G_AND:
480  case TargetOpcode::G_MUL:
481  case TargetOpcode::G_OR:
482  case TargetOpcode::G_XOR:
483  case TargetOpcode::G_SUB:
484  case TargetOpcode::G_SHL: {
485  // Perform operation at larger width (any extension is fine here, high bits
486  // don't affect the result) and then truncate the result back to the
487  // original type.
488  unsigned Src1Ext = MRI.createGenericVirtualRegister(WideTy);
489  unsigned Src2Ext = MRI.createGenericVirtualRegister(WideTy);
490  MIRBuilder.buildAnyExt(Src1Ext, MI.getOperand(1).getReg());
491  MIRBuilder.buildAnyExt(Src2Ext, MI.getOperand(2).getReg());
492 
493  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
495  .addDef(DstExt)
496  .addUse(Src1Ext)
497  .addUse(Src2Ext);
498 
499  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
500  MI.eraseFromParent();
501  return Legalized;
502  }
503  case TargetOpcode::G_SDIV:
504  case TargetOpcode::G_UDIV:
505  case TargetOpcode::G_SREM:
506  case TargetOpcode::G_UREM:
507  case TargetOpcode::G_ASHR:
508  case TargetOpcode::G_LSHR: {
509  unsigned ExtOp = MI.getOpcode() == TargetOpcode::G_SDIV ||
510  MI.getOpcode() == TargetOpcode::G_SREM ||
511  MI.getOpcode() == TargetOpcode::G_ASHR
512  ? TargetOpcode::G_SEXT
513  : TargetOpcode::G_ZEXT;
514 
515  unsigned LHSExt = MRI.createGenericVirtualRegister(WideTy);
516  MIRBuilder.buildInstr(ExtOp).addDef(LHSExt).addUse(
517  MI.getOperand(1).getReg());
518 
519  unsigned RHSExt = MRI.createGenericVirtualRegister(WideTy);
520  MIRBuilder.buildInstr(ExtOp).addDef(RHSExt).addUse(
521  MI.getOperand(2).getReg());
522 
523  unsigned ResExt = MRI.createGenericVirtualRegister(WideTy);
525  .addDef(ResExt)
526  .addUse(LHSExt)
527  .addUse(RHSExt);
528 
529  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), ResExt);
530  MI.eraseFromParent();
531  return Legalized;
532  }
533  case TargetOpcode::G_SELECT: {
534  if (TypeIdx != 0)
535  return UnableToLegalize;
536 
537  // Perform operation at larger width (any extension is fine here, high bits
538  // don't affect the result) and then truncate the result back to the
539  // original type.
540  unsigned Src1Ext = MRI.createGenericVirtualRegister(WideTy);
541  unsigned Src2Ext = MRI.createGenericVirtualRegister(WideTy);
542  MIRBuilder.buildAnyExt(Src1Ext, MI.getOperand(2).getReg());
543  MIRBuilder.buildAnyExt(Src2Ext, MI.getOperand(3).getReg());
544 
545  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
546  MIRBuilder.buildInstr(TargetOpcode::G_SELECT)
547  .addDef(DstExt)
548  .addReg(MI.getOperand(1).getReg())
549  .addUse(Src1Ext)
550  .addUse(Src2Ext);
551 
552  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
553  MI.eraseFromParent();
554  return Legalized;
555  }
556  case TargetOpcode::G_FPTOSI:
557  case TargetOpcode::G_FPTOUI: {
558  if (TypeIdx != 0)
559  return UnableToLegalize;
560 
561  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
563  .addDef(DstExt)
564  .addUse(MI.getOperand(1).getReg());
565 
566  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
567  MI.eraseFromParent();
568  return Legalized;
569  }
570  case TargetOpcode::G_SITOFP:
571  case TargetOpcode::G_UITOFP: {
572  if (TypeIdx != 1)
573  return UnableToLegalize;
574 
575  unsigned Src = MI.getOperand(1).getReg();
576  unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy);
577 
578  if (MI.getOpcode() == TargetOpcode::G_SITOFP) {
579  MIRBuilder.buildSExt(SrcExt, Src);
580  } else {
581  assert(MI.getOpcode() == TargetOpcode::G_UITOFP && "Unexpected conv op");
582  MIRBuilder.buildZExt(SrcExt, Src);
583  }
584 
586  .addDef(MI.getOperand(0).getReg())
587  .addUse(SrcExt);
588 
589  MI.eraseFromParent();
590  return Legalized;
591  }
592  case TargetOpcode::G_INSERT: {
593  if (TypeIdx != 0)
594  return UnableToLegalize;
595 
596  unsigned Src = MI.getOperand(1).getReg();
597  unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy);
598  MIRBuilder.buildAnyExt(SrcExt, Src);
599 
600  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
601  auto MIB = MIRBuilder.buildInsert(DstExt, SrcExt, MI.getOperand(2).getReg(),
602  MI.getOperand(3).getImm());
603  for (unsigned OpNum = 4; OpNum < MI.getNumOperands(); OpNum += 2) {
604  MIB.addReg(MI.getOperand(OpNum).getReg());
605  MIB.addImm(MI.getOperand(OpNum + 1).getImm());
606  }
607 
608  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
609  MI.eraseFromParent();
610  return Legalized;
611  }
612  case TargetOpcode::G_LOAD: {
613  assert(alignTo(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(), 8) ==
614  WideTy.getSizeInBits() &&
615  "illegal to increase number of bytes loaded");
616 
617  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
618  MIRBuilder.buildLoad(DstExt, MI.getOperand(1).getReg(),
619  **MI.memoperands_begin());
620  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
621  MI.eraseFromParent();
622  return Legalized;
623  }
624  case TargetOpcode::G_STORE: {
625  if (MRI.getType(MI.getOperand(0).getReg()) != LLT::scalar(1) ||
626  WideTy != LLT::scalar(8))
627  return UnableToLegalize;
628 
629  auto &TLI = *MIRBuilder.getMF().getSubtarget().getTargetLowering();
630  auto Content = TLI.getBooleanContents(false, false);
631 
632  unsigned ExtOp = TargetOpcode::G_ANYEXT;
634  ExtOp = TargetOpcode::G_ZEXT;
636  ExtOp = TargetOpcode::G_SEXT;
637  else
638  ExtOp = TargetOpcode::G_ANYEXT;
639 
640  unsigned SrcExt = MRI.createGenericVirtualRegister(WideTy);
641  MIRBuilder.buildInstr(ExtOp).addDef(SrcExt).addUse(
642  MI.getOperand(0).getReg());
643  MIRBuilder.buildStore(SrcExt, MI.getOperand(1).getReg(),
644  **MI.memoperands_begin());
645  MI.eraseFromParent();
646  return Legalized;
647  }
648  case TargetOpcode::G_CONSTANT: {
649  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
650  MIRBuilder.buildConstant(DstExt, *MI.getOperand(1).getCImm());
651  MIRBuilder.buildTrunc(MI.getOperand(0).getReg(), DstExt);
652  MI.eraseFromParent();
653  return Legalized;
654  }
655  case TargetOpcode::G_FCONSTANT: {
656  unsigned DstExt = MRI.createGenericVirtualRegister(WideTy);
657  MIRBuilder.buildFConstant(DstExt, *MI.getOperand(1).getFPImm());
658  MIRBuilder.buildFPTrunc(MI.getOperand(0).getReg(), DstExt);
659  MI.eraseFromParent();
660  return Legalized;
661  }
662  case TargetOpcode::G_BRCOND: {
663  unsigned TstExt = MRI.createGenericVirtualRegister(WideTy);
664  MIRBuilder.buildAnyExt(TstExt, MI.getOperand(0).getReg());
665  MIRBuilder.buildBrCond(TstExt, *MI.getOperand(1).getMBB());
666  MI.eraseFromParent();
667  return Legalized;
668  }
669  case TargetOpcode::G_FCMP: {
670  unsigned Op0Ext, Op1Ext, DstReg;
671  unsigned Cmp1 = MI.getOperand(2).getReg();
672  unsigned Cmp2 = MI.getOperand(3).getReg();
673  if (TypeIdx == 0) {
674  Op0Ext = Cmp1;
675  Op1Ext = Cmp2;
676  DstReg = MRI.createGenericVirtualRegister(WideTy);
677  } else {
678  Op0Ext = MRI.createGenericVirtualRegister(WideTy);
679  Op1Ext = MRI.createGenericVirtualRegister(WideTy);
680  DstReg = MI.getOperand(0).getReg();
681  MIRBuilder.buildInstr(TargetOpcode::G_FPEXT, Op0Ext, Cmp1);
682  MIRBuilder.buildInstr(TargetOpcode::G_FPEXT, Op1Ext, Cmp2);
683  }
685  static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()),
686  DstReg, Op0Ext, Op1Ext);
687  if (TypeIdx == 0)
688  MIRBuilder.buildInstr(TargetOpcode::G_TRUNC, MI.getOperand(0).getReg(),
689  DstReg);
690  MI.eraseFromParent();
691  return Legalized;
692  }
693  case TargetOpcode::G_ICMP: {
694  bool IsSigned = CmpInst::isSigned(
695  static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()));
696  unsigned Cmp1 = MI.getOperand(2).getReg();
697  unsigned Cmp2 = MI.getOperand(3).getReg();
698  unsigned Op0Ext, Op1Ext, DstReg;
699  if (TypeIdx == 0) {
700  Op0Ext = Cmp1;
701  Op1Ext = Cmp2;
702  DstReg = MRI.createGenericVirtualRegister(WideTy);
703  } else {
704  Op0Ext = MRI.createGenericVirtualRegister(WideTy);
705  Op1Ext = MRI.createGenericVirtualRegister(WideTy);
706  DstReg = MI.getOperand(0).getReg();
707  if (IsSigned) {
708  MIRBuilder.buildSExt(Op0Ext, Cmp1);
709  MIRBuilder.buildSExt(Op1Ext, Cmp2);
710  } else {
711  MIRBuilder.buildZExt(Op0Ext, Cmp1);
712  MIRBuilder.buildZExt(Op1Ext, Cmp2);
713  }
714  }
716  static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()),
717  DstReg, Op0Ext, Op1Ext);
718  if (TypeIdx == 0)
719  MIRBuilder.buildInstr(TargetOpcode::G_TRUNC, MI.getOperand(0).getReg(),
720  DstReg);
721  MI.eraseFromParent();
722  return Legalized;
723  }
724  case TargetOpcode::G_GEP: {
725  assert(TypeIdx == 1 && "unable to legalize pointer of GEP");
726  unsigned OffsetExt = MRI.createGenericVirtualRegister(WideTy);
727  MIRBuilder.buildSExt(OffsetExt, MI.getOperand(2).getReg());
728  MI.getOperand(2).setReg(OffsetExt);
729  return Legalized;
730  }
731  case TargetOpcode::G_PHI: {
732  assert(TypeIdx == 0 && "Expecting only Idx 0");
733  auto getExtendedReg = [&](unsigned Reg, MachineBasicBlock &MBB) {
734  auto FirstTermIt = MBB.getFirstTerminator();
735  MIRBuilder.setInsertPt(MBB, FirstTermIt);
736  MachineInstr *DefMI = MRI.getVRegDef(Reg);
738  if (DefMI->getOpcode() == TargetOpcode::G_TRUNC)
739  MIB = MIRBuilder.buildAnyExtOrTrunc(WideTy,
740  DefMI->getOperand(1).getReg());
741  else
742  MIB = MIRBuilder.buildAnyExt(WideTy, Reg);
743  return MIB->getOperand(0).getReg();
744  };
745  auto MIB = MIRBuilder.buildInstr(TargetOpcode::G_PHI, WideTy);
746  for (auto OpIt = MI.operands_begin() + 1, OpE = MI.operands_end();
747  OpIt != OpE;) {
748  unsigned Reg = OpIt++->getReg();
749  MachineBasicBlock *OpMBB = OpIt++->getMBB();
750  MIB.addReg(getExtendedReg(Reg, *OpMBB));
751  MIB.addMBB(OpMBB);
752  }
753  auto *MBB = MI.getParent();
754  MIRBuilder.setInsertPt(*MBB, MBB->getFirstNonPHI());
756  MIB->getOperand(0).getReg());
757  MI.eraseFromParent();
758  return Legalized;
759  }
760  }
761 }
762 
764 LegalizerHelper::lower(MachineInstr &MI, unsigned TypeIdx, LLT Ty) {
765  using namespace TargetOpcode;
766  MIRBuilder.setInstr(MI);
767 
768  switch(MI.getOpcode()) {
769  default:
770  return UnableToLegalize;
771  case TargetOpcode::G_SREM:
772  case TargetOpcode::G_UREM: {
773  unsigned QuotReg = MRI.createGenericVirtualRegister(Ty);
774  MIRBuilder.buildInstr(MI.getOpcode() == G_SREM ? G_SDIV : G_UDIV)
775  .addDef(QuotReg)
776  .addUse(MI.getOperand(1).getReg())
777  .addUse(MI.getOperand(2).getReg());
778 
779  unsigned ProdReg = MRI.createGenericVirtualRegister(Ty);
780  MIRBuilder.buildMul(ProdReg, QuotReg, MI.getOperand(2).getReg());
782  ProdReg);
783  MI.eraseFromParent();
784  return Legalized;
785  }
786  case TargetOpcode::G_SMULO:
787  case TargetOpcode::G_UMULO: {
788  // Generate G_UMULH/G_SMULH to check for overflow and a normal G_MUL for the
789  // result.
790  unsigned Res = MI.getOperand(0).getReg();
791  unsigned Overflow = MI.getOperand(1).getReg();
792  unsigned LHS = MI.getOperand(2).getReg();
793  unsigned RHS = MI.getOperand(3).getReg();
794 
795  MIRBuilder.buildMul(Res, LHS, RHS);
796 
797  unsigned Opcode = MI.getOpcode() == TargetOpcode::G_SMULO
798  ? TargetOpcode::G_SMULH
799  : TargetOpcode::G_UMULH;
800 
801  unsigned HiPart = MRI.createGenericVirtualRegister(Ty);
802  MIRBuilder.buildInstr(Opcode)
803  .addDef(HiPart)
804  .addUse(LHS)
805  .addUse(RHS);
806 
807  unsigned Zero = MRI.createGenericVirtualRegister(Ty);
808  MIRBuilder.buildConstant(Zero, 0);
809  MIRBuilder.buildICmp(CmpInst::ICMP_NE, Overflow, HiPart, Zero);
810  MI.eraseFromParent();
811  return Legalized;
812  }
813  case TargetOpcode::G_FNEG: {
814  // TODO: Handle vector types once we are able to
815  // represent them.
816  if (Ty.isVector())
817  return UnableToLegalize;
818  unsigned Res = MI.getOperand(0).getReg();
819  Type *ZeroTy;
821  switch (Ty.getSizeInBits()) {
822  case 16:
823  ZeroTy = Type::getHalfTy(Ctx);
824  break;
825  case 32:
826  ZeroTy = Type::getFloatTy(Ctx);
827  break;
828  case 64:
829  ZeroTy = Type::getDoubleTy(Ctx);
830  break;
831  default:
832  llvm_unreachable("unexpected floating-point type");
833  }
834  ConstantFP &ZeroForNegation =
835  *cast<ConstantFP>(ConstantFP::getZeroValueForNegation(ZeroTy));
836  unsigned Zero = MRI.createGenericVirtualRegister(Ty);
837  MIRBuilder.buildFConstant(Zero, ZeroForNegation);
838  MIRBuilder.buildInstr(TargetOpcode::G_FSUB)
839  .addDef(Res)
840  .addUse(Zero)
841  .addUse(MI.getOperand(1).getReg());
842  MI.eraseFromParent();
843  return Legalized;
844  }
845  case TargetOpcode::G_FSUB: {
846  // Lower (G_FSUB LHS, RHS) to (G_FADD LHS, (G_FNEG RHS)).
847  // First, check if G_FNEG is marked as Lower. If so, we may
848  // end up with an infinite loop as G_FSUB is used to legalize G_FNEG.
849  if (LI.getAction({G_FNEG, Ty}).first == LegalizerInfo::Lower)
850  return UnableToLegalize;
851  unsigned Res = MI.getOperand(0).getReg();
852  unsigned LHS = MI.getOperand(1).getReg();
853  unsigned RHS = MI.getOperand(2).getReg();
854  unsigned Neg = MRI.createGenericVirtualRegister(Ty);
855  MIRBuilder.buildInstr(TargetOpcode::G_FNEG).addDef(Neg).addUse(RHS);
856  MIRBuilder.buildInstr(TargetOpcode::G_FADD)
857  .addDef(Res)
858  .addUse(LHS)
859  .addUse(Neg);
860  MI.eraseFromParent();
861  return Legalized;
862  }
863  }
864 }
865 
868  LLT NarrowTy) {
869  // FIXME: Don't know how to handle secondary types yet.
870  if (TypeIdx != 0)
871  return UnableToLegalize;
872  switch (MI.getOpcode()) {
873  default:
874  return UnableToLegalize;
875  case TargetOpcode::G_ADD: {
876  unsigned NarrowSize = NarrowTy.getSizeInBits();
877  unsigned DstReg = MI.getOperand(0).getReg();
878  unsigned Size = MRI.getType(DstReg).getSizeInBits();
879  int NumParts = Size / NarrowSize;
880  // FIXME: Don't know how to handle the situation where the small vectors
881  // aren't all the same size yet.
882  if (Size % NarrowSize != 0)
883  return UnableToLegalize;
884 
885  MIRBuilder.setInstr(MI);
886 
887  SmallVector<unsigned, 2> Src1Regs, Src2Regs, DstRegs;
888  extractParts(MI.getOperand(1).getReg(), NarrowTy, NumParts, Src1Regs);
889  extractParts(MI.getOperand(2).getReg(), NarrowTy, NumParts, Src2Regs);
890 
891  for (int i = 0; i < NumParts; ++i) {
892  unsigned DstReg = MRI.createGenericVirtualRegister(NarrowTy);
893  MIRBuilder.buildAdd(DstReg, Src1Regs[i], Src2Regs[i]);
894  DstRegs.push_back(DstReg);
895  }
896 
897  MIRBuilder.buildMerge(DstReg, DstRegs);
898  MI.eraseFromParent();
899  return Legalized;
900  }
901  }
902 }
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:327
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
MachineInstrBuilder buildZExt(unsigned Res, unsigned Op)
Build and insert Res<def> = G_ZEXT Op.
unsigned getReg() const
getReg - Returns the register number.
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:818
MachineInstrBuilder buildTrunc(unsigned Res, unsigned Op)
Build and insert Res<def> = G_TRUNC Op.
MachineInstrBuilder buildAnyExtOrTrunc(DstTy &&Dst, UseArgTy &&Use)
Res = COPY Op depending on the differing sizes of Res and Op.
MachineInstrBuilder buildSub(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res<def> = G_SUB Op0, Op1.
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<def> = 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<def>, ...
MachineInstrBuilder buildFPTrunc(unsigned Res, unsigned Op)
Build and insert Res<def> = G_FPTRUNC Op.
MachineInstrBuilder buildFCmp(CmpInst::Predicate Pred, unsigned Res, unsigned Op0, unsigned Op1)
Build and insert a Res = G_FCMP PredOp0, Op1.
std::pair< LegalizeAction, LLT > getAction(const InstrAspect &Aspect) const
Determine what action should be taken to legalize the given generic instruction opcode, type-index and type.
LegalizerHelper(MachineFunction &MF)
MachineInstrBuilder buildStore(unsigned Val, unsigned Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
bool isVector() const
bool isSigned() const
Determine if this instruction is using a signed comparison.
Definition: InstrTypes.h:994
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:293
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 buildFConstant(unsigned Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
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:290
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 ...
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
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
The target wants to do something special with this combination of operand and type.
Definition: LegalizerInfo.h:93
unsigned const MachineRegisterInfo * MRI
The (vector) operation should be implemented by splitting it into sub-vectors where the operation is ...
Definition: LegalizerInfo.h:74
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.
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, unsigned Res, unsigned Op0, unsigned Op1)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
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
void setMF(MachineFunction &)
MachineInstrBuilder buildOr(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res<def> = G_OR Op0, Op1.
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<def>, CarryOut<def> = 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
The operation should be synthesized from multiple instructions acting on a narrower scalar base-type...
Definition: LegalizerInfo.h:64
static Type * getHalfTy(LLVMContext &C)
Definition: Type.cpp:163
The operation should be implemented as a call to some kind of runtime support library.
Definition: LegalizerInfo.h:89
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:389
static RTLIB::Libcall getRTLibDesc(unsigned Opcode, unsigned Size)
MachineInstrBuilder MachineInstrBuilder & DefMI
The operation should be implemented in terms of a wider scalar base-type.
Definition: LegalizerInfo.h:69
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
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:560
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
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
The operation itself must be expressed in terms of simpler actions on this target.
Definition: LegalizerInfo.h:84
static MachineOperand CreateES(const char *SymName, unsigned char TargetFlags=0)
MachineInstrBuilder buildSExt(unsigned Res, unsigned Op)
Build and insert Res<def> = G_SEXT Op.
The operation is expected to be selectable directly by the target, and no transformation is necessary...
Definition: LegalizerInfo.h:59
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:139
virtual bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder) const
Representation of each machine instruction.
Definition: MachineInstr.h:59
Instruction has been legalized and the MachineFunction changed.
MachineInstrBuilder buildUndef(unsigned Dst)
Build and insert Res = IMPLICIT_DEF.
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<def> = 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:676
MachineInstrBuilder buildMul(unsigned Res, unsigned Op0, unsigned Op1)
Build and insert Res<def> = G_MUL Op0, Op1.
LLT getType(unsigned VReg) const
Get the low-level type of VReg or LLT{} if VReg is not a generic (target independent) virtual registe...
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
void print(raw_ostream &OS, bool SkipOpers=false, bool SkipDebugLoc=false, const TargetInstrInfo *TII=nullptr) const
Debugging supportPrint this MI to OS.
Optional< MachineInstrBuilder > materializeGEP(unsigned &Res, unsigned Op0, const LLT &ValueTy, uint64_t Value)
Materialize and insert Res<def> = G_GEP Op0, (G_CONSTANT Value)
MachineInstrBuilder buildUnmerge(ArrayRef< unsigned > Res, unsigned Op)
Build and insert Res0<def>, ...
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
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:326
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<def> = G_LOAD Addr, MMO.
#define DEBUG(X)
Definition: Debug.h:118
IRTranslator LLVM IR MI
const MachineInstrBuilder & addDef(unsigned RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:295
MachineInstrBuilder buildMerge(unsigned Res, ArrayRef< unsigned > Ops)
Build and insert Res<def> = G_MERGE_VALUES Op0, ...
const ConstantInt * getCImm() const
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
This file describes how to lower LLVM code to machine code.
unsigned getPredicate() const
MachineInstrBuilder buildBrCond(unsigned Tst, MachineBasicBlock &BB)
Build and insert G_BRCOND Tst, Dest.