LLVM  17.0.0git
PPCInstructionSelector.cpp
Go to the documentation of this file.
1 //===- PPCInstructionSelector.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 InstructionSelector class for
10 /// PowerPC.
11 //===----------------------------------------------------------------------===//
12 
13 #include "PPC.h"
14 #include "PPCInstrInfo.h"
15 #include "PPCRegisterBankInfo.h"
16 #include "PPCSubtarget.h"
17 #include "PPCTargetMachine.h"
24 #include "llvm/IR/IntrinsicsPowerPC.h"
25 #include "llvm/Support/Debug.h"
26 
27 #define DEBUG_TYPE "ppc-gisel"
28 
29 using namespace llvm;
30 
31 namespace {
32 
33 #define GET_GLOBALISEL_PREDICATE_BITSET
34 #include "PPCGenGlobalISel.inc"
35 #undef GET_GLOBALISEL_PREDICATE_BITSET
36 
37 class PPCInstructionSelector : public InstructionSelector {
38 public:
39  PPCInstructionSelector(const PPCTargetMachine &TM, const PPCSubtarget &STI,
40  const PPCRegisterBankInfo &RBI);
41 
42  bool select(MachineInstr &I) override;
43  static const char *getName() { return DEBUG_TYPE; }
44 
45 private:
46  /// tblgen generated 'select' implementation that is used as the initial
47  /// selector for the patterns that do not require complex C++.
48  bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
49 
50  bool selectFPToInt(MachineInstr &I, MachineBasicBlock &MBB,
51  MachineRegisterInfo &MRI) const;
52  bool selectIntToFP(MachineInstr &I, MachineBasicBlock &MBB,
53  MachineRegisterInfo &MRI) const;
54 
55  bool selectZExt(MachineInstr &I, MachineBasicBlock &MBB,
56  MachineRegisterInfo &MRI) const;
57 
58  std::optional<bool> selectI64ImmDirect(MachineInstr &I,
61  uint64_t Imm) const;
63  MachineRegisterInfo &MRI) const;
64 
65  const PPCSubtarget &STI;
66  const PPCInstrInfo &TII;
67  const PPCRegisterInfo &TRI;
68  const PPCRegisterBankInfo &RBI;
69 
70 #define GET_GLOBALISEL_PREDICATES_DECL
71 #include "PPCGenGlobalISel.inc"
72 #undef GET_GLOBALISEL_PREDICATES_DECL
73 
74 #define GET_GLOBALISEL_TEMPORARIES_DECL
75 #include "PPCGenGlobalISel.inc"
76 #undef GET_GLOBALISEL_TEMPORARIES_DECL
77 };
78 
79 } // end anonymous namespace
80 
81 #define GET_GLOBALISEL_IMPL
82 #include "PPCGenGlobalISel.inc"
83 #undef GET_GLOBALISEL_IMPL
84 
85 PPCInstructionSelector::PPCInstructionSelector(const PPCTargetMachine &TM,
86  const PPCSubtarget &STI,
87  const PPCRegisterBankInfo &RBI)
88  : STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI),
90 #include "PPCGenGlobalISel.inc"
93 #include "PPCGenGlobalISel.inc"
95 {
96 }
97 
98 static const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank *RB) {
99  if (RB->getID() == PPC::GPRRegBankID) {
100  if (Ty.getSizeInBits() == 64)
101  return &PPC::G8RCRegClass;
102  if (Ty.getSizeInBits() <= 32)
103  return &PPC::GPRCRegClass;
104  }
105  if (RB->getID() == PPC::FPRRegBankID) {
106  if (Ty.getSizeInBits() == 32)
107  return &PPC::F4RCRegClass;
108  if (Ty.getSizeInBits() == 64)
109  return &PPC::F8RCRegClass;
110  }
111  if (RB->getID() == PPC::CRRegBankID) {
112  if (Ty.getSizeInBits() == 1)
113  return &PPC::CRBITRCRegClass;
114  if (Ty.getSizeInBits() == 4)
115  return &PPC::CRRCRegClass;
116  }
117 
118  llvm_unreachable("Unknown RegBank!");
119 }
120 
123  const RegisterBankInfo &RBI) {
124  Register DstReg = I.getOperand(0).getReg();
125 
126  if (DstReg.isPhysical())
127  return true;
128 
129  const RegisterBank *DstRegBank = RBI.getRegBank(DstReg, MRI, TRI);
130  const TargetRegisterClass *DstRC =
131  getRegClass(MRI.getType(DstReg), DstRegBank);
132 
133  // No need to constrain SrcReg. It will get constrained when we hit another of
134  // its use or its defs.
135  // Copies do not have constraints.
136  if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
137  LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
138  << " operand\n");
139  return false;
140  }
141 
142  return true;
143 }
144 
145 static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID,
146  unsigned OpSize) {
147  const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
148  switch (RegBankID) {
149  case PPC::GPRRegBankID:
150  switch (OpSize) {
151  case 32:
152  return IsStore ? PPC::STW : PPC::LWZ;
153  case 64:
154  return IsStore ? PPC::STD : PPC::LD;
155  default:
156  llvm_unreachable("Unexpected size!");
157  }
158  break;
159  case PPC::FPRRegBankID:
160  switch (OpSize) {
161  case 32:
162  return IsStore ? PPC::STFS : PPC::LFS;
163  case 64:
164  return IsStore ? PPC::STFD : PPC::LFD;
165  default:
166  llvm_unreachable("Unexpected size!");
167  }
168  break;
169  default:
170  llvm_unreachable("Unexpected register bank!");
171  }
172  return GenericOpc;
173 }
174 
175 bool PPCInstructionSelector::selectIntToFP(MachineInstr &I,
177  MachineRegisterInfo &MRI) const {
178  if (!STI.hasDirectMove() || !STI.isPPC64() || !STI.hasFPCVT())
179  return false;
180 
181  const DebugLoc &DbgLoc = I.getDebugLoc();
182  const Register DstReg = I.getOperand(0).getReg();
183  const Register SrcReg = I.getOperand(1).getReg();
184 
185  Register MoveReg = MRI.createVirtualRegister(&PPC::VSFRCRegClass);
186 
187  // For now, only handle the case for 64 bit integer.
188  BuildMI(MBB, I, DbgLoc, TII.get(PPC::MTVSRD), MoveReg).addReg(SrcReg);
189 
190  bool IsSingle = MRI.getType(DstReg).getSizeInBits() == 32;
191  bool IsSigned = I.getOpcode() == TargetOpcode::G_SITOFP;
192  unsigned ConvOp = IsSingle ? (IsSigned ? PPC::XSCVSXDSP : PPC::XSCVUXDSP)
193  : (IsSigned ? PPC::XSCVSXDDP : PPC::XSCVUXDDP);
194 
195  MachineInstr *MI =
196  BuildMI(MBB, I, DbgLoc, TII.get(ConvOp), DstReg).addReg(MoveReg);
197 
198  I.eraseFromParent();
199  return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
200 }
201 
202 bool PPCInstructionSelector::selectFPToInt(MachineInstr &I,
204  MachineRegisterInfo &MRI) const {
205  if (!STI.hasDirectMove() || !STI.isPPC64() || !STI.hasFPCVT())
206  return false;
207 
208  const DebugLoc &DbgLoc = I.getDebugLoc();
209  const Register DstReg = I.getOperand(0).getReg();
210  const Register SrcReg = I.getOperand(1).getReg();
211 
212  Register CopyReg = MRI.createVirtualRegister(&PPC::VSFRCRegClass);
213  BuildMI(MBB, I, DbgLoc, TII.get(TargetOpcode::COPY), CopyReg).addReg(SrcReg);
214 
215  Register ConvReg = MRI.createVirtualRegister(&PPC::VSFRCRegClass);
216 
217  bool IsSigned = I.getOpcode() == TargetOpcode::G_FPTOSI;
218 
219  // single-precision is stored as double-precision on PPC in registers, so
220  // always use double-precision convertions.
221  unsigned ConvOp = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
222 
223  BuildMI(MBB, I, DbgLoc, TII.get(ConvOp), ConvReg).addReg(CopyReg);
224 
225  MachineInstr *MI =
226  BuildMI(MBB, I, DbgLoc, TII.get(PPC::MFVSRD), DstReg).addReg(ConvReg);
227 
228  I.eraseFromParent();
229  return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
230 }
231 
232 bool PPCInstructionSelector::selectZExt(MachineInstr &I, MachineBasicBlock &MBB,
233  MachineRegisterInfo &MRI) const {
234  const Register DstReg = I.getOperand(0).getReg();
235  const LLT DstTy = MRI.getType(DstReg);
236  const RegisterBank *DstRegBank = RBI.getRegBank(DstReg, MRI, TRI);
237 
238  const Register SrcReg = I.getOperand(1).getReg();
239 
240  assert(DstTy.getSizeInBits() == 64 && "Unexpected dest size!");
241  assert(MRI.getType(SrcReg).getSizeInBits() == 32 && "Unexpected src size!");
242 
243  Register ImpDefReg =
244  MRI.createVirtualRegister(getRegClass(DstTy, DstRegBank));
245  BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::IMPLICIT_DEF),
246  ImpDefReg);
247 
248  Register NewDefReg =
249  MRI.createVirtualRegister(getRegClass(DstTy, DstRegBank));
250  BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::INSERT_SUBREG),
251  NewDefReg)
252  .addReg(ImpDefReg)
253  .addReg(SrcReg)
254  .addImm(PPC::sub_32);
255 
256  MachineInstr *MI =
257  BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), DstReg)
258  .addReg(NewDefReg)
259  .addImm(0)
260  .addImm(32);
261 
262  I.eraseFromParent();
263  return constrainSelectedInstRegOperands(*MI, TII, TRI, RBI);
264 }
265 
266 // For any 32 < Num < 64, check if the Imm contains at least Num consecutive
267 // zeros and return the number of bits by the left of these consecutive zeros.
269  uint32_t HiTZ = countTrailingZeros<uint32_t>(Hi_32(Imm));
270  uint32_t LoLZ = countLeadingZeros<uint32_t>(Lo_32(Imm));
271  if ((HiTZ + LoLZ) >= Num)
272  return (32 + HiTZ);
273  return 0;
274 }
275 
276 // Direct materialization of 64-bit constants by enumerated patterns.
277 // Similar to PPCISelDAGToDAG::selectI64ImmDirect().
281  Register Reg,
282  uint64_t Imm) const {
283  unsigned TZ = countTrailingZeros<uint64_t>(Imm);
284  unsigned LZ = countLeadingZeros<uint64_t>(Imm);
285  unsigned TO = countTrailingOnes<uint64_t>(Imm);
286  unsigned LO = countLeadingOnes<uint64_t>(Imm);
287  uint32_t Hi32 = Hi_32(Imm);
288  uint32_t Lo32 = Lo_32(Imm);
289  uint32_t Shift = 0;
290 
291  // Following patterns use 1 instructions to materialize the Imm.
292 
293  // 1-1) Patterns : {zeros}{15-bit valve}
294  // {ones}{15-bit valve}
295  if (isInt<16>(Imm))
296  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), Reg)
297  .addImm(Imm)
298  .constrainAllUses(TII, TRI, RBI);
299  // 1-2) Patterns : {zeros}{15-bit valve}{16 zeros}
300  // {ones}{15-bit valve}{16 zeros}
301  if (TZ > 15 && (LZ > 32 || LO > 32))
302  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), Reg)
303  .addImm((Imm >> 16) & 0xffff)
304  .constrainAllUses(TII, TRI, RBI);
305 
306  // Following patterns use 2 instructions to materialize the Imm.
307 
308  assert(LZ < 64 && "Unexpected leading zeros here.");
309  // Count of ones follwing the leading zeros.
310  unsigned FO = countLeadingOnes<uint64_t>(Imm << LZ);
311  // 2-1) Patterns : {zeros}{31-bit value}
312  // {ones}{31-bit value}
313  if (isInt<32>(Imm)) {
314  uint64_t ImmHi16 = (Imm >> 16) & 0xffff;
315  unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
316  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
317  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
318  .addImm((Imm >> 16) & 0xffff)
319  .constrainAllUses(TII, TRI, RBI))
320  return false;
321  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Reg)
322  .addReg(TmpReg, RegState::Kill)
323  .addImm(Imm & 0xffff)
324  .constrainAllUses(TII, TRI, RBI);
325  }
326  // 2-2) Patterns : {zeros}{ones}{15-bit value}{zeros}
327  // {zeros}{15-bit value}{zeros}
328  // {zeros}{ones}{15-bit value}
329  // {ones}{15-bit value}{zeros}
330  // We can take advantage of LI's sign-extension semantics to generate leading
331  // ones, and then use RLDIC to mask off the ones in both sides after rotation.
332  if ((LZ + FO + TZ) > 48) {
333  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
334  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
335  .addImm((Imm >> TZ) & 0xffff)
336  .constrainAllUses(TII, TRI, RBI))
337  return false;
338  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIC), Reg)
339  .addReg(TmpReg, RegState::Kill)
340  .addImm(TZ)
341  .addImm(LZ)
342  .constrainAllUses(TII, TRI, RBI);
343  }
344  // 2-3) Pattern : {zeros}{15-bit value}{ones}
345  // Shift right the Imm by (48 - LZ) bits to construct a negtive 16 bits value,
346  // therefore we can take advantage of LI's sign-extension semantics, and then
347  // mask them off after rotation.
348  //
349  // +--LZ--||-15-bit-||--TO--+ +-------------|--16-bit--+
350  // |00000001bbbbbbbbb1111111| -> |00000000000001bbbbbbbbb1|
351  // +------------------------+ +------------------------+
352  // 63 0 63 0
353  // Imm (Imm >> (48 - LZ) & 0xffff)
354  // +----sext-----|--16-bit--+ +clear-|-----------------+
355  // |11111111111111bbbbbbbbb1| -> |00000001bbbbbbbbb1111111|
356  // +------------------------+ +------------------------+
357  // 63 0 63 0
358  // LI8: sext many leading zeros RLDICL: rotate left (48 - LZ), clear left LZ
359  if ((LZ + TO) > 48) {
360  // Since the immediates with (LZ > 32) have been handled by previous
361  // patterns, here we have (LZ <= 32) to make sure we will not shift right
362  // the Imm by a negative value.
363  assert(LZ <= 32 && "Unexpected shift value.");
364  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
365  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
366  .addImm(Imm >> (48 - LZ) & 0xffff)
367  .constrainAllUses(TII, TRI, RBI))
368  return false;
369  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
370  .addReg(TmpReg, RegState::Kill)
371  .addImm(48 - LZ)
372  .addImm(LZ)
373  .constrainAllUses(TII, TRI, RBI);
374  }
375  // 2-4) Patterns : {zeros}{ones}{15-bit value}{ones}
376  // {ones}{15-bit value}{ones}
377  // We can take advantage of LI's sign-extension semantics to generate leading
378  // ones, and then use RLDICL to mask off the ones in left sides (if required)
379  // after rotation.
380  //
381  // +-LZ-FO||-15-bit-||--TO--+ +-------------|--16-bit--+
382  // |00011110bbbbbbbbb1111111| -> |000000000011110bbbbbbbbb|
383  // +------------------------+ +------------------------+
384  // 63 0 63 0
385  // Imm (Imm >> TO) & 0xffff
386  // +----sext-----|--16-bit--+ +LZ|---------------------+
387  // |111111111111110bbbbbbbbb| -> |00011110bbbbbbbbb1111111|
388  // +------------------------+ +------------------------+
389  // 63 0 63 0
390  // LI8: sext many leading zeros RLDICL: rotate left TO, clear left LZ
391  if ((LZ + FO + TO) > 48) {
392  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
393  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
394  .addImm((Imm >> TO) & 0xffff)
395  .constrainAllUses(TII, TRI, RBI))
396  return false;
397  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
398  .addReg(TmpReg, RegState::Kill)
399  .addImm(TO)
400  .addImm(LZ)
401  .constrainAllUses(TII, TRI, RBI);
402  }
403  // 2-5) Pattern : {32 zeros}{****}{0}{15-bit value}
404  // If Hi32 is zero and the Lo16(in Lo32) can be presented as a positive 16 bit
405  // value, we can use LI for Lo16 without generating leading ones then add the
406  // Hi16(in Lo32).
407  if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
408  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
409  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
410  .addImm(Lo32 & 0xffff)
411  .constrainAllUses(TII, TRI, RBI))
412  return false;
413  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORIS8), Reg)
414  .addReg(TmpReg, RegState::Kill)
415  .addImm(Lo32 >> 16)
416  .constrainAllUses(TII, TRI, RBI);
417  }
418  // 2-6) Patterns : {******}{49 zeros}{******}
419  // {******}{49 ones}{******}
420  // If the Imm contains 49 consecutive zeros/ones, it means that a total of 15
421  // bits remain on both sides. Rotate right the Imm to construct an int<16>
422  // value, use LI for int<16> value and then use RLDICL without mask to rotate
423  // it back.
424  //
425  // 1) findContiguousZerosAtLeast(Imm, 49)
426  // +------|--zeros-|------+ +---ones--||---15 bit--+
427  // |bbbbbb0000000000aaaaaa| -> |0000000000aaaaaabbbbbb|
428  // +----------------------+ +----------------------+
429  // 63 0 63 0
430  //
431  // 2) findContiguousZerosAtLeast(~Imm, 49)
432  // +------|--ones--|------+ +---ones--||---15 bit--+
433  // |bbbbbb1111111111aaaaaa| -> |1111111111aaaaaabbbbbb|
434  // +----------------------+ +----------------------+
435  // 63 0 63 0
436  if ((Shift = findContiguousZerosAtLeast(Imm, 49)) ||
438  uint64_t RotImm = APInt(64, Imm).rotr(Shift).getZExtValue();
439  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
440  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
441  .addImm(RotImm & 0xffff)
442  .constrainAllUses(TII, TRI, RBI))
443  return false;
444  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
445  .addReg(TmpReg, RegState::Kill)
446  .addImm(Shift)
447  .addImm(0)
448  .constrainAllUses(TII, TRI, RBI);
449  }
450 
451  // Following patterns use 3 instructions to materialize the Imm.
452 
453  // 3-1) Patterns : {zeros}{ones}{31-bit value}{zeros}
454  // {zeros}{31-bit value}{zeros}
455  // {zeros}{ones}{31-bit value}
456  // {ones}{31-bit value}{zeros}
457  // We can take advantage of LIS's sign-extension semantics to generate leading
458  // ones, add the remaining bits with ORI, and then use RLDIC to mask off the
459  // ones in both sides after rotation.
460  if ((LZ + FO + TZ) > 32) {
461  uint64_t ImmHi16 = (Imm >> (TZ + 16)) & 0xffff;
462  unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
463  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
464  Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
465  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
466  .addImm(ImmHi16)
467  .constrainAllUses(TII, TRI, RBI))
468  return false;
469  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
470  .addReg(TmpReg, RegState::Kill)
471  .addImm((Imm >> TZ) & 0xffff)
472  .constrainAllUses(TII, TRI, RBI))
473  return false;
474  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIC), Reg)
475  .addReg(Tmp2Reg, RegState::Kill)
476  .addImm(TZ)
477  .addImm(LZ)
478  .constrainAllUses(TII, TRI, RBI);
479  }
480  // 3-2) Pattern : {zeros}{31-bit value}{ones}
481  // Shift right the Imm by (32 - LZ) bits to construct a negative 32 bits
482  // value, therefore we can take advantage of LIS's sign-extension semantics,
483  // add the remaining bits with ORI, and then mask them off after rotation.
484  // This is similar to Pattern 2-3, please refer to the diagram there.
485  if ((LZ + TO) > 32) {
486  // Since the immediates with (LZ > 32) have been handled by previous
487  // patterns, here we have (LZ <= 32) to make sure we will not shift right
488  // the Imm by a negative value.
489  assert(LZ <= 32 && "Unexpected shift value.");
490  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
491  Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
492  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), TmpReg)
493  .addImm((Imm >> (48 - LZ)) & 0xffff)
494  .constrainAllUses(TII, TRI, RBI))
495  return false;
496  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
497  .addReg(TmpReg, RegState::Kill)
498  .addImm((Imm >> (32 - LZ)) & 0xffff)
499  .constrainAllUses(TII, TRI, RBI))
500  return false;
501  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
502  .addReg(Tmp2Reg, RegState::Kill)
503  .addImm(32 - LZ)
504  .addImm(LZ)
505  .constrainAllUses(TII, TRI, RBI);
506  }
507  // 3-3) Patterns : {zeros}{ones}{31-bit value}{ones}
508  // {ones}{31-bit value}{ones}
509  // We can take advantage of LIS's sign-extension semantics to generate leading
510  // ones, add the remaining bits with ORI, and then use RLDICL to mask off the
511  // ones in left sides (if required) after rotation.
512  // This is similar to Pattern 2-4, please refer to the diagram there.
513  if ((LZ + FO + TO) > 32) {
514  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
515  Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
516  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), TmpReg)
517  .addImm((Imm >> (TO + 16)) & 0xffff)
518  .constrainAllUses(TII, TRI, RBI))
519  return false;
520  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
521  .addReg(TmpReg, RegState::Kill)
522  .addImm((Imm >> TO) & 0xffff)
523  .constrainAllUses(TII, TRI, RBI))
524  return false;
525  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
526  .addReg(Tmp2Reg, RegState::Kill)
527  .addImm(TO)
528  .addImm(LZ)
529  .constrainAllUses(TII, TRI, RBI);
530  }
531  // 3-4) Patterns : High word == Low word
532  if (Hi32 == Lo32) {
533  // Handle the first 32 bits.
534  uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
535  unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
536  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
537  Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
538  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
539  .addImm(ImmHi16)
540  .constrainAllUses(TII, TRI, RBI))
541  return false;
542  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
543  .addReg(TmpReg, RegState::Kill)
544  .addImm(Lo32 & 0xffff)
545  .constrainAllUses(TII, TRI, RBI))
546  return false;
547  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIMI), Reg)
548  .addReg(Tmp2Reg)
549  .addReg(Tmp2Reg, RegState::Kill)
550  .addImm(32)
551  .addImm(0)
552  .constrainAllUses(TII, TRI, RBI);
553  }
554  // 3-5) Patterns : {******}{33 zeros}{******}
555  // {******}{33 ones}{******}
556  // If the Imm contains 33 consecutive zeros/ones, it means that a total of 31
557  // bits remain on both sides. Rotate right the Imm to construct an int<32>
558  // value, use LIS + ORI for int<32> value and then use RLDICL without mask to
559  // rotate it back.
560  // This is similar to Pattern 2-6, please refer to the diagram there.
561  if ((Shift = findContiguousZerosAtLeast(Imm, 33)) ||
563  uint64_t RotImm = APInt(64, Imm).rotr(Shift).getZExtValue();
564  uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
565  unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
566  Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
567  Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
568  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
569  .addImm(ImmHi16)
570  .constrainAllUses(TII, TRI, RBI))
571  return false;
572  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
573  .addReg(TmpReg, RegState::Kill)
574  .addImm(RotImm & 0xffff)
575  .constrainAllUses(TII, TRI, RBI))
576  return false;
577  return BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
578  .addReg(Tmp2Reg, RegState::Kill)
579  .addImm(Shift)
580  .addImm(0)
581  .constrainAllUses(TII, TRI, RBI);
582  }
583 
584  // If we end up here then no instructions were inserted.
585  return std::nullopt;
586 }
587 
588 // Derived from PPCISelDAGToDAG::selectI64Imm().
589 // TODO: Add support for prefixed instructions.
592  MachineRegisterInfo &MRI) const {
593  assert(I.getOpcode() == TargetOpcode::G_CONSTANT && "Unexpected G code");
594 
595  Register DstReg = I.getOperand(0).getReg();
596  int64_t Imm = I.getOperand(1).getCImm()->getValue().getZExtValue();
597  // No more than 3 instructions are used if we can select the i64 immediate
598  // directly.
599  if (std::optional<bool> Res = selectI64ImmDirect(I, MBB, MRI, DstReg, Imm)) {
600  I.eraseFromParent();
601  return *Res;
602  }
603 
604  // Calculate the last bits as required.
605  uint32_t Hi16 = (Lo_32(Imm) >> 16) & 0xffff;
606  uint32_t Lo16 = Lo_32(Imm) & 0xffff;
607 
608  Register Reg =
609  (Hi16 || Lo16) ? MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
610 
611  // Handle the upper 32 bit value.
612  std::optional<bool> Res =
613  selectI64ImmDirect(I, MBB, MRI, Reg, Imm & 0xffffffff00000000);
614  if (!Res || !*Res)
615  return false;
616 
617  // Add in the last bits as required.
618  if (Hi16) {
619  Register TmpReg =
620  Lo16 ? MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
621  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORIS8), TmpReg)
623  .addImm(Hi16)
624  .constrainAllUses(TII, TRI, RBI))
625  return false;
626  Reg = TmpReg;
627  }
628  if (Lo16) {
629  if (!BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), DstReg)
631  .addImm(Lo16)
632  .constrainAllUses(TII, TRI, RBI))
633  return false;
634  }
635  I.eraseFromParent();
636  return true;
637 }
638 
640  auto &MBB = *I.getParent();
641  auto &MF = *MBB.getParent();
642  auto &MRI = MF.getRegInfo();
643 
644  if (!isPreISelGenericOpcode(I.getOpcode())) {
645  if (I.isCopy())
646  return selectCopy(I, TII, MRI, TRI, RBI);
647 
648  return true;
649  }
650 
651  if (selectImpl(I, *CoverageInfo))
652  return true;
653 
654  unsigned Opcode = I.getOpcode();
655 
656  switch (Opcode) {
657  default:
658  return false;
659  case TargetOpcode::G_LOAD:
660  case TargetOpcode::G_STORE: {
661  GLoadStore &LdSt = cast<GLoadStore>(I);
662  LLT PtrTy = MRI.getType(LdSt.getPointerReg());
663 
664  if (PtrTy != LLT::pointer(0, 64)) {
665  LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
666  << ", expected: " << LLT::pointer(0, 64) << '\n');
667  return false;
668  }
669 
670  auto SelectLoadStoreAddressingMode = [&]() -> MachineInstr * {
671  const unsigned NewOpc = selectLoadStoreOp(
672  I.getOpcode(), RBI.getRegBank(LdSt.getReg(0), MRI, TRI)->getID(),
673  LdSt.getMemSizeInBits());
674 
675  if (NewOpc == I.getOpcode())
676  return nullptr;
677 
678  // For now, simply use DForm with load/store addr as base and 0 as imm.
679  // FIXME: optimize load/store with some specific address patterns.
680  I.setDesc(TII.get(NewOpc));
681  Register AddrReg = I.getOperand(1).getReg();
682  bool IsKill = I.getOperand(1).isKill();
683  I.getOperand(1).ChangeToImmediate(0);
684  I.addOperand(*I.getParent()->getParent(),
685  MachineOperand::CreateReg(AddrReg, /* isDef */ false,
686  /* isImp */ false, IsKill));
687  return &I;
688  };
689 
690  MachineInstr *LoadStore = SelectLoadStoreAddressingMode();
691  if (!LoadStore)
692  return false;
693 
695  }
696  case TargetOpcode::G_SITOFP:
697  case TargetOpcode::G_UITOFP:
698  return selectIntToFP(I, MBB, MRI);
699  case TargetOpcode::G_FPTOSI:
700  case TargetOpcode::G_FPTOUI:
701  return selectFPToInt(I, MBB, MRI);
702  // G_SEXT will be selected in tb-gen pattern.
703  case TargetOpcode::G_ZEXT:
704  return selectZExt(I, MBB, MRI);
705  case TargetOpcode::G_CONSTANT:
706  return selectI64Imm(I, MBB, MRI);
707  }
708  return false;
709 }
710 
711 namespace llvm {
714  const PPCSubtarget &Subtarget,
715  const PPCRegisterBankInfo &RBI) {
716  return new PPCInstructionSelector(TM, Subtarget, RBI);
717 }
718 } // end namespace llvm
llvm::PPCRegisterInfo
Definition: PPCRegisterInfo.h:57
llvm::AArch64CC::LO
@ LO
Definition: AArch64BaseInfo.h:258
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:20
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:109
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_PREDICATES_INIT
llvm::MachineRegisterInfo::createVirtualRegister
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Definition: MachineRegisterInfo.cpp:157
llvm::MachineRegisterInfo
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Definition: MachineRegisterInfo.h:51
llvm::APInt::rotr
APInt rotr(unsigned rotateAmt) const
Rotate right by rotateAmt.
Definition: APInt.cpp:1116
pointer
Replace within non kernel function use of LDS with pointer
Definition: AMDGPUReplaceLDSUseWithPointer.cpp:631
llvm::NVPTX::LoadStore
LoadStore
Definition: NVPTX.h:100
llvm::ARM_MB::LD
@ LD
Definition: ARMBaseInfo.h:72
llvm::isPreISelGenericOpcode
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
Definition: TargetOpcodes.h:30
llvm::RegisterBankInfo::getRegBank
RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
Definition: RegisterBankInfo.h:431
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::PPCInstrInfo
Definition: PPCInstrInfo.h:212
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:236
Shift
bool Shift
Definition: README.txt:468
llvm::GLoadStore::getMemSizeInBits
uint64_t getMemSizeInBits() const
Returns the size in bits of the memory access.
Definition: GenericMachineInstrs.h:63
GenericMachineInstrs.h
MachineIRBuilder.h
llvm::Lo_32
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition: MathExtras.h:165
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
PPCRegisterBankInfo.h
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:152
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
PPCSubtarget.h
llvm::Register::isPhysical
bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:97
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:98
select
into xmm2 addss xmm2 xmm1 xmm3 addss xmm3 movaps xmm0 unpcklps xmm0 ret seems silly when it could just be one addps Expand libm rounding functions main should enable SSE DAZ mode and other fast SSE modes Think about doing i64 math in SSE regs on x86 This testcase should have no SSE instructions in and only one load from a constant double ret double C the select is being which prevents the dag combiner from turning select(load CPI1)
llvm::RegisterBank
This class implements the register bank concept.
Definition: RegisterBank.h:28
llvm::PPCSubtarget
Definition: PPCSubtarget.h:71
GET_GLOBALISEL_TEMPORARIES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
llvm::createPPCInstructionSelector
InstructionSelector * createPPCInstructionSelector(const PPCTargetMachine &TM, const PPCSubtarget &Subtarget, const PPCRegisterBankInfo &RBI)
Definition: PPCInstructionSelector.cpp:713
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:45
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:125
llvm::APInt::getZExtValue
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1494
include
include(LLVM-Build) add_subdirectory(IR) add_subdirectory(FuzzMutate) add_subdirectory(FileCheck) add_subdirectory(InterfaceStub) add_subdirectory(IRPrinter) add_subdirectory(IRReader) add_subdirectory(CodeGen) add_subdirectory(BinaryFormat) add_subdirectory(Bitcode) add_subdirectory(Bitstream) add_subdirectory(DWARFLinker) add_subdirectory(DWARFLinkerParallel) add_subdirectory(Extensions) add_subdirectory(Frontend) add_subdirectory(Transforms) add_subdirectory(Linker) add_subdirectory(Analysis) add_subdirectory(LTO) add_subdirectory(MC) add_subdirectory(MCA) add_subdirectory(ObjCopy) add_subdirectory(Object) add_subdirectory(ObjectYAML) add_subdirectory(Option) add_subdirectory(Remarks) add_subdirectory(Debuginfod) add_subdirectory(DebugInfo) add_subdirectory(DWP) add_subdirectory(ExecutionEngine) add_subdirectory(Target) add_subdirectory(AsmParser) add_subdirectory(LineEditor) add_subdirectory(ProfileData) add_subdirectory(Passes) add_subdirectory(TargetParser) add_subdirectory(TextAPI) add_subdirectory(ToolDrivers) add_subdirectory(XRay) if(LLVM_INCLUDE_TESTS) add_subdirectory(Testing) endif() add_subdirectory(WindowsDriver) add_subdirectory(WindowsManifest) set(LLVMCONFIGLIBRARYDEPENDENCIESINC "$
Definition: CMakeLists.txt:1
PPC.h
llvm::RegisterBank::getID
unsigned getID() const
Get the identifier of this register bank.
Definition: RegisterBank.h:47
llvm::GLoadStore::getPointerReg
Register getPointerReg() const
Get the source register of the pointer value.
Definition: GenericMachineInstrs.h:44
llvm::RegisterBankInfo::constrainGenericRegister
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
Definition: RegisterBankInfo.cpp:129
llvm::LLT::getSizeInBits
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
Definition: LowLevelTypeImpl.h:159
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:94
llvm::Hi_32
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition: MathExtras.h:160
InstructionSelector.h
llvm::RegisterBankInfo
Holds all the information related to register banks.
Definition: RegisterBankInfo.h:39
llvm::InstructionSelector
Provides the logic to select generic machine instructions.
Definition: InstructionSelector.h:428
llvm::CodeGenCoverage
Definition: CodeGenCoverage.h:19
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
uint64_t
PPCInstrInfo.h
I
#define I(x, y, z)
Definition: MD5.cpp:58
MachineConstantPool.h
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:265
selectCopy
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Definition: PPCInstructionSelector.cpp:121
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
findContiguousZerosAtLeast
static uint32_t findContiguousZerosAtLeast(uint64_t Imm, unsigned Num)
Definition: PPCInstructionSelector.cpp:268
llvm::MachineInstrBuilder::constrainAllUses
bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
Definition: MachineInstrBuilder.h:326
llvm::APInt
Class for arbitrary precision integers.
Definition: APInt.h:75
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
uint32_t
DEBUG_TYPE
#define DEBUG_TYPE
Definition: PPCInstructionSelector.cpp:27
selectI64ImmDirect
static SDNode * selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
Definition: PPCISelDAGToDAG.cpp:937
llvm::GenericMachineInstr::getReg
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
Definition: GenericMachineInstrs.h:32
InstructionSelectorImpl.h
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
getRegClass
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
Definition: AArch64InstrInfo.cpp:3228
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
selectI64Imm
static SDNode * selectI64Imm(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned *InstCnt=nullptr)
Definition: PPCISelDAGToDAG.cpp:1286
llvm::GLoadStore
Represents any type of generic load or store.
Definition: GenericMachineInstrs.h:41
selectLoadStoreOp
static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
Definition: PPCInstructionSelector.cpp:145
llvm::MCID::MoveReg
@ MoveReg
Definition: MCInstrDesc.h:163
llvm::PPCTargetMachine
Common code between 32-bit and 64-bit PowerPC targets.
Definition: PPCTargetMachine.h:26
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:357
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:759
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::PPCRegisterBankInfo
Definition: PPCRegisterBankInfo.h:63
MachineFunction.h
llvm::mca::selectImpl
static uint64_t selectImpl(uint64_t CandidateMask, uint64_t &NextInSequenceMask)
Definition: ResourceManager.cpp:26
Debug.h
PPCTargetMachine.h
llvm::LLT
Definition: LowLevelTypeImpl.h:39