LLVM  13.0.0git
MipsLegalizerInfo.cpp
Go to the documentation of this file.
1 //===- MipsLegalizerInfo.cpp ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements the targeting of the Machinelegalizer class for Mips.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12 
13 #include "MipsLegalizerInfo.h"
14 #include "MipsTargetMachine.h"
16 #include "llvm/IR/IntrinsicsMips.h"
17 
18 using namespace llvm;
19 
23  unsigned MemSize;
25 };
26 
27 // Assumes power of 2 memory size. Subtargets that have only naturally-aligned
28 // memory access need to perform additional legalization here.
29 static bool isUnalignedMemmoryAccess(uint64_t MemSize, uint64_t AlignInBits) {
30  assert(isPowerOf2_64(MemSize) && "Expected power of 2 memory size");
31  assert(isPowerOf2_64(AlignInBits) && "Expected power of 2 align");
32  if (MemSize > AlignInBits)
33  return true;
34  return false;
35 }
36 
37 static bool
39  std::initializer_list<TypesAndMemOps> SupportedValues) {
40  unsigned QueryMemSize = Query.MMODescrs[0].SizeInBits;
41 
42  // Non power of two memory access is never legal.
43  if (!isPowerOf2_64(QueryMemSize))
44  return false;
45 
46  for (auto &Val : SupportedValues) {
47  if (Val.ValTy != Query.Types[0])
48  continue;
49  if (Val.PtrTy != Query.Types[1])
50  continue;
51  if (Val.MemSize != QueryMemSize)
52  continue;
53  if (!Val.SystemSupportsUnalignedAccess &&
54  isUnalignedMemmoryAccess(QueryMemSize, Query.MMODescrs[0].AlignInBits))
55  return false;
56  return true;
57  }
58  return false;
59 }
60 
61 static bool CheckTyN(unsigned N, const LegalityQuery &Query,
62  std::initializer_list<LLT> SupportedValues) {
63  return llvm::is_contained(SupportedValues, Query.Types[N]);
64 }
65 
67  using namespace TargetOpcode;
68 
69  const LLT s1 = LLT::scalar(1);
70  const LLT s32 = LLT::scalar(32);
71  const LLT s64 = LLT::scalar(64);
72  const LLT v16s8 = LLT::vector(16, 8);
73  const LLT v8s16 = LLT::vector(8, 16);
74  const LLT v4s32 = LLT::vector(4, 32);
75  const LLT v2s64 = LLT::vector(2, 64);
76  const LLT p0 = LLT::pointer(0, 32);
77 
78  getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL})
79  .legalIf([=, &ST](const LegalityQuery &Query) {
80  if (CheckTyN(0, Query, {s32}))
81  return true;
82  if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64}))
83  return true;
84  return false;
85  })
86  .clampScalar(0, s32, s32);
87 
88  getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_USUBO, G_USUBE, G_UMULO})
89  .lowerFor({{s32, s1}});
90 
92  .legalFor({s32})
93  .maxScalar(0, s32);
94 
95  // MIPS32r6 does not have alignment restrictions for memory access.
96  // For MIPS32r5 and older memory access must be naturally-aligned i.e. aligned
97  // to at least a multiple of its own size. There is however a two instruction
98  // combination that performs 4 byte unaligned access (lwr/lwl and swl/swr)
99  // therefore 4 byte load and store are legal and will use NoAlignRequirements.
100  bool NoAlignRequirements = true;
101 
102  getActionDefinitionsBuilder({G_LOAD, G_STORE})
103  .legalIf([=, &ST](const LegalityQuery &Query) {
105  Query, {{s32, p0, 8, NoAlignRequirements},
106  {s32, p0, 16, ST.systemSupportsUnalignedAccess()},
107  {s32, p0, 32, NoAlignRequirements},
108  {p0, p0, 32, NoAlignRequirements},
109  {s64, p0, 64, ST.systemSupportsUnalignedAccess()}}))
110  return true;
111  if (ST.hasMSA() && CheckTy0Ty1MemSizeAlign(
112  Query, {{v16s8, p0, 128, NoAlignRequirements},
113  {v8s16, p0, 128, NoAlignRequirements},
114  {v4s32, p0, 128, NoAlignRequirements},
115  {v2s64, p0, 128, NoAlignRequirements}}))
116  return true;
117  return false;
118  })
119  // Custom lower scalar memory access, up to 8 bytes, for:
120  // - non-power-of-2 MemSizes
121  // - unaligned 2 or 8 byte MemSizes for MIPS32r5 and older
122  .customIf([=, &ST](const LegalityQuery &Query) {
123  if (!Query.Types[0].isScalar() || Query.Types[1] != p0 ||
124  Query.Types[0] == s1)
125  return false;
126 
127  unsigned Size = Query.Types[0].getSizeInBits();
128  unsigned QueryMemSize = Query.MMODescrs[0].SizeInBits;
129  assert(QueryMemSize <= Size && "Scalar can't hold MemSize");
130 
131  if (Size > 64 || QueryMemSize > 64)
132  return false;
133 
134  if (!isPowerOf2_64(Query.MMODescrs[0].SizeInBits))
135  return true;
136 
137  if (!ST.systemSupportsUnalignedAccess() &&
138  isUnalignedMemmoryAccess(QueryMemSize,
139  Query.MMODescrs[0].AlignInBits)) {
140  assert(QueryMemSize != 32 && "4 byte load and store are legal");
141  return true;
142  }
143 
144  return false;
145  })
146  .minScalar(0, s32);
147 
148  getActionDefinitionsBuilder(G_IMPLICIT_DEF)
149  .legalFor({s32, s64});
150 
151  getActionDefinitionsBuilder(G_UNMERGE_VALUES)
152  .legalFor({{s32, s64}});
153 
154  getActionDefinitionsBuilder(G_MERGE_VALUES)
155  .legalFor({{s64, s32}});
156 
157  getActionDefinitionsBuilder({G_ZEXTLOAD, G_SEXTLOAD})
158  .legalForTypesWithMemDesc({{s32, p0, 8, 8},
159  {s32, p0, 16, 8}})
160  .clampScalar(0, s32, s32);
161 
162  getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
163  .legalIf([](const LegalityQuery &Query) { return false; })
164  .maxScalar(0, s32);
165 
167  .legalIf([](const LegalityQuery &Query) { return false; })
168  .maxScalar(1, s32);
169 
171  .legalForCartesianProduct({p0, s32, s64}, {s32})
172  .minScalar(0, s32)
173  .minScalar(1, s32);
174 
176  .legalFor({s32})
177  .minScalar(0, s32);
178 
180  .legalFor({{p0, s32}});
181 
182  getActionDefinitionsBuilder(G_BRINDIRECT)
183  .legalFor({p0});
184 
186  .legalFor({p0, s32, s64})
187  .minScalar(0, s32);
188 
189  getActionDefinitionsBuilder({G_AND, G_OR, G_XOR})
190  .legalFor({s32})
191  .clampScalar(0, s32, s32);
192 
193  getActionDefinitionsBuilder({G_SDIV, G_SREM, G_UDIV, G_UREM})
194  .legalIf([=, &ST](const LegalityQuery &Query) {
195  if (CheckTyN(0, Query, {s32}))
196  return true;
197  if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64}))
198  return true;
199  return false;
200  })
201  .minScalar(0, s32)
202  .libcallFor({s64});
203 
204  getActionDefinitionsBuilder({G_SHL, G_ASHR, G_LSHR})
205  .legalFor({{s32, s32}})
206  .clampScalar(1, s32, s32)
207  .clampScalar(0, s32, s32);
208 
210  .legalForCartesianProduct({s32}, {s32, p0})
211  .clampScalar(1, s32, s32)
212  .minScalar(0, s32);
213 
214  getActionDefinitionsBuilder(G_CONSTANT)
215  .legalFor({s32})
216  .clampScalar(0, s32, s32);
217 
218  getActionDefinitionsBuilder({G_PTR_ADD, G_INTTOPTR})
219  .legalFor({{p0, s32}});
220 
221  getActionDefinitionsBuilder(G_PTRTOINT)
222  .legalFor({{s32, p0}});
223 
224  getActionDefinitionsBuilder(G_FRAME_INDEX)
225  .legalFor({p0});
226 
227  getActionDefinitionsBuilder({G_GLOBAL_VALUE, G_JUMP_TABLE})
228  .legalFor({p0});
229 
230  getActionDefinitionsBuilder(G_DYN_STACKALLOC)
231  .lowerFor({{p0, s32}});
232 
233  getActionDefinitionsBuilder(G_VASTART)
234  .legalFor({p0});
235 
237  .legalIf([=, &ST](const LegalityQuery &Query) {
238  if (ST.hasMips32r2() && CheckTyN(0, Query, {s32}))
239  return true;
240  return false;
241  })
242  .lowerIf([=, &ST](const LegalityQuery &Query) {
243  if (!ST.hasMips32r2() && CheckTyN(0, Query, {s32}))
244  return true;
245  return false;
246  })
247  .maxScalar(0, s32);
248 
249  getActionDefinitionsBuilder(G_BITREVERSE)
250  .lowerFor({s32})
251  .maxScalar(0, s32);
252 
254  .legalFor({{s32, s32}})
255  .maxScalar(0, s32)
256  .maxScalar(1, s32);
257  getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)
258  .lowerFor({{s32, s32}});
259 
261  .lowerFor({{s32, s32}})
262  .maxScalar(0, s32)
263  .maxScalar(1, s32);
264  getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF)
265  .lowerFor({{s32, s32}, {s64, s64}});
266 
268  .lowerFor({{s32, s32}})
269  .clampScalar(0, s32, s32)
270  .clampScalar(1, s32, s32);
271 
272  // FP instructions
273  getActionDefinitionsBuilder(G_FCONSTANT)
274  .legalFor({s32, s64});
275 
276  getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FABS, G_FSQRT})
277  .legalIf([=, &ST](const LegalityQuery &Query) {
278  if (CheckTyN(0, Query, {s32, s64}))
279  return true;
280  if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64}))
281  return true;
282  return false;
283  });
284 
286  .legalFor({{s32, s32}, {s32, s64}})
287  .minScalar(0, s32);
288 
289  getActionDefinitionsBuilder({G_FCEIL, G_FFLOOR})
290  .libcallFor({s32, s64});
291 
293  .legalFor({{s64, s32}});
294 
295  getActionDefinitionsBuilder(G_FPTRUNC)
296  .legalFor({{s32, s64}});
297 
298  // FP to int conversion instructions
300  .legalForCartesianProduct({s32}, {s64, s32})
301  .libcallForCartesianProduct({s64}, {s64, s32})
302  .minScalar(0, s32);
303 
305  .libcallForCartesianProduct({s64}, {s64, s32})
306  .lowerForCartesianProduct({s32}, {s64, s32})
307  .minScalar(0, s32);
308 
309  // Int to FP conversion instructions
311  .legalForCartesianProduct({s64, s32}, {s32})
312  .libcallForCartesianProduct({s64, s32}, {s64})
313  .minScalar(1, s32);
314 
316  .libcallForCartesianProduct({s64, s32}, {s64})
317  .customForCartesianProduct({s64, s32}, {s32})
318  .minScalar(1, s32);
319 
320  getActionDefinitionsBuilder(G_SEXT_INREG).lower();
321 
322  getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
323 
324  computeTables();
325  verify(*ST.getInstrInfo());
326 }
327 
329  MachineInstr &MI) const {
330  using namespace TargetOpcode;
331 
332  MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
333  MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
334 
335  const LLT s32 = LLT::scalar(32);
336  const LLT s64 = LLT::scalar(64);
337 
338  switch (MI.getOpcode()) {
339  case G_LOAD:
340  case G_STORE: {
341  unsigned MemSize = (**MI.memoperands_begin()).getSize();
342  Register Val = MI.getOperand(0).getReg();
343  unsigned Size = MRI.getType(Val).getSizeInBits();
344 
345  MachineMemOperand *MMOBase = *MI.memoperands_begin();
346 
347  assert(MemSize <= 8 && "MemSize is too large");
348  assert(Size <= 64 && "Scalar size is too large");
349 
350  // Split MemSize into two, P2HalfMemSize is largest power of two smaller
351  // then MemSize. e.g. 8 = 4 + 4 , 6 = 4 + 2, 3 = 2 + 1.
352  unsigned P2HalfMemSize, RemMemSize;
353  if (isPowerOf2_64(MemSize)) {
354  P2HalfMemSize = RemMemSize = MemSize / 2;
355  } else {
356  P2HalfMemSize = 1 << Log2_32(MemSize);
357  RemMemSize = MemSize - P2HalfMemSize;
358  }
359 
360  Register BaseAddr = MI.getOperand(1).getReg();
361  LLT PtrTy = MRI.getType(BaseAddr);
362  MachineFunction &MF = MIRBuilder.getMF();
363 
364  auto P2HalfMemOp = MF.getMachineMemOperand(MMOBase, 0, P2HalfMemSize);
365  auto RemMemOp = MF.getMachineMemOperand(MMOBase, P2HalfMemSize, RemMemSize);
366 
367  if (MI.getOpcode() == G_STORE) {
368  // Widen Val to s32 or s64 in order to create legal G_LSHR or G_UNMERGE.
369  if (Size < 32)
370  Val = MIRBuilder.buildAnyExt(s32, Val).getReg(0);
371  if (Size > 32 && Size < 64)
372  Val = MIRBuilder.buildAnyExt(s64, Val).getReg(0);
373 
374  auto C_P2HalfMemSize = MIRBuilder.buildConstant(s32, P2HalfMemSize);
375  auto Addr = MIRBuilder.buildPtrAdd(PtrTy, BaseAddr, C_P2HalfMemSize);
376 
377  if (MI.getOpcode() == G_STORE && MemSize <= 4) {
378  MIRBuilder.buildStore(Val, BaseAddr, *P2HalfMemOp);
379  auto C_P2Half_InBits = MIRBuilder.buildConstant(s32, P2HalfMemSize * 8);
380  auto Shift = MIRBuilder.buildLShr(s32, Val, C_P2Half_InBits);
381  MIRBuilder.buildStore(Shift, Addr, *RemMemOp);
382  } else {
383  auto Unmerge = MIRBuilder.buildUnmerge(s32, Val);
384  MIRBuilder.buildStore(Unmerge.getReg(0), BaseAddr, *P2HalfMemOp);
385  MIRBuilder.buildStore(Unmerge.getReg(1), Addr, *RemMemOp);
386  }
387  }
388 
389  if (MI.getOpcode() == G_LOAD) {
390 
391  if (MemSize <= 4) {
392  // This is anyextending load, use 4 byte lwr/lwl.
393  auto *Load4MMO = MF.getMachineMemOperand(MMOBase, 0, 4);
394 
395  if (Size == 32)
396  MIRBuilder.buildLoad(Val, BaseAddr, *Load4MMO);
397  else {
398  auto Load = MIRBuilder.buildLoad(s32, BaseAddr, *Load4MMO);
399  MIRBuilder.buildTrunc(Val, Load.getReg(0));
400  }
401 
402  } else {
403  auto C_P2HalfMemSize = MIRBuilder.buildConstant(s32, P2HalfMemSize);
404  auto Addr = MIRBuilder.buildPtrAdd(PtrTy, BaseAddr, C_P2HalfMemSize);
405 
406  auto Load_P2Half = MIRBuilder.buildLoad(s32, BaseAddr, *P2HalfMemOp);
407  auto Load_Rem = MIRBuilder.buildLoad(s32, Addr, *RemMemOp);
408 
409  if (Size == 64)
410  MIRBuilder.buildMerge(Val, {Load_P2Half, Load_Rem});
411  else {
412  auto Merge = MIRBuilder.buildMerge(s64, {Load_P2Half, Load_Rem});
413  MIRBuilder.buildTrunc(Val, Merge);
414  }
415  }
416  }
417  MI.eraseFromParent();
418  break;
419  }
420  case G_UITOFP: {
421  Register Dst = MI.getOperand(0).getReg();
422  Register Src = MI.getOperand(1).getReg();
423  LLT DstTy = MRI.getType(Dst);
424  LLT SrcTy = MRI.getType(Src);
425 
426  if (SrcTy != s32)
427  return false;
428  if (DstTy != s32 && DstTy != s64)
429  return false;
430 
431  // Let 0xABCDEFGH be given unsigned in MI.getOperand(1). First let's convert
432  // unsigned to double. Mantissa has 52 bits so we use following trick:
433  // First make floating point bit mask 0x43300000ABCDEFGH.
434  // Mask represents 2^52 * 0x1.00000ABCDEFGH i.e. 0x100000ABCDEFGH.0 .
435  // Next, subtract 2^52 * 0x1.0000000000000 i.e. 0x10000000000000.0 from it.
436  // Done. Trunc double to float if needed.
437 
438  auto C_HiMask = MIRBuilder.buildConstant(s32, UINT32_C(0x43300000));
439  auto Bitcast = MIRBuilder.buildMerge(s64, {Src, C_HiMask.getReg(0)});
440 
441  MachineInstrBuilder TwoP52FP = MIRBuilder.buildFConstant(
442  s64, BitsToDouble(UINT64_C(0x4330000000000000)));
443 
444  if (DstTy == s64)
445  MIRBuilder.buildFSub(Dst, Bitcast, TwoP52FP);
446  else {
447  MachineInstrBuilder ResF64 = MIRBuilder.buildFSub(s64, Bitcast, TwoP52FP);
448  MIRBuilder.buildFPTrunc(Dst, ResF64);
449  }
450 
451  MI.eraseFromParent();
452  break;
453  }
454  default:
455  return false;
456  }
457 
458  return true;
459 }
460 
461 static bool SelectMSA3OpIntrinsic(MachineInstr &MI, unsigned Opcode,
462  MachineIRBuilder &MIRBuilder,
463  const MipsSubtarget &ST) {
464  assert(ST.hasMSA() && "MSA intrinsic not supported on target without MSA.");
465  if (!MIRBuilder.buildInstr(Opcode)
466  .add(MI.getOperand(0))
467  .add(MI.getOperand(2))
468  .add(MI.getOperand(3))
469  .constrainAllUses(MIRBuilder.getTII(), *ST.getRegisterInfo(),
470  *ST.getRegBankInfo()))
471  return false;
472  MI.eraseFromParent();
473  return true;
474 }
475 
476 static bool MSA3OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode,
477  MachineIRBuilder &MIRBuilder,
478  const MipsSubtarget &ST) {
479  assert(ST.hasMSA() && "MSA intrinsic not supported on target without MSA.");
480  MIRBuilder.buildInstr(Opcode)
481  .add(MI.getOperand(0))
482  .add(MI.getOperand(2))
483  .add(MI.getOperand(3));
484  MI.eraseFromParent();
485  return true;
486 }
487 
488 static bool MSA2OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode,
489  MachineIRBuilder &MIRBuilder,
490  const MipsSubtarget &ST) {
491  assert(ST.hasMSA() && "MSA intrinsic not supported on target without MSA.");
492  MIRBuilder.buildInstr(Opcode)
493  .add(MI.getOperand(0))
494  .add(MI.getOperand(2));
495  MI.eraseFromParent();
496  return true;
497 }
498 
500  MachineInstr &MI) const {
501  MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
502  const MipsSubtarget &ST =
503  static_cast<const MipsSubtarget &>(MI.getMF()->getSubtarget());
504  const MipsInstrInfo &TII = *ST.getInstrInfo();
505  const MipsRegisterInfo &TRI = *ST.getRegisterInfo();
506  const RegisterBankInfo &RBI = *ST.getRegBankInfo();
507 
508  switch (MI.getIntrinsicID()) {
509  case Intrinsic::trap: {
510  MachineInstr *Trap = MIRBuilder.buildInstr(Mips::TRAP);
511  MI.eraseFromParent();
512  return constrainSelectedInstRegOperands(*Trap, TII, TRI, RBI);
513  }
514  case Intrinsic::vacopy: {
515  MachinePointerInfo MPO;
516  auto Tmp =
517  MIRBuilder.buildLoad(LLT::pointer(0, 32), MI.getOperand(2),
518  *MI.getMF()->getMachineMemOperand(
519  MPO, MachineMemOperand::MOLoad, 4, Align(4)));
520  MIRBuilder.buildStore(Tmp, MI.getOperand(1),
521  *MI.getMF()->getMachineMemOperand(
522  MPO, MachineMemOperand::MOStore, 4, Align(4)));
523  MI.eraseFromParent();
524  return true;
525  }
526  case Intrinsic::mips_addv_b:
527  case Intrinsic::mips_addv_h:
528  case Intrinsic::mips_addv_w:
529  case Intrinsic::mips_addv_d:
530  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_ADD, MIRBuilder, ST);
531  case Intrinsic::mips_addvi_b:
532  return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_B, MIRBuilder, ST);
533  case Intrinsic::mips_addvi_h:
534  return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_H, MIRBuilder, ST);
535  case Intrinsic::mips_addvi_w:
536  return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_W, MIRBuilder, ST);
537  case Intrinsic::mips_addvi_d:
538  return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_D, MIRBuilder, ST);
539  case Intrinsic::mips_subv_b:
540  case Intrinsic::mips_subv_h:
541  case Intrinsic::mips_subv_w:
542  case Intrinsic::mips_subv_d:
543  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SUB, MIRBuilder, ST);
544  case Intrinsic::mips_subvi_b:
545  return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_B, MIRBuilder, ST);
546  case Intrinsic::mips_subvi_h:
547  return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_H, MIRBuilder, ST);
548  case Intrinsic::mips_subvi_w:
549  return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_W, MIRBuilder, ST);
550  case Intrinsic::mips_subvi_d:
551  return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_D, MIRBuilder, ST);
552  case Intrinsic::mips_mulv_b:
553  case Intrinsic::mips_mulv_h:
554  case Intrinsic::mips_mulv_w:
555  case Intrinsic::mips_mulv_d:
556  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_MUL, MIRBuilder, ST);
557  case Intrinsic::mips_div_s_b:
558  case Intrinsic::mips_div_s_h:
559  case Intrinsic::mips_div_s_w:
560  case Intrinsic::mips_div_s_d:
561  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SDIV, MIRBuilder, ST);
562  case Intrinsic::mips_mod_s_b:
563  case Intrinsic::mips_mod_s_h:
564  case Intrinsic::mips_mod_s_w:
565  case Intrinsic::mips_mod_s_d:
566  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SREM, MIRBuilder, ST);
567  case Intrinsic::mips_div_u_b:
568  case Intrinsic::mips_div_u_h:
569  case Intrinsic::mips_div_u_w:
570  case Intrinsic::mips_div_u_d:
571  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_UDIV, MIRBuilder, ST);
572  case Intrinsic::mips_mod_u_b:
573  case Intrinsic::mips_mod_u_h:
574  case Intrinsic::mips_mod_u_w:
575  case Intrinsic::mips_mod_u_d:
576  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_UREM, MIRBuilder, ST);
577  case Intrinsic::mips_fadd_w:
578  case Intrinsic::mips_fadd_d:
579  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FADD, MIRBuilder, ST);
580  case Intrinsic::mips_fsub_w:
581  case Intrinsic::mips_fsub_d:
582  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FSUB, MIRBuilder, ST);
583  case Intrinsic::mips_fmul_w:
584  case Intrinsic::mips_fmul_d:
585  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FMUL, MIRBuilder, ST);
586  case Intrinsic::mips_fdiv_w:
587  case Intrinsic::mips_fdiv_d:
588  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FDIV, MIRBuilder, ST);
589  case Intrinsic::mips_fmax_a_w:
590  return SelectMSA3OpIntrinsic(MI, Mips::FMAX_A_W, MIRBuilder, ST);
591  case Intrinsic::mips_fmax_a_d:
592  return SelectMSA3OpIntrinsic(MI, Mips::FMAX_A_D, MIRBuilder, ST);
593  case Intrinsic::mips_fsqrt_w:
594  return MSA2OpIntrinsicToGeneric(MI, TargetOpcode::G_FSQRT, MIRBuilder, ST);
595  case Intrinsic::mips_fsqrt_d:
596  return MSA2OpIntrinsicToGeneric(MI, TargetOpcode::G_FSQRT, MIRBuilder, ST);
597  default:
598  break;
599  }
600  return true;
601 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:100
Merge
R600 Clause Merge
Definition: R600ClauseMergePass.cpp:69
llvm
Definition: AllocatorList.h:23
llvm::MachineIRBuilder::buildFSub
MachineInstrBuilder buildFSub(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, Optional< unsigned > Flags=None)
Build and insert Res = G_FSUB Op0, Op1.
Definition: MachineIRBuilder.h:1586
llvm::LegalizerInfo::getActionDefinitionsBuilder
LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
Definition: LegalizerInfo.cpp:435
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:52
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:225
MipsLegalizerInfo.h
llvm::MachineIRBuilder::getMRI
MachineRegisterInfo * getMRI()
Getter for MRI.
Definition: MachineIRBuilder.h:288
llvm::MachineFunction::getMachineMemOperand
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, uint64_t s, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
Definition: MachineFunction.cpp:430
llvm::MipsLegalizerInfo::legalizeIntrinsic
bool legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const override
Definition: MipsLegalizerInfo.cpp:499
TypesAndMemOps::MemSize
unsigned MemSize
Definition: MipsLegalizerInfo.cpp:23
Shift
bool Shift
Definition: README.txt:468
llvm::MipsLegalizerInfo::MipsLegalizerInfo
MipsLegalizerInfo(const MipsSubtarget &ST)
Definition: MipsLegalizerInfo.cpp:66
llvm::MachineMemOperand
A description of a memory reference used in the backend.
Definition: MachineMemOperand.h:127
llvm::MachineIRBuilder::buildFPTrunc
MachineInstrBuilder buildFPTrunc(const DstOp &Res, const SrcOp &Op, Optional< unsigned > Flags=None)
Build and insert Res = G_FPTRUNC Op.
Definition: MachineIRBuilder.cpp:742
llvm::LegalizeRuleSet::maxScalar
LegalizeRuleSet & maxScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
Definition: LegalizerInfo.h:875
MSA2OpIntrinsicToGeneric
static bool MSA2OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode, MachineIRBuilder &MIRBuilder, const MipsSubtarget &ST)
Definition: MipsLegalizerInfo.cpp:488
CheckTyN
static bool CheckTyN(unsigned N, const LegalityQuery &Query, std::initializer_list< LLT > SupportedValues)
Definition: MipsLegalizerInfo.cpp:61
llvm::LegalizeRuleSet::lower
LegalizeRuleSet & lower()
The instruction is lowered.
Definition: LegalizerInfo.h:604
MipsTargetMachine.h
llvm::LegalizerHelper
Definition: LegalizerHelper.h:37
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
llvm::constrainSelectedInstRegOperands
bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
Definition: Utils.cpp:134
llvm::MachineIRBuilder::buildConstant
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
Definition: MachineIRBuilder.cpp:255
llvm::LegalizeRuleSet::legalIf
LegalizeRuleSet & legalIf(LegalityPredicate Predicate)
The instruction is legal if predicate is true.
Definition: LegalizerInfo.h:531
llvm::LegalizeRuleSet::minScalar
LegalizeRuleSet & minScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty.
Definition: LegalizerInfo.h:857
llvm::MachineIRBuilder::buildUnmerge
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ...
Definition: MachineIRBuilder.cpp:605
llvm::MachineIRBuilder::buildLoad
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
Definition: MachineIRBuilder.h:840
llvm::LLT::getSizeInBits
unsigned getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:109
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::Log2_32
unsigned Log2_32(uint32_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
Definition: MathExtras.h:596
llvm::MipsInstrInfo
Definition: MipsInstrInfo.h:41
llvm::MachineIRBuilder::getMF
MachineFunction & getMF()
Getter for the function we currently build.
Definition: MachineIRBuilder.h:270
isUnalignedMemmoryAccess
static bool isUnalignedMemmoryAccess(uint64_t MemSize, uint64_t AlignInBits)
Definition: MipsLegalizerInfo.cpp:29
llvm::LLT::vector
static LLT vector(uint16_t NumElements, unsigned ScalarSizeInBits)
Get a low-level vector of some number of elements and element width.
Definition: LowLevelTypeImpl.h:58
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
TypesAndMemOps::ValTy
LLT ValTy
Definition: MipsLegalizerInfo.cpp:21
TypesAndMemOps::SystemSupportsUnalignedAccess
bool SystemSupportsUnalignedAccess
Definition: MipsLegalizerInfo.cpp:24
llvm::MachineInstrBuilder::getReg
Register getReg(unsigned Idx) const
Get the register for the operand index.
Definition: MachineInstrBuilder.h:95
llvm::LegalizeRuleSet::libcallForCartesianProduct
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types)
Definition: LegalizerInfo.h:691
llvm::LLT::pointer
static LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
Definition: LowLevelTypeImpl.h:50
llvm::RegisterBankInfo
Holds all the information related to register banks.
Definition: RegisterBankInfo.h:39
llvm::MachineIRBuilder::buildFConstant
virtual MachineInstrBuilder buildFConstant(const DstOp &Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
Definition: MachineIRBuilder.cpp:284
llvm::MachineIRBuilder
Helper class to build MachineInstr.
Definition: MachineIRBuilder.h:220
llvm::LegalizeRuleSet::legalFor
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
Definition: LegalizerInfo.h:538
SelectMSA3OpIntrinsic
static bool SelectMSA3OpIntrinsic(MachineInstr &MI, unsigned Opcode, MachineIRBuilder &MIRBuilder, const MipsSubtarget &ST)
Definition: MipsLegalizerInfo.cpp:461
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:70
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
llvm::LegalizeActions::Bitcast
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Definition: LegalizerInfo.h:72
llvm::ISD::TRAP
@ TRAP
TRAP - Trapping instruction.
Definition: ISDOpcodes.h:1073
llvm::MachinePointerInfo
This class contains a discriminated union of information about pointers in memory operands,...
Definition: MachineMemOperand.h:37
llvm::MachineIRBuilder::buildPtrAdd
MachineInstrBuilder buildPtrAdd(const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1)
Build and insert Res = G_PTR_ADD Op0, Op1.
Definition: MachineIRBuilder.cpp:182
TypesAndMemOps
Definition: MipsLegalizerInfo.cpp:20
llvm::MipsRegisterInfo
Definition: MipsRegisterInfo.h:27
llvm::LegalizeRuleSet::clampScalar
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
Definition: LegalizerInfo.h:902
llvm::is_contained
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.
Definition: STLExtras.h:1570
llvm::LegalizeRuleSet::lowerFor
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types)
The instruction is lowered when type index 0 is any type in the given list.
Definition: LegalizerInfo.h:630
llvm::LegalizeRuleSet::legalForCartesianProduct
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)
The instruction is legal when type indexes 0 and 1 are both in the given list.
Definition: LegalizerInfo.h:570
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
TypesAndMemOps::PtrTy
LLT PtrTy
Definition: MipsLegalizerInfo.cpp:22
llvm::MachineInstrBuilder::constrainAllUses
bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
Definition: MachineInstrBuilder.h:321
llvm::MachineFunction
Definition: MachineFunction.h:227
llvm::MachineIRBuilder::buildInstr
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
Definition: MachineIRBuilder.h:375
llvm::LegalityQuery
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
Definition: LegalizerInfo.h:124
llvm::SPII::Load
@ Load
Definition: SparcInstrInfo.h:32
if
if(llvm_vc STREQUAL "") set(fake_version_inc "$
Definition: CMakeLists.txt:14
MSA3OpIntrinsicToGeneric
static bool MSA3OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode, MachineIRBuilder &MIRBuilder, const MipsSubtarget &ST)
Definition: MipsLegalizerInfo.cpp:476
llvm::MipsSubtarget
Definition: MipsSubtarget.h:39
llvm::MachineMemOperand::MOLoad
@ MOLoad
The memory access reads data.
Definition: MachineMemOperand.h:134
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::MachineIRBuilder::buildAnyExt
MachineInstrBuilder buildAnyExt(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_ANYEXT Op0.
Definition: MachineIRBuilder.cpp:416
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineIRBuilder::buildTrunc
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_TRUNC Op.
Definition: MachineIRBuilder.cpp:737
CheckTy0Ty1MemSizeAlign
static bool CheckTy0Ty1MemSizeAlign(const LegalityQuery &Query, std::initializer_list< TypesAndMemOps > SupportedValues)
Definition: MipsLegalizerInfo.cpp:38
llvm::LegalityQuery::MMODescrs
ArrayRef< MemDesc > MMODescrs
Operations which require memory can use this to place requirements on the memory type for each MMO.
Definition: LegalizerInfo.h:136
LegalizerHelper.h
llvm::MachineIRBuilder::getTII
const TargetInstrInfo & getTII()
Definition: MachineIRBuilder.h:264
llvm::MachineMemOperand::MOStore
@ MOStore
The memory access writes data.
Definition: MachineMemOperand.h:136
llvm::LegalizerInfo::verify
void verify(const MCInstrInfo &MII) const
Perform simple self-diagnostic and assert if there is anything obviously wrong with the actions set u...
Definition: LegalizerInfo.cpp:691
llvm::BitsToDouble
double BitsToDouble(uint64_t Bits)
This function takes a 64-bit integer and returns the bit equivalent double.
Definition: MathExtras.h:635
s1
int s1
Definition: README.txt:182
llvm::MachineRegisterInfo::getType
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
Definition: MachineRegisterInfo.h:732
llvm::LegalityQuery::Types
ArrayRef< LLT > Types
Definition: LegalizerInfo.h:126
N
#define N
llvm::LegalizerHelper::MIRBuilder
MachineIRBuilder & MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions.
Definition: LegalizerHelper.h:41
llvm::MachineIRBuilder::buildLShr
MachineInstrBuilder buildLShr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, Optional< unsigned > Flags=None)
Definition: MachineIRBuilder.h:1490
llvm::MachineIRBuilder::buildMerge
MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ...
Definition: MachineIRBuilder.cpp:588
llvm::LegalizerInfo::computeTables
void computeTables()
Compute any ancillary tables needed to quickly decide how an operation should be handled.
Definition: LegalizerInfo.cpp:294
llvm::MachineIRBuilder::buildStore
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
Definition: MachineIRBuilder.cpp:388
llvm::LegalizeRuleSet::libcallFor
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
Definition: LegalizerInfo.h:683
llvm::isPowerOf2_64
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition: MathExtras.h:496
llvm::LLT::scalar
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelTypeImpl.h:43
libcall
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj obj **nth_el If the i64 division is lowered to a libcall
Definition: README.txt:127
llvm::MipsLegalizerInfo::legalizeCustom
bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI) const override
Called for instructions with the Custom LegalizationAction.
Definition: MipsLegalizerInfo.cpp:328
llvm::LLT
Definition: LowLevelTypeImpl.h:40