LLVM 23.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"
16#include "PPCRegisterBankInfo.h"
17#include "PPCSubtarget.h"
18#include "PPCTargetMachine.h"
25#include "llvm/IR/IntrinsicsPowerPC.h"
26#include "llvm/Support/Debug.h"
27
28#define DEBUG_TYPE "ppc-gisel"
29
30using namespace llvm;
31
32namespace {
33
34#define GET_GLOBALISEL_PREDICATE_BITSET
35#include "PPCGenGlobalISel.inc"
36#undef GET_GLOBALISEL_PREDICATE_BITSET
37
38class PPCInstructionSelector : public InstructionSelector {
39public:
40 PPCInstructionSelector(const PPCTargetMachine &TM, const PPCSubtarget &STI,
41 const PPCRegisterBankInfo &RBI);
42
43 bool select(MachineInstr &I) override;
44 static const char *getName() { return DEBUG_TYPE; }
45
46private:
47 /// tblgen generated 'select' implementation that is used as the initial
48 /// selector for the patterns that do not require complex C++.
49 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const;
50
51 bool selectFPToInt(MachineInstr &I, MachineBasicBlock &MBB,
53 bool selectIntToFP(MachineInstr &I, MachineBasicBlock &MBB,
55
56 bool selectZExt(MachineInstr &I, MachineBasicBlock &MBB,
58 bool selectConstantPool(MachineInstr &I, MachineBasicBlock &MBB,
60
61 std::optional<bool> selectI64ImmDirect(MachineInstr &I,
64 uint64_t Imm) const;
67
68 const PPCTargetMachine &TM;
69 const PPCSubtarget &STI;
70 const PPCInstrInfo &TII;
71 const PPCRegisterInfo &TRI;
72 const PPCRegisterBankInfo &RBI;
73
74#define GET_GLOBALISEL_PREDICATES_DECL
75#include "PPCGenGlobalISel.inc"
76#undef GET_GLOBALISEL_PREDICATES_DECL
77
78#define GET_GLOBALISEL_TEMPORARIES_DECL
79#include "PPCGenGlobalISel.inc"
80#undef GET_GLOBALISEL_TEMPORARIES_DECL
81};
82
83} // end anonymous namespace
84
85#define GET_GLOBALISEL_IMPL
86#include "PPCGenGlobalISel.inc"
87#undef GET_GLOBALISEL_IMPL
88
89PPCInstructionSelector::PPCInstructionSelector(const PPCTargetMachine &TM,
90 const PPCSubtarget &STI,
91 const PPCRegisterBankInfo &RBI)
92 : TM(TM), STI(STI), TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()),
93 RBI(RBI),
95#include "PPCGenGlobalISel.inc"
98#include "PPCGenGlobalISel.inc"
100{
101}
102
103static const TargetRegisterClass *getRegClass(LLT Ty, const RegisterBank *RB) {
104 if (RB->getID() == PPC::GPRRegBankID) {
105 if (Ty.getSizeInBits() == 64)
106 return &PPC::G8RCRegClass;
107 if (Ty.getSizeInBits() <= 32)
108 return &PPC::GPRCRegClass;
109 }
110 if (RB->getID() == PPC::FPRRegBankID) {
111 if (Ty.getSizeInBits() == 32)
112 return &PPC::F4RCRegClass;
113 if (Ty.getSizeInBits() == 64)
114 return &PPC::F8RCRegClass;
115 }
116 if (RB->getID() == PPC::VECRegBankID) {
117 if (Ty.getSizeInBits() == 128)
118 return &PPC::VSRCRegClass;
119 }
120 if (RB->getID() == PPC::CRRegBankID) {
121 if (Ty.getSizeInBits() == 1)
122 return &PPC::CRBITRCRegClass;
123 if (Ty.getSizeInBits() == 4)
124 return &PPC::CRRCRegClass;
125 }
126
127 llvm_unreachable("Unknown RegBank!");
128}
129
132 const RegisterBankInfo &RBI) {
133 Register DstReg = I.getOperand(0).getReg();
134
135 if (DstReg.isPhysical())
136 return true;
137
138 const RegisterBank *DstRegBank = RBI.getRegBank(DstReg, MRI, TRI);
139 const TargetRegisterClass *DstRC =
140 getRegClass(MRI.getType(DstReg), DstRegBank);
141
142 // No need to constrain SrcReg. It will get constrained when we hit another of
143 // its use or its defs.
144 // Copies do not have constraints.
145 if (!RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) {
146 LLVM_DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode())
147 << " operand\n");
148 return false;
149 }
150
151 return true;
152}
153
154static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID,
155 unsigned OpSize) {
156 const bool IsStore = GenericOpc == TargetOpcode::G_STORE;
157 switch (RegBankID) {
158 case PPC::GPRRegBankID:
159 switch (OpSize) {
160 case 32:
161 return IsStore ? PPC::STW : PPC::LWZ;
162 case 64:
163 return IsStore ? PPC::STD : PPC::LD;
164 default:
165 llvm_unreachable("Unexpected size!");
166 }
167 break;
168 case PPC::FPRRegBankID:
169 switch (OpSize) {
170 case 32:
171 return IsStore ? PPC::STFS : PPC::LFS;
172 case 64:
173 return IsStore ? PPC::STFD : PPC::LFD;
174 default:
175 llvm_unreachable("Unexpected size!");
176 }
177 break;
178 default:
179 llvm_unreachable("Unexpected register bank!");
180 }
181 return GenericOpc;
182}
183
184bool PPCInstructionSelector::selectIntToFP(MachineInstr &I,
186 MachineRegisterInfo &MRI) const {
187 if (!STI.hasDirectMove() || !STI.isPPC64() || !STI.hasFPCVT())
188 return false;
189
190 const DebugLoc &DbgLoc = I.getDebugLoc();
191 const Register DstReg = I.getOperand(0).getReg();
192 const Register SrcReg = I.getOperand(1).getReg();
193
194 Register MoveReg = MRI.createVirtualRegister(&PPC::VSFRCRegClass);
195
196 // For now, only handle the case for 64 bit integer.
197 BuildMI(MBB, I, DbgLoc, TII.get(PPC::MTVSRD), MoveReg).addReg(SrcReg);
198
199 bool IsSingle = MRI.getType(DstReg).getSizeInBits() == 32;
200 bool IsSigned = I.getOpcode() == TargetOpcode::G_SITOFP;
201 unsigned ConvOp = IsSingle ? (IsSigned ? PPC::XSCVSXDSP : PPC::XSCVUXDSP)
202 : (IsSigned ? PPC::XSCVSXDDP : PPC::XSCVUXDDP);
203
204 MachineInstr *MI =
205 BuildMI(MBB, I, DbgLoc, TII.get(ConvOp), DstReg).addReg(MoveReg);
206
207 I.eraseFromParent();
209 return true;
210}
211
212bool PPCInstructionSelector::selectFPToInt(MachineInstr &I,
213 MachineBasicBlock &MBB,
214 MachineRegisterInfo &MRI) const {
215 if (!STI.hasDirectMove() || !STI.isPPC64() || !STI.hasFPCVT())
216 return false;
217
218 const DebugLoc &DbgLoc = I.getDebugLoc();
219 const Register DstReg = I.getOperand(0).getReg();
220 const Register SrcReg = I.getOperand(1).getReg();
221
222 Register CopyReg = MRI.createVirtualRegister(&PPC::VSFRCRegClass);
223 BuildMI(MBB, I, DbgLoc, TII.get(TargetOpcode::COPY), CopyReg).addReg(SrcReg);
224
225 Register ConvReg = MRI.createVirtualRegister(&PPC::VSFRCRegClass);
226
227 bool IsSigned = I.getOpcode() == TargetOpcode::G_FPTOSI;
228
229 // single-precision is stored as double-precision on PPC in registers, so
230 // always use double-precision convertions.
231 unsigned ConvOp = IsSigned ? PPC::XSCVDPSXDS : PPC::XSCVDPUXDS;
232
233 BuildMI(MBB, I, DbgLoc, TII.get(ConvOp), ConvReg).addReg(CopyReg);
234
235 MachineInstr *MI =
236 BuildMI(MBB, I, DbgLoc, TII.get(PPC::MFVSRD), DstReg).addReg(ConvReg);
237
238 I.eraseFromParent();
240 return true;
241}
242
243bool PPCInstructionSelector::selectZExt(MachineInstr &I, MachineBasicBlock &MBB,
244 MachineRegisterInfo &MRI) const {
245 const Register DstReg = I.getOperand(0).getReg();
246 const LLT DstTy = MRI.getType(DstReg);
247 const RegisterBank *DstRegBank = RBI.getRegBank(DstReg, MRI, TRI);
248
249 const Register SrcReg = I.getOperand(1).getReg();
250
251 assert(DstTy.getSizeInBits() == 64 && "Unexpected dest size!");
252 assert(MRI.getType(SrcReg).getSizeInBits() == 32 && "Unexpected src size!");
253
254 Register ImpDefReg =
255 MRI.createVirtualRegister(getRegClass(DstTy, DstRegBank));
256 BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::IMPLICIT_DEF),
257 ImpDefReg);
258
259 Register NewDefReg =
260 MRI.createVirtualRegister(getRegClass(DstTy, DstRegBank));
261 BuildMI(MBB, I, I.getDebugLoc(), TII.get(TargetOpcode::INSERT_SUBREG),
262 NewDefReg)
263 .addReg(ImpDefReg)
264 .addReg(SrcReg)
265 .addImm(PPC::sub_32);
266
267 MachineInstr *MI =
268 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), DstReg)
269 .addReg(NewDefReg)
270 .addImm(0)
271 .addImm(32);
272
273 I.eraseFromParent();
275 return true;
276}
277
278// For any 32 < Num < 64, check if the Imm contains at least Num consecutive
279// zeros and return the number of bits by the left of these consecutive zeros.
283 if ((HiTZ + LoLZ) >= Num)
284 return (32 + HiTZ);
285 return 0;
286}
287
288// Direct materialization of 64-bit constants by enumerated patterns.
289// Similar to PPCISelDAGToDAG::selectI64ImmDirect().
290std::optional<bool> PPCInstructionSelector::selectI64ImmDirect(MachineInstr &I,
291 MachineBasicBlock &MBB,
292 MachineRegisterInfo &MRI,
294 uint64_t Imm) const {
295 unsigned TZ = llvm::countr_zero<uint64_t>(Imm);
296 unsigned LZ = llvm::countl_zero<uint64_t>(Imm);
297 unsigned TO = llvm::countr_one<uint64_t>(Imm);
298 unsigned LO = llvm::countl_one<uint64_t>(Imm);
299 uint32_t Hi32 = Hi_32(Imm);
300 uint32_t Lo32 = Lo_32(Imm);
301 uint32_t Shift = 0;
302
303 // Following patterns use 1 instructions to materialize the Imm.
304
305 // 1-1) Patterns : {zeros}{15-bit valve}
306 // {ones}{15-bit valve}
307 if (isInt<16>(Imm)) {
308 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), Reg)
309 .addImm(Imm)
310 .constrainAllUses(TII, TRI, RBI);
311 return true;
312 }
313 // 1-2) Patterns : {zeros}{15-bit valve}{16 zeros}
314 // {ones}{15-bit valve}{16 zeros}
315 if (TZ > 15 && (LZ > 32 || LO > 32)) {
316 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), Reg)
317 .addImm((Imm >> 16) & 0xffff)
318 .constrainAllUses(TII, TRI, RBI);
319 return true;
320 }
321
322 // Following patterns use 2 instructions to materialize the Imm.
323
324 assert(LZ < 64 && "Unexpected leading zeros here.");
325 // Count of ones follwing the leading zeros.
326 unsigned FO = llvm::countl_one<uint64_t>(Imm << LZ);
327 // 2-1) Patterns : {zeros}{31-bit value}
328 // {ones}{31-bit value}
329 if (isInt<32>(Imm)) {
330 uint64_t ImmHi16 = (Imm >> 16) & 0xffff;
331 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
332 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
333 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
334 .addImm((Imm >> 16) & 0xffff)
335 .constrainAllUses(TII, TRI, RBI);
336 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Reg)
337 .addReg(TmpReg, RegState::Kill)
338 .addImm(Imm & 0xffff)
339 .constrainAllUses(TII, TRI, RBI);
340 return true;
341 }
342 // 2-2) Patterns : {zeros}{ones}{15-bit value}{zeros}
343 // {zeros}{15-bit value}{zeros}
344 // {zeros}{ones}{15-bit value}
345 // {ones}{15-bit value}{zeros}
346 // We can take advantage of LI's sign-extension semantics to generate leading
347 // ones, and then use RLDIC to mask off the ones in both sides after rotation.
348 if ((LZ + FO + TZ) > 48) {
349 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
350 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
351 .addImm((Imm >> TZ) & 0xffff)
352 .constrainAllUses(TII, TRI, RBI);
353 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIC), Reg)
354 .addReg(TmpReg, RegState::Kill)
355 .addImm(TZ)
356 .addImm(LZ)
357 .constrainAllUses(TII, TRI, RBI);
358 return true;
359 }
360 // 2-3) Pattern : {zeros}{15-bit value}{ones}
361 // Shift right the Imm by (48 - LZ) bits to construct a negtive 16 bits value,
362 // therefore we can take advantage of LI's sign-extension semantics, and then
363 // mask them off after rotation.
364 //
365 // +--LZ--||-15-bit-||--TO--+ +-------------|--16-bit--+
366 // |00000001bbbbbbbbb1111111| -> |00000000000001bbbbbbbbb1|
367 // +------------------------+ +------------------------+
368 // 63 0 63 0
369 // Imm (Imm >> (48 - LZ) & 0xffff)
370 // +----sext-----|--16-bit--+ +clear-|-----------------+
371 // |11111111111111bbbbbbbbb1| -> |00000001bbbbbbbbb1111111|
372 // +------------------------+ +------------------------+
373 // 63 0 63 0
374 // LI8: sext many leading zeros RLDICL: rotate left (48 - LZ), clear left LZ
375 if ((LZ + TO) > 48) {
376 // Since the immediates with (LZ > 32) have been handled by previous
377 // patterns, here we have (LZ <= 32) to make sure we will not shift right
378 // the Imm by a negative value.
379 assert(LZ <= 32 && "Unexpected shift value.");
380 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
381 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
382 .addImm(Imm >> (48 - LZ) & 0xffff)
383 .constrainAllUses(TII, TRI, RBI);
384 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
385 .addReg(TmpReg, RegState::Kill)
386 .addImm(48 - LZ)
387 .addImm(LZ)
388 .constrainAllUses(TII, TRI, RBI);
389 return true;
390 }
391 // 2-4) Patterns : {zeros}{ones}{15-bit value}{ones}
392 // {ones}{15-bit value}{ones}
393 // We can take advantage of LI's sign-extension semantics to generate leading
394 // ones, and then use RLDICL to mask off the ones in left sides (if required)
395 // after rotation.
396 //
397 // +-LZ-FO||-15-bit-||--TO--+ +-------------|--16-bit--+
398 // |00011110bbbbbbbbb1111111| -> |000000000011110bbbbbbbbb|
399 // +------------------------+ +------------------------+
400 // 63 0 63 0
401 // Imm (Imm >> TO) & 0xffff
402 // +----sext-----|--16-bit--+ +LZ|---------------------+
403 // |111111111111110bbbbbbbbb| -> |00011110bbbbbbbbb1111111|
404 // +------------------------+ +------------------------+
405 // 63 0 63 0
406 // LI8: sext many leading zeros RLDICL: rotate left TO, clear left LZ
407 if ((LZ + FO + TO) > 48) {
408 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
409 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
410 .addImm((Imm >> TO) & 0xffff)
411 .constrainAllUses(TII, TRI, RBI);
412 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
413 .addReg(TmpReg, RegState::Kill)
414 .addImm(TO)
415 .addImm(LZ)
416 .constrainAllUses(TII, TRI, RBI);
417 return true;
418 }
419 // 2-5) Pattern : {32 zeros}{****}{0}{15-bit value}
420 // If Hi32 is zero and the Lo16(in Lo32) can be presented as a positive 16 bit
421 // value, we can use LI for Lo16 without generating leading ones then add the
422 // Hi16(in Lo32).
423 if (LZ == 32 && ((Lo32 & 0x8000) == 0)) {
424 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
425 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
426 .addImm(Lo32 & 0xffff)
427 .constrainAllUses(TII, TRI, RBI);
428 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORIS8), Reg)
429 .addReg(TmpReg, RegState::Kill)
430 .addImm(Lo32 >> 16)
431 .constrainAllUses(TII, TRI, RBI);
432 return true;
433 }
434 // 2-6) Patterns : {******}{49 zeros}{******}
435 // {******}{49 ones}{******}
436 // If the Imm contains 49 consecutive zeros/ones, it means that a total of 15
437 // bits remain on both sides. Rotate right the Imm to construct an int<16>
438 // value, use LI for int<16> value and then use RLDICL without mask to rotate
439 // it back.
440 //
441 // 1) findContiguousZerosAtLeast(Imm, 49)
442 // +------|--zeros-|------+ +---ones--||---15 bit--+
443 // |bbbbbb0000000000aaaaaa| -> |0000000000aaaaaabbbbbb|
444 // +----------------------+ +----------------------+
445 // 63 0 63 0
446 //
447 // 2) findContiguousZerosAtLeast(~Imm, 49)
448 // +------|--ones--|------+ +---ones--||---15 bit--+
449 // |bbbbbb1111111111aaaaaa| -> |1111111111aaaaaabbbbbb|
450 // +----------------------+ +----------------------+
451 // 63 0 63 0
452 if ((Shift = findContiguousZerosAtLeast(Imm, 49)) ||
453 (Shift = findContiguousZerosAtLeast(~Imm, 49))) {
454 uint64_t RotImm = APInt(64, Imm).rotr(Shift).getZExtValue();
455 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
456 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LI8), TmpReg)
457 .addImm(RotImm & 0xffff)
458 .constrainAllUses(TII, TRI, RBI);
459 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
460 .addReg(TmpReg, RegState::Kill)
461 .addImm(Shift)
462 .addImm(0)
463 .constrainAllUses(TII, TRI, RBI);
464 return true;
465 }
466
467 // Following patterns use 3 instructions to materialize the Imm.
468
469 // 3-1) Patterns : {zeros}{ones}{31-bit value}{zeros}
470 // {zeros}{31-bit value}{zeros}
471 // {zeros}{ones}{31-bit value}
472 // {ones}{31-bit value}{zeros}
473 // We can take advantage of LIS's sign-extension semantics to generate leading
474 // ones, add the remaining bits with ORI, and then use RLDIC to mask off the
475 // ones in both sides after rotation.
476 if ((LZ + FO + TZ) > 32) {
477 uint64_t ImmHi16 = (Imm >> (TZ + 16)) & 0xffff;
478 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
479 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
480 Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
481 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
482 .addImm(ImmHi16)
483 .constrainAllUses(TII, TRI, RBI);
484 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
485 .addReg(TmpReg, RegState::Kill)
486 .addImm((Imm >> TZ) & 0xffff)
487 .constrainAllUses(TII, TRI, RBI);
488 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIC), Reg)
489 .addReg(Tmp2Reg, RegState::Kill)
490 .addImm(TZ)
491 .addImm(LZ)
492 .constrainAllUses(TII, TRI, RBI);
493 return true;
494 }
495 // 3-2) Pattern : {zeros}{31-bit value}{ones}
496 // Shift right the Imm by (32 - LZ) bits to construct a negative 32 bits
497 // value, therefore we can take advantage of LIS's sign-extension semantics,
498 // add the remaining bits with ORI, and then mask them off after rotation.
499 // This is similar to Pattern 2-3, please refer to the diagram there.
500 if ((LZ + TO) > 32) {
501 // Since the immediates with (LZ > 32) have been handled by previous
502 // patterns, here we have (LZ <= 32) to make sure we will not shift right
503 // the Imm by a negative value.
504 assert(LZ <= 32 && "Unexpected shift value.");
505 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
506 Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
507 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), TmpReg)
508 .addImm((Imm >> (48 - LZ)) & 0xffff)
509 .constrainAllUses(TII, TRI, RBI);
510 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
511 .addReg(TmpReg, RegState::Kill)
512 .addImm((Imm >> (32 - LZ)) & 0xffff)
513 .constrainAllUses(TII, TRI, RBI);
514 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
515 .addReg(Tmp2Reg, RegState::Kill)
516 .addImm(32 - LZ)
517 .addImm(LZ)
518 .constrainAllUses(TII, TRI, RBI);
519 return true;
520 }
521 // 3-3) Patterns : {zeros}{ones}{31-bit value}{ones}
522 // {ones}{31-bit value}{ones}
523 // We can take advantage of LIS's sign-extension semantics to generate leading
524 // ones, add the remaining bits with ORI, and then use RLDICL to mask off the
525 // ones in left sides (if required) after rotation.
526 // This is similar to Pattern 2-4, please refer to the diagram there.
527 if ((LZ + FO + TO) > 32) {
528 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
529 Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
530 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::LIS8), TmpReg)
531 .addImm((Imm >> (TO + 16)) & 0xffff)
532 .constrainAllUses(TII, TRI, RBI);
533 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
534 .addReg(TmpReg, RegState::Kill)
535 .addImm((Imm >> TO) & 0xffff)
536 .constrainAllUses(TII, TRI, RBI);
537 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
538 .addReg(Tmp2Reg, RegState::Kill)
539 .addImm(TO)
540 .addImm(LZ)
541 .constrainAllUses(TII, TRI, RBI);
542 return true;
543 }
544 // 3-4) Patterns : High word == Low word
545 if (Hi32 == Lo32) {
546 // Handle the first 32 bits.
547 uint64_t ImmHi16 = (Lo32 >> 16) & 0xffff;
548 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
549 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
550 Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
551 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
552 .addImm(ImmHi16)
553 .constrainAllUses(TII, TRI, RBI);
554 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
555 .addReg(TmpReg, RegState::Kill)
556 .addImm(Lo32 & 0xffff)
557 .constrainAllUses(TII, TRI, RBI);
558 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDIMI), Reg)
559 .addReg(Tmp2Reg)
560 .addReg(Tmp2Reg, RegState::Kill)
561 .addImm(32)
562 .addImm(0)
563 .constrainAllUses(TII, TRI, RBI);
564 return true;
565 }
566 // 3-5) Patterns : {******}{33 zeros}{******}
567 // {******}{33 ones}{******}
568 // If the Imm contains 33 consecutive zeros/ones, it means that a total of 31
569 // bits remain on both sides. Rotate right the Imm to construct an int<32>
570 // value, use LIS + ORI for int<32> value and then use RLDICL without mask to
571 // rotate it back.
572 // This is similar to Pattern 2-6, please refer to the diagram there.
573 if ((Shift = findContiguousZerosAtLeast(Imm, 33)) ||
574 (Shift = findContiguousZerosAtLeast(~Imm, 33))) {
575 uint64_t RotImm = APInt(64, Imm).rotr(Shift).getZExtValue();
576 uint64_t ImmHi16 = (RotImm >> 16) & 0xffff;
577 unsigned Opcode = ImmHi16 ? PPC::LIS8 : PPC::LI8;
578 Register TmpReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
579 Register Tmp2Reg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
580 BuildMI(MBB, I, I.getDebugLoc(), TII.get(Opcode), TmpReg)
581 .addImm(ImmHi16)
582 .constrainAllUses(TII, TRI, RBI);
583 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), Tmp2Reg)
584 .addReg(TmpReg, RegState::Kill)
585 .addImm(RotImm & 0xffff)
586 .constrainAllUses(TII, TRI, RBI);
587 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::RLDICL), Reg)
588 .addReg(Tmp2Reg, RegState::Kill)
589 .addImm(Shift)
590 .addImm(0)
591 .constrainAllUses(TII, TRI, RBI);
592 return true;
593 }
594
595 // If we end up here then no instructions were inserted.
596 return std::nullopt;
597}
598
599// Derived from PPCISelDAGToDAG::selectI64Imm().
600// TODO: Add support for prefixed instructions.
601bool PPCInstructionSelector::selectI64Imm(MachineInstr &I,
602 MachineBasicBlock &MBB,
603 MachineRegisterInfo &MRI) const {
604 assert(I.getOpcode() == TargetOpcode::G_CONSTANT && "Unexpected G code");
605
606 Register DstReg = I.getOperand(0).getReg();
607 int64_t Imm = I.getOperand(1).getCImm()->getValue().getZExtValue();
608 // No more than 3 instructions are used if we can select the i64 immediate
609 // directly.
610 if (std::optional<bool> Res = selectI64ImmDirect(I, MBB, MRI, DstReg, Imm)) {
611 I.eraseFromParent();
612 return *Res;
613 }
614
615 // Calculate the last bits as required.
616 uint32_t Hi16 = (Lo_32(Imm) >> 16) & 0xffff;
617 uint32_t Lo16 = Lo_32(Imm) & 0xffff;
618
619 Register Reg =
620 (Hi16 || Lo16) ? MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
621
622 // Handle the upper 32 bit value.
623 std::optional<bool> Res =
624 selectI64ImmDirect(I, MBB, MRI, Reg, Imm & 0xffffffff00000000);
625 if (!Res || !*Res)
626 return false;
627
628 // Add in the last bits as required.
629 if (Hi16) {
630 Register TmpReg =
631 Lo16 ? MRI.createVirtualRegister(&PPC::G8RCRegClass) : DstReg;
632 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORIS8), TmpReg)
633 .addReg(Reg, RegState::Kill)
634 .addImm(Hi16)
635 .constrainAllUses(TII, TRI, RBI);
636 Reg = TmpReg;
637 }
638 if (Lo16) {
639 BuildMI(MBB, I, I.getDebugLoc(), TII.get(PPC::ORI8), DstReg)
640 .addReg(Reg, RegState::Kill)
641 .addImm(Lo16)
642 .constrainAllUses(TII, TRI, RBI);
643 }
644 I.eraseFromParent();
645 return true;
646}
647
648bool PPCInstructionSelector::selectConstantPool(
649 MachineInstr &I, MachineBasicBlock &MBB, MachineRegisterInfo &MRI) const {
650 const DebugLoc &DbgLoc = I.getDebugLoc();
651 MachineFunction *MF = MBB.getParent();
652
653 // TODO: handle 32-bit.
654 // TODO: Enabling floating point constant pool selection on AIX requires
655 // global isel on big endian target enabled first.
656 // See CallLowering::enableBigEndian().
657 if (!STI.isPPC64() || !STI.isLittleEndian())
658 return false;
659
660 MF->getInfo<PPCFunctionInfo>()->setUsesTOCBasePtr();
661
662 const Register DstReg = I.getOperand(0).getReg();
663 unsigned CPI = I.getOperand(1).getIndex();
664
665 // Address stored in the TOC entry. This is related to code model and the ABI
666 // we are currently using. For now we only handle 64-bit Linux LE. PowerPC
667 // only supports small, medium and large code model.
668 const CodeModel::Model CModel = TM.getCodeModel();
669 assert(!(CModel == CodeModel::Tiny || CModel == CodeModel::Kernel) &&
670 "PowerPC doesn't support tiny or kernel code models.");
671
672 const MCRegister TOCReg = STI.getTOCPointerRegister();
673 MachineMemOperand *MMO = MF->getMachineMemOperand(
675 MRI.getType(DstReg), MF->getDataLayout().getPointerABIAlignment(0));
676
677 MachineInstr *MI = nullptr;
678 // For now we only handle 64-bit Linux.
679 if (CModel == CodeModel::Small) {
680 // For small code model, generate LDtocCPT(CPI, X2).
681 MI = BuildMI(MBB, I, DbgLoc, TII.get(PPC::LDtocCPT), DstReg)
683 .addReg(TOCReg)
684 .addMemOperand(MMO);
685 } else {
686 Register HaAddrReg = MRI.createVirtualRegister(&PPC::G8RCRegClass);
687 BuildMI(MBB, I, DbgLoc, TII.get(PPC::ADDIStocHA8), HaAddrReg)
688 .addReg(TOCReg)
690
691 if (CModel == CodeModel::Large)
692 // For large code model, generate LDtocL(CPI, ADDIStocHA8(X2, CPI))
693 MI = BuildMI(MBB, I, DbgLoc, TII.get(PPC::LDtocL), DstReg)
695 .addReg(HaAddrReg)
696 .addMemOperand(MMO);
697 else
698 // For medium code model, generate ADDItocL8(CPI, ADDIStocHA8(X2, CPI))
699 MI = BuildMI(MBB, I, DbgLoc, TII.get(PPC::ADDItocL8), DstReg)
700 .addReg(HaAddrReg)
702 }
703
704 I.eraseFromParent();
706 return true;
707}
708
709bool PPCInstructionSelector::select(MachineInstr &I) {
710 auto &MBB = *I.getParent();
711 auto &MF = *MBB.getParent();
712 auto &MRI = MF.getRegInfo();
713
714 if (!isPreISelGenericOpcode(I.getOpcode())) {
715 if (I.isCopy())
716 return selectCopy(I, TII, MRI, TRI, RBI);
717
718 return true;
719 }
720
721 if (selectImpl(I, *CoverageInfo))
722 return true;
723
724 unsigned Opcode = I.getOpcode();
725
726 switch (Opcode) {
727 default:
728 return false;
729 case TargetOpcode::G_LOAD:
730 case TargetOpcode::G_STORE: {
731 GLoadStore &LdSt = cast<GLoadStore>(I);
732 LLT PtrTy = MRI.getType(LdSt.getPointerReg());
733
734 if (PtrTy != LLT::pointer(0, 64)) {
735 LLVM_DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy
736 << ", expected: " << LLT::pointer(0, 64) << '\n');
737 return false;
738 }
739
740 auto SelectLoadStoreAddressingMode = [&]() -> MachineInstr * {
741 const unsigned NewOpc = selectLoadStoreOp(
742 I.getOpcode(), RBI.getRegBank(LdSt.getReg(0), MRI, TRI)->getID(),
743 LdSt.getMemSizeInBits().getValue());
744
745 if (NewOpc == I.getOpcode())
746 return nullptr;
747
748 // For now, simply use DForm with load/store addr as base and 0 as imm.
749 // FIXME: optimize load/store with some specific address patterns.
750 I.setDesc(TII.get(NewOpc));
751 Register AddrReg = I.getOperand(1).getReg();
752 bool IsKill = I.getOperand(1).isKill();
753 I.getOperand(1).ChangeToImmediate(0);
754 I.addOperand(*I.getParent()->getParent(),
755 MachineOperand::CreateReg(AddrReg, /* isDef */ false,
756 /* isImp */ false, IsKill));
757 return &I;
758 };
759
760 MachineInstr *LoadStore = SelectLoadStoreAddressingMode();
761 if (!LoadStore)
762 return false;
763
764 constrainSelectedInstRegOperands(*LoadStore, TII, TRI, RBI);
765 return true;
766 }
767 case TargetOpcode::G_SITOFP:
768 case TargetOpcode::G_UITOFP:
769 return selectIntToFP(I, MBB, MRI);
770 case TargetOpcode::G_FPTOSI:
771 case TargetOpcode::G_FPTOUI:
772 return selectFPToInt(I, MBB, MRI);
773 // G_SEXT will be selected in tb-gen pattern.
774 case TargetOpcode::G_ZEXT:
775 return selectZExt(I, MBB, MRI);
776 case TargetOpcode::G_CONSTANT:
777 return selectI64Imm(I, MBB, MRI);
778 case TargetOpcode::G_CONSTANT_POOL:
779 return selectConstantPool(I, MBB, MRI);
780 }
781 return false;
782}
783
784namespace llvm {
785InstructionSelector *
787 const PPCSubtarget &Subtarget,
788 const PPCRegisterBankInfo &RBI) {
789 return new PPCInstructionSelector(TM, Subtarget, RBI);
790}
791} // end namespace llvm
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
#define DEBUG_TYPE
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
This file declares the MachineIRBuilder class.
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
static SDNode * selectI64ImmDirect(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned &InstCnt)
static SDNode * selectI64Imm(SelectionDAG *CurDAG, const SDLoc &dl, uint64_t Imm, unsigned *InstCnt=nullptr)
static void setUsesTOCBasePtr(MachineFunction &MF)
static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
static uint32_t findContiguousZerosAtLeast(uint64_t Imm, unsigned Num)
static unsigned selectLoadStoreOp(unsigned GenericOpc, unsigned RegBankID, unsigned OpSize)
This file declares the targeting of the RegisterBankInfo class for PowerPC.
static StringRef getName(Value *V)
#define LLVM_DEBUG(...)
Definition Debug.h:114
LLVM_ABI Align getPointerABIAlignment(unsigned AS) const
Layout pointer alignment.
Register getPointerReg() const
Get the source register of the pointer value.
LocationSize getMemSizeInBits() const
Returns the size in bits of the memory access.
Register getReg(unsigned Idx) const
Access the Idx'th operand as a register and return it.
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
TypeSize getValue() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, 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.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
void constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
Representation of each machine instruction.
@ MOLoad
The memory access reads data.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
bool isLittleEndian() const
MCRegister getTOCPointerRegister() const
Common code between 32-bit and 64-bit PowerPC targets.
Holds all the information related to register banks.
static const TargetRegisterClass * constrainGenericRegister(Register Reg, const TargetRegisterClass &RC, MachineRegisterInfo &MRI)
Constrain the (possibly generic) virtual register Reg to RC.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
TargetInstrInfo - Interface to description of machine instruction set.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:165
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
Definition bit.h:293
LLVM_ABI void 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:155
bool isPreISelGenericOpcode(unsigned Opcode)
Check whether the given Opcode is a generic opcode that is not supposed to appear after ISel.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition bit.h:202
int countl_zero(T Val)
Count number of 0's from the most significant bit to the least stopping at the first 1.
Definition bit.h:236
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
Definition MathExtras.h:150
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
int countl_one(T Value)
Count the number of ones from the most significant bit to the first zero bit.
Definition bit.h:280
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
Definition MathExtras.h:155
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
InstructionSelector * createPPCInstructionSelector(const PPCTargetMachine &TM, const PPCSubtarget &Subtarget, const PPCRegisterBankInfo &RBI)
static LLVM_ABI MachinePointerInfo getGOT(MachineFunction &MF)
Return a MachinePointerInfo record that refers to a GOT entry.