LLVM  14.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].MemoryTy.getSizeInBits();
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 s8 = LLT::scalar(8);
71  const LLT s16 = LLT::scalar(16);
72  const LLT s32 = LLT::scalar(32);
73  const LLT s64 = LLT::scalar(64);
74  const LLT v16s8 = LLT::fixed_vector(16, 8);
75  const LLT v8s16 = LLT::fixed_vector(8, 16);
76  const LLT v4s32 = LLT::fixed_vector(4, 32);
77  const LLT v2s64 = LLT::fixed_vector(2, 64);
78  const LLT p0 = LLT::pointer(0, 32);
79 
80  getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL})
81  .legalIf([=, &ST](const LegalityQuery &Query) {
82  if (CheckTyN(0, Query, {s32}))
83  return true;
84  if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64}))
85  return true;
86  return false;
87  })
88  .clampScalar(0, s32, s32);
89 
90  getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_USUBO, G_USUBE, G_UMULO})
91  .lowerFor({{s32, s1}});
92 
94  .legalFor({s32})
95  .maxScalar(0, s32);
96 
97  // MIPS32r6 does not have alignment restrictions for memory access.
98  // For MIPS32r5 and older memory access must be naturally-aligned i.e. aligned
99  // to at least a multiple of its own size. There is however a two instruction
100  // combination that performs 4 byte unaligned access (lwr/lwl and swl/swr)
101  // therefore 4 byte load and store are legal and will use NoAlignRequirements.
102  bool NoAlignRequirements = true;
103 
104  getActionDefinitionsBuilder({G_LOAD, G_STORE})
105  .legalIf([=, &ST](const LegalityQuery &Query) {
107  Query, {{s32, p0, 8, NoAlignRequirements},
108  {s32, p0, 16, ST.systemSupportsUnalignedAccess()},
109  {s32, p0, 32, NoAlignRequirements},
110  {p0, p0, 32, NoAlignRequirements},
111  {s64, p0, 64, ST.systemSupportsUnalignedAccess()}}))
112  return true;
113  if (ST.hasMSA() && CheckTy0Ty1MemSizeAlign(
114  Query, {{v16s8, p0, 128, NoAlignRequirements},
115  {v8s16, p0, 128, NoAlignRequirements},
116  {v4s32, p0, 128, NoAlignRequirements},
117  {v2s64, p0, 128, NoAlignRequirements}}))
118  return true;
119  return false;
120  })
121  // Custom lower scalar memory access, up to 8 bytes, for:
122  // - non-power-of-2 MemSizes
123  // - unaligned 2 or 8 byte MemSizes for MIPS32r5 and older
124  .customIf([=, &ST](const LegalityQuery &Query) {
125  if (!Query.Types[0].isScalar() || Query.Types[1] != p0 ||
126  Query.Types[0] == s1)
127  return false;
128 
129  unsigned Size = Query.Types[0].getSizeInBits();
130  unsigned QueryMemSize = Query.MMODescrs[0].MemoryTy.getSizeInBits();
131  assert(QueryMemSize <= Size && "Scalar can't hold MemSize");
132 
133  if (Size > 64 || QueryMemSize > 64)
134  return false;
135 
136  if (!isPowerOf2_64(Query.MMODescrs[0].MemoryTy.getSizeInBits()))
137  return true;
138 
139  if (!ST.systemSupportsUnalignedAccess() &&
140  isUnalignedMemmoryAccess(QueryMemSize,
141  Query.MMODescrs[0].AlignInBits)) {
142  assert(QueryMemSize != 32 && "4 byte load and store are legal");
143  return true;
144  }
145 
146  return false;
147  })
148  .minScalar(0, s32)
149  .lower();
150 
151  getActionDefinitionsBuilder(G_IMPLICIT_DEF)
152  .legalFor({s32, s64});
153 
154  getActionDefinitionsBuilder(G_UNMERGE_VALUES)
155  .legalFor({{s32, s64}});
156 
157  getActionDefinitionsBuilder(G_MERGE_VALUES)
158  .legalFor({{s64, s32}});
159 
160  getActionDefinitionsBuilder({G_ZEXTLOAD, G_SEXTLOAD})
161  .legalForTypesWithMemDesc({{s32, p0, s8, 8},
162  {s32, p0, s16, 8}})
163  .clampScalar(0, s32, s32);
164 
165  getActionDefinitionsBuilder({G_ZEXT, G_SEXT, G_ANYEXT})
166  .legalIf([](const LegalityQuery &Query) { return false; })
167  .maxScalar(0, s32);
168 
170  .legalIf([](const LegalityQuery &Query) { return false; })
171  .maxScalar(1, s32);
172 
174  .legalForCartesianProduct({p0, s32, s64}, {s32})
175  .minScalar(0, s32)
176  .minScalar(1, s32);
177 
179  .legalFor({s32})
180  .minScalar(0, s32);
181 
183  .legalFor({{p0, s32}});
184 
185  getActionDefinitionsBuilder(G_BRINDIRECT)
186  .legalFor({p0});
187 
189  .legalFor({p0, s32, s64})
190  .minScalar(0, s32);
191 
192  getActionDefinitionsBuilder({G_AND, G_OR, G_XOR})
193  .legalFor({s32})
194  .clampScalar(0, s32, s32);
195 
196  getActionDefinitionsBuilder({G_SDIV, G_SREM, G_UDIV, G_UREM})
197  .legalIf([=, &ST](const LegalityQuery &Query) {
198  if (CheckTyN(0, Query, {s32}))
199  return true;
200  if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64}))
201  return true;
202  return false;
203  })
204  .minScalar(0, s32)
205  .libcallFor({s64});
206 
207  getActionDefinitionsBuilder({G_SHL, G_ASHR, G_LSHR})
208  .legalFor({{s32, s32}})
209  .clampScalar(1, s32, s32)
210  .clampScalar(0, s32, s32);
211 
213  .legalForCartesianProduct({s32}, {s32, p0})
214  .clampScalar(1, s32, s32)
215  .minScalar(0, s32);
216 
217  getActionDefinitionsBuilder(G_CONSTANT)
218  .legalFor({s32})
219  .clampScalar(0, s32, s32);
220 
221  getActionDefinitionsBuilder({G_PTR_ADD, G_INTTOPTR})
222  .legalFor({{p0, s32}});
223 
224  getActionDefinitionsBuilder(G_PTRTOINT)
225  .legalFor({{s32, p0}});
226 
227  getActionDefinitionsBuilder(G_FRAME_INDEX)
228  .legalFor({p0});
229 
230  getActionDefinitionsBuilder({G_GLOBAL_VALUE, G_JUMP_TABLE})
231  .legalFor({p0});
232 
233  getActionDefinitionsBuilder(G_DYN_STACKALLOC)
234  .lowerFor({{p0, s32}});
235 
236  getActionDefinitionsBuilder(G_VASTART)
237  .legalFor({p0});
238 
240  .legalIf([=, &ST](const LegalityQuery &Query) {
241  if (ST.hasMips32r2() && CheckTyN(0, Query, {s32}))
242  return true;
243  return false;
244  })
245  .lowerIf([=, &ST](const LegalityQuery &Query) {
246  if (!ST.hasMips32r2() && CheckTyN(0, Query, {s32}))
247  return true;
248  return false;
249  })
250  .maxScalar(0, s32);
251 
252  getActionDefinitionsBuilder(G_BITREVERSE)
253  .lowerFor({s32})
254  .maxScalar(0, s32);
255 
257  .legalFor({{s32, s32}})
258  .maxScalar(0, s32)
259  .maxScalar(1, s32);
260  getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)
261  .lowerFor({{s32, s32}});
262 
264  .lowerFor({{s32, s32}})
265  .maxScalar(0, s32)
266  .maxScalar(1, s32);
267  getActionDefinitionsBuilder(G_CTTZ_ZERO_UNDEF)
268  .lowerFor({{s32, s32}, {s64, s64}});
269 
271  .lowerFor({{s32, s32}})
272  .clampScalar(0, s32, s32)
273  .clampScalar(1, s32, s32);
274 
275  // FP instructions
276  getActionDefinitionsBuilder(G_FCONSTANT)
277  .legalFor({s32, s64});
278 
279  getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FABS, G_FSQRT})
280  .legalIf([=, &ST](const LegalityQuery &Query) {
281  if (CheckTyN(0, Query, {s32, s64}))
282  return true;
283  if (ST.hasMSA() && CheckTyN(0, Query, {v16s8, v8s16, v4s32, v2s64}))
284  return true;
285  return false;
286  });
287 
289  .legalFor({{s32, s32}, {s32, s64}})
290  .minScalar(0, s32);
291 
292  getActionDefinitionsBuilder({G_FCEIL, G_FFLOOR})
293  .libcallFor({s32, s64});
294 
296  .legalFor({{s64, s32}});
297 
298  getActionDefinitionsBuilder(G_FPTRUNC)
299  .legalFor({{s32, s64}});
300 
301  // FP to int conversion instructions
303  .legalForCartesianProduct({s32}, {s64, s32})
304  .libcallForCartesianProduct({s64}, {s64, s32})
305  .minScalar(0, s32);
306 
308  .libcallForCartesianProduct({s64}, {s64, s32})
309  .lowerForCartesianProduct({s32}, {s64, s32})
310  .minScalar(0, s32);
311 
312  // Int to FP conversion instructions
314  .legalForCartesianProduct({s64, s32}, {s32})
315  .libcallForCartesianProduct({s64, s32}, {s64})
316  .minScalar(1, s32);
317 
319  .libcallForCartesianProduct({s64, s32}, {s64})
320  .customForCartesianProduct({s64, s32}, {s32})
321  .minScalar(1, s32);
322 
323  getActionDefinitionsBuilder(G_SEXT_INREG).lower();
324 
325  getActionDefinitionsBuilder({G_MEMCPY, G_MEMMOVE, G_MEMSET}).libcall();
326 
328  verify(*ST.getInstrInfo());
329 }
330 
332  MachineInstr &MI) const {
333  using namespace TargetOpcode;
334 
335  MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
336  MachineRegisterInfo &MRI = *MIRBuilder.getMRI();
337 
338  const LLT s32 = LLT::scalar(32);
339  const LLT s64 = LLT::scalar(64);
340 
341  switch (MI.getOpcode()) {
342  case G_LOAD:
343  case G_STORE: {
344  unsigned MemSize = (**MI.memoperands_begin()).getSize();
345  Register Val = MI.getOperand(0).getReg();
346  unsigned Size = MRI.getType(Val).getSizeInBits();
347 
348  MachineMemOperand *MMOBase = *MI.memoperands_begin();
349 
350  assert(MemSize <= 8 && "MemSize is too large");
351  assert(Size <= 64 && "Scalar size is too large");
352 
353  // Split MemSize into two, P2HalfMemSize is largest power of two smaller
354  // then MemSize. e.g. 8 = 4 + 4 , 6 = 4 + 2, 3 = 2 + 1.
355  unsigned P2HalfMemSize, RemMemSize;
356  if (isPowerOf2_64(MemSize)) {
357  P2HalfMemSize = RemMemSize = MemSize / 2;
358  } else {
359  P2HalfMemSize = 1 << Log2_32(MemSize);
360  RemMemSize = MemSize - P2HalfMemSize;
361  }
362 
363  Register BaseAddr = MI.getOperand(1).getReg();
364  LLT PtrTy = MRI.getType(BaseAddr);
365  MachineFunction &MF = MIRBuilder.getMF();
366 
367  auto P2HalfMemOp = MF.getMachineMemOperand(MMOBase, 0, P2HalfMemSize);
368  auto RemMemOp = MF.getMachineMemOperand(MMOBase, P2HalfMemSize, RemMemSize);
369 
370  if (MI.getOpcode() == G_STORE) {
371  // Widen Val to s32 or s64 in order to create legal G_LSHR or G_UNMERGE.
372  if (Size < 32)
373  Val = MIRBuilder.buildAnyExt(s32, Val).getReg(0);
374  if (Size > 32 && Size < 64)
375  Val = MIRBuilder.buildAnyExt(s64, Val).getReg(0);
376 
377  auto C_P2HalfMemSize = MIRBuilder.buildConstant(s32, P2HalfMemSize);
378  auto Addr = MIRBuilder.buildPtrAdd(PtrTy, BaseAddr, C_P2HalfMemSize);
379 
380  if (MI.getOpcode() == G_STORE && MemSize <= 4) {
381  MIRBuilder.buildStore(Val, BaseAddr, *P2HalfMemOp);
382  auto C_P2Half_InBits = MIRBuilder.buildConstant(s32, P2HalfMemSize * 8);
383  auto Shift = MIRBuilder.buildLShr(s32, Val, C_P2Half_InBits);
384  MIRBuilder.buildStore(Shift, Addr, *RemMemOp);
385  } else {
386  auto Unmerge = MIRBuilder.buildUnmerge(s32, Val);
387  MIRBuilder.buildStore(Unmerge.getReg(0), BaseAddr, *P2HalfMemOp);
388  MIRBuilder.buildStore(Unmerge.getReg(1), Addr, *RemMemOp);
389  }
390  }
391 
392  if (MI.getOpcode() == G_LOAD) {
393 
394  if (MemSize <= 4) {
395  // This is anyextending load, use 4 byte lwr/lwl.
396  auto *Load4MMO = MF.getMachineMemOperand(MMOBase, 0, 4);
397 
398  if (Size == 32)
399  MIRBuilder.buildLoad(Val, BaseAddr, *Load4MMO);
400  else {
401  auto Load = MIRBuilder.buildLoad(s32, BaseAddr, *Load4MMO);
402  MIRBuilder.buildTrunc(Val, Load.getReg(0));
403  }
404 
405  } else {
406  auto C_P2HalfMemSize = MIRBuilder.buildConstant(s32, P2HalfMemSize);
407  auto Addr = MIRBuilder.buildPtrAdd(PtrTy, BaseAddr, C_P2HalfMemSize);
408 
409  auto Load_P2Half = MIRBuilder.buildLoad(s32, BaseAddr, *P2HalfMemOp);
410  auto Load_Rem = MIRBuilder.buildLoad(s32, Addr, *RemMemOp);
411 
412  if (Size == 64)
413  MIRBuilder.buildMerge(Val, {Load_P2Half, Load_Rem});
414  else {
415  auto Merge = MIRBuilder.buildMerge(s64, {Load_P2Half, Load_Rem});
416  MIRBuilder.buildTrunc(Val, Merge);
417  }
418  }
419  }
420  MI.eraseFromParent();
421  break;
422  }
423  case G_UITOFP: {
424  Register Dst = MI.getOperand(0).getReg();
425  Register Src = MI.getOperand(1).getReg();
426  LLT DstTy = MRI.getType(Dst);
427  LLT SrcTy = MRI.getType(Src);
428 
429  if (SrcTy != s32)
430  return false;
431  if (DstTy != s32 && DstTy != s64)
432  return false;
433 
434  // Let 0xABCDEFGH be given unsigned in MI.getOperand(1). First let's convert
435  // unsigned to double. Mantissa has 52 bits so we use following trick:
436  // First make floating point bit mask 0x43300000ABCDEFGH.
437  // Mask represents 2^52 * 0x1.00000ABCDEFGH i.e. 0x100000ABCDEFGH.0 .
438  // Next, subtract 2^52 * 0x1.0000000000000 i.e. 0x10000000000000.0 from it.
439  // Done. Trunc double to float if needed.
440 
441  auto C_HiMask = MIRBuilder.buildConstant(s32, UINT32_C(0x43300000));
442  auto Bitcast = MIRBuilder.buildMerge(s64, {Src, C_HiMask.getReg(0)});
443 
444  MachineInstrBuilder TwoP52FP = MIRBuilder.buildFConstant(
445  s64, BitsToDouble(UINT64_C(0x4330000000000000)));
446 
447  if (DstTy == s64)
448  MIRBuilder.buildFSub(Dst, Bitcast, TwoP52FP);
449  else {
450  MachineInstrBuilder ResF64 = MIRBuilder.buildFSub(s64, Bitcast, TwoP52FP);
451  MIRBuilder.buildFPTrunc(Dst, ResF64);
452  }
453 
454  MI.eraseFromParent();
455  break;
456  }
457  default:
458  return false;
459  }
460 
461  return true;
462 }
463 
464 static bool SelectMSA3OpIntrinsic(MachineInstr &MI, unsigned Opcode,
465  MachineIRBuilder &MIRBuilder,
466  const MipsSubtarget &ST) {
467  assert(ST.hasMSA() && "MSA intrinsic not supported on target without MSA.");
468  if (!MIRBuilder.buildInstr(Opcode)
469  .add(MI.getOperand(0))
470  .add(MI.getOperand(2))
471  .add(MI.getOperand(3))
472  .constrainAllUses(MIRBuilder.getTII(), *ST.getRegisterInfo(),
473  *ST.getRegBankInfo()))
474  return false;
475  MI.eraseFromParent();
476  return true;
477 }
478 
479 static bool MSA3OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode,
480  MachineIRBuilder &MIRBuilder,
481  const MipsSubtarget &ST) {
482  assert(ST.hasMSA() && "MSA intrinsic not supported on target without MSA.");
483  MIRBuilder.buildInstr(Opcode)
484  .add(MI.getOperand(0))
485  .add(MI.getOperand(2))
486  .add(MI.getOperand(3));
487  MI.eraseFromParent();
488  return true;
489 }
490 
491 static bool MSA2OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode,
492  MachineIRBuilder &MIRBuilder,
493  const MipsSubtarget &ST) {
494  assert(ST.hasMSA() && "MSA intrinsic not supported on target without MSA.");
495  MIRBuilder.buildInstr(Opcode)
496  .add(MI.getOperand(0))
497  .add(MI.getOperand(2));
498  MI.eraseFromParent();
499  return true;
500 }
501 
503  MachineInstr &MI) const {
504  MachineIRBuilder &MIRBuilder = Helper.MIRBuilder;
505  const MipsSubtarget &ST =
506  static_cast<const MipsSubtarget &>(MI.getMF()->getSubtarget());
507  const MipsInstrInfo &TII = *ST.getInstrInfo();
508  const MipsRegisterInfo &TRI = *ST.getRegisterInfo();
509  const RegisterBankInfo &RBI = *ST.getRegBankInfo();
510 
511  switch (MI.getIntrinsicID()) {
512  case Intrinsic::trap: {
513  MachineInstr *Trap = MIRBuilder.buildInstr(Mips::TRAP);
514  MI.eraseFromParent();
515  return constrainSelectedInstRegOperands(*Trap, TII, TRI, RBI);
516  }
517  case Intrinsic::vacopy: {
518  MachinePointerInfo MPO;
519  LLT PtrTy = LLT::pointer(0, 32);
520  auto Tmp =
521  MIRBuilder.buildLoad(PtrTy, MI.getOperand(2),
522  *MI.getMF()->getMachineMemOperand(
523  MPO, MachineMemOperand::MOLoad, PtrTy, Align(4)));
524  MIRBuilder.buildStore(Tmp, MI.getOperand(1),
525  *MI.getMF()->getMachineMemOperand(
526  MPO, MachineMemOperand::MOStore, PtrTy, Align(4)));
527  MI.eraseFromParent();
528  return true;
529  }
530  case Intrinsic::mips_addv_b:
531  case Intrinsic::mips_addv_h:
532  case Intrinsic::mips_addv_w:
533  case Intrinsic::mips_addv_d:
534  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_ADD, MIRBuilder, ST);
535  case Intrinsic::mips_addvi_b:
536  return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_B, MIRBuilder, ST);
537  case Intrinsic::mips_addvi_h:
538  return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_H, MIRBuilder, ST);
539  case Intrinsic::mips_addvi_w:
540  return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_W, MIRBuilder, ST);
541  case Intrinsic::mips_addvi_d:
542  return SelectMSA3OpIntrinsic(MI, Mips::ADDVI_D, MIRBuilder, ST);
543  case Intrinsic::mips_subv_b:
544  case Intrinsic::mips_subv_h:
545  case Intrinsic::mips_subv_w:
546  case Intrinsic::mips_subv_d:
547  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SUB, MIRBuilder, ST);
548  case Intrinsic::mips_subvi_b:
549  return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_B, MIRBuilder, ST);
550  case Intrinsic::mips_subvi_h:
551  return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_H, MIRBuilder, ST);
552  case Intrinsic::mips_subvi_w:
553  return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_W, MIRBuilder, ST);
554  case Intrinsic::mips_subvi_d:
555  return SelectMSA3OpIntrinsic(MI, Mips::SUBVI_D, MIRBuilder, ST);
556  case Intrinsic::mips_mulv_b:
557  case Intrinsic::mips_mulv_h:
558  case Intrinsic::mips_mulv_w:
559  case Intrinsic::mips_mulv_d:
560  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_MUL, MIRBuilder, ST);
561  case Intrinsic::mips_div_s_b:
562  case Intrinsic::mips_div_s_h:
563  case Intrinsic::mips_div_s_w:
564  case Intrinsic::mips_div_s_d:
565  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SDIV, MIRBuilder, ST);
566  case Intrinsic::mips_mod_s_b:
567  case Intrinsic::mips_mod_s_h:
568  case Intrinsic::mips_mod_s_w:
569  case Intrinsic::mips_mod_s_d:
570  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_SREM, MIRBuilder, ST);
571  case Intrinsic::mips_div_u_b:
572  case Intrinsic::mips_div_u_h:
573  case Intrinsic::mips_div_u_w:
574  case Intrinsic::mips_div_u_d:
575  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_UDIV, MIRBuilder, ST);
576  case Intrinsic::mips_mod_u_b:
577  case Intrinsic::mips_mod_u_h:
578  case Intrinsic::mips_mod_u_w:
579  case Intrinsic::mips_mod_u_d:
580  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_UREM, MIRBuilder, ST);
581  case Intrinsic::mips_fadd_w:
582  case Intrinsic::mips_fadd_d:
583  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FADD, MIRBuilder, ST);
584  case Intrinsic::mips_fsub_w:
585  case Intrinsic::mips_fsub_d:
586  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FSUB, MIRBuilder, ST);
587  case Intrinsic::mips_fmul_w:
588  case Intrinsic::mips_fmul_d:
589  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FMUL, MIRBuilder, ST);
590  case Intrinsic::mips_fdiv_w:
591  case Intrinsic::mips_fdiv_d:
592  return MSA3OpIntrinsicToGeneric(MI, TargetOpcode::G_FDIV, MIRBuilder, ST);
593  case Intrinsic::mips_fmax_a_w:
594  return SelectMSA3OpIntrinsic(MI, Mips::FMAX_A_W, MIRBuilder, ST);
595  case Intrinsic::mips_fmax_a_d:
596  return SelectMSA3OpIntrinsic(MI, Mips::FMAX_A_D, MIRBuilder, ST);
597  case Intrinsic::mips_fsqrt_w:
598  return MSA2OpIntrinsicToGeneric(MI, TargetOpcode::G_FSQRT, MIRBuilder, ST);
599  case Intrinsic::mips_fsqrt_d:
600  return MSA2OpIntrinsicToGeneric(MI, TargetOpcode::G_FSQRT, MIRBuilder, ST);
601  default:
602  break;
603  }
604  return true;
605 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
Merge
R600 Clause Merge
Definition: R600ClauseMergePass.cpp:69
llvm
---------------------— PointerInfo ------------------------------------—
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:290
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:224
MipsLegalizerInfo.h
llvm::MachineIRBuilder::getMRI
MachineRegisterInfo * getMRI()
Getter for MRI.
Definition: MachineIRBuilder.h:280
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::LegacyLegalizeActions::Bitcast
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Definition: LegacyLegalizerInfo.h:54
llvm::MipsLegalizerInfo::legalizeIntrinsic
bool legalizeIntrinsic(LegalizerHelper &Helper, MachineInstr &MI) const override
Definition: MipsLegalizerInfo.cpp:502
llvm::LegacyLegalizerInfo::computeTables
void computeTables()
Compute any ancillary tables needed to quickly decide how an operation should be handled.
Definition: LegacyLegalizerInfo.cpp:102
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:128
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:926
MSA2OpIntrinsicToGeneric
static bool MSA2OpIntrinsicToGeneric(MachineInstr &MI, unsigned Opcode, MachineIRBuilder &MIRBuilder, const MipsSubtarget &ST)
Definition: MipsLegalizerInfo.cpp:491
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:645
MipsTargetMachine.h
llvm::LegalizerHelper
Definition: LegalizerHelper.h:39
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:572
llvm::LegalizeRuleSet::minScalar
LegalizeRuleSet & minScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at least as wide as Ty.
Definition: LegalizerInfo.h:908
llvm::LLT::fixed_vector
static LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
Definition: LowLevelTypeImpl.h:75
llvm::MachineIRBuilder::buildUnmerge
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ...
Definition: MachineIRBuilder.cpp:603
llvm::MachineIRBuilder::buildLoad
MachineInstrBuilder buildLoad(const DstOp &Res, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert Res = G_LOAD Addr, MMO.
Definition: MachineIRBuilder.h:832
llvm::LLT::getSizeInBits
TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:153
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:262
isUnalignedMemmoryAccess
static bool isUnalignedMemmoryAccess(uint64_t MemSize, uint64_t AlignInBits)
Definition: MipsLegalizerInfo.cpp:29
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
llvm::SPII::Load
@ Load
Definition: SparcInstrInfo.h:32
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:94
llvm::LegalizeRuleSet::libcallForCartesianProduct
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types)
Definition: LegalizerInfo.h:732
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:212
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:579
SelectMSA3OpIntrinsic
static bool SelectMSA3OpIntrinsic(MachineInstr &MI, unsigned Opcode, MachineIRBuilder &MIRBuilder, const MipsSubtarget &ST)
Definition: MipsLegalizerInfo.cpp:464
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:69
uint64_t
llvm::ARM_MB::ST
@ ST
Definition: ARMBaseInfo.h:73
Addr
uint64_t Addr
Definition: ELFObjHandler.cpp:80
llvm::ISD::TRAP
@ TRAP
TRAP - Trapping instruction.
Definition: ISDOpcodes.h:1088
llvm::MachinePointerInfo
This class contains a discriminated union of information about pointers in memory operands,...
Definition: MachineMemOperand.h:38
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:953
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:1612
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:671
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:611
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:320
llvm::MachineFunction
Definition: MachineFunction.h:230
llvm::MachineIRBuilder::buildInstr
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
Definition: MachineIRBuilder.h:367
llvm::LegalityQuery
The LegalityQuery object bundles together all the information that's needed to decide whether a given...
Definition: LegalizerInfo.h:108
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:479
llvm::MipsSubtarget
Definition: MipsSubtarget.h:39
llvm::MachineMemOperand::MOLoad
@ MOLoad
The memory access reads data.
Definition: MachineMemOperand.h:135
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:414
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::LegalizerInfo::getLegacyLegalizerInfo
const LegacyLegalizerInfo & getLegacyLegalizerInfo() const
Definition: LegalizerInfo.h:1114
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:128
LegalizerHelper.h
llvm::MachineIRBuilder::getTII
const TargetInstrInfo & getTII()
Definition: MachineIRBuilder.h:256
llvm::MachineMemOperand::MOStore
@ MOStore
The memory access writes data.
Definition: MachineMemOperand.h:137
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:378
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:110
N
#define N
llvm::LegalizerHelper::MIRBuilder
MachineIRBuilder & MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions.
Definition: LegalizerHelper.h:43
llvm::MachineIRBuilder::buildLShr
MachineInstrBuilder buildLShr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, Optional< unsigned > Flags=None)
Definition: MachineIRBuilder.h:1482
llvm::MachineIRBuilder::buildMerge
MachineInstrBuilder buildMerge(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ...
Definition: MachineIRBuilder.cpp:586
llvm::MachineIRBuilder::buildStore
MachineInstrBuilder buildStore(const SrcOp &Val, const SrcOp &Addr, MachineMemOperand &MMO)
Build and insert G_STORE Val, Addr, MMO.
Definition: MachineIRBuilder.cpp:387
llvm::LegalizeRuleSet::libcallFor
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
Definition: LegalizerInfo.h:724
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:331
llvm::LLT
Definition: LowLevelTypeImpl.h:40