xref: /llvm-project/llvm/lib/Target/RISCV/RISCVExpandPseudoInsts.cpp (revision d4af658323c6e2492ca1224930488c390a08c720)
1 //===-- RISCVExpandPseudoInsts.cpp - Expand pseudo instructions -----------===//
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 //
9 // This file contains a pass that expands pseudo instructions into target
10 // instructions. This pass should be run after register allocation but before
11 // the post-regalloc scheduling pass.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "RISCV.h"
16 #include "RISCVInstrInfo.h"
17 #include "RISCVTargetMachine.h"
18 
19 #include "llvm/CodeGen/LivePhysRegs.h"
20 #include "llvm/CodeGen/MachineFunctionPass.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/MC/MCContext.h"
23 
24 using namespace llvm;
25 
26 #define RISCV_EXPAND_PSEUDO_NAME "RISC-V pseudo instruction expansion pass"
27 #define RISCV_PRERA_EXPAND_PSEUDO_NAME "RISC-V Pre-RA pseudo instruction expansion pass"
28 
29 namespace {
30 
31 class RISCVExpandPseudo : public MachineFunctionPass {
32 public:
33   const RISCVSubtarget *STI;
34   const RISCVInstrInfo *TII;
35   static char ID;
36 
37   RISCVExpandPseudo() : MachineFunctionPass(ID) {}
38 
39   bool runOnMachineFunction(MachineFunction &MF) override;
40 
41   StringRef getPassName() const override { return RISCV_EXPAND_PSEUDO_NAME; }
42 
43 private:
44   bool expandMBB(MachineBasicBlock &MBB);
45   bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
46                 MachineBasicBlock::iterator &NextMBBI);
47   bool expandCCOp(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
48                   MachineBasicBlock::iterator &NextMBBI);
49   bool expandVMSET_VMCLR(MachineBasicBlock &MBB,
50                          MachineBasicBlock::iterator MBBI, unsigned Opcode);
51   bool expandMV_FPR16INX(MachineBasicBlock &MBB,
52                          MachineBasicBlock::iterator MBBI);
53   bool expandMV_FPR32INX(MachineBasicBlock &MBB,
54                          MachineBasicBlock::iterator MBBI);
55   bool expandRV32ZdinxStore(MachineBasicBlock &MBB,
56                             MachineBasicBlock::iterator MBBI);
57   bool expandRV32ZdinxLoad(MachineBasicBlock &MBB,
58                            MachineBasicBlock::iterator MBBI);
59 #ifndef NDEBUG
60   unsigned getInstSizeInBytes(const MachineFunction &MF) const {
61     unsigned Size = 0;
62     for (auto &MBB : MF)
63       for (auto &MI : MBB)
64         Size += TII->getInstSizeInBytes(MI);
65     return Size;
66   }
67 #endif
68 };
69 
70 char RISCVExpandPseudo::ID = 0;
71 
72 bool RISCVExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
73   STI = &MF.getSubtarget<RISCVSubtarget>();
74   TII = STI->getInstrInfo();
75 
76 #ifndef NDEBUG
77   const unsigned OldSize = getInstSizeInBytes(MF);
78 #endif
79 
80   bool Modified = false;
81   for (auto &MBB : MF)
82     Modified |= expandMBB(MBB);
83 
84 #ifndef NDEBUG
85   const unsigned NewSize = getInstSizeInBytes(MF);
86   assert(OldSize >= NewSize);
87 #endif
88   return Modified;
89 }
90 
91 bool RISCVExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
92   bool Modified = false;
93 
94   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
95   while (MBBI != E) {
96     MachineBasicBlock::iterator NMBBI = std::next(MBBI);
97     Modified |= expandMI(MBB, MBBI, NMBBI);
98     MBBI = NMBBI;
99   }
100 
101   return Modified;
102 }
103 
104 bool RISCVExpandPseudo::expandMI(MachineBasicBlock &MBB,
105                                  MachineBasicBlock::iterator MBBI,
106                                  MachineBasicBlock::iterator &NextMBBI) {
107   // RISCVInstrInfo::getInstSizeInBytes expects that the total size of the
108   // expanded instructions for each pseudo is correct in the Size field of the
109   // tablegen definition for the pseudo.
110   switch (MBBI->getOpcode()) {
111   case RISCV::PseudoMV_FPR16INX:
112     return expandMV_FPR16INX(MBB, MBBI);
113   case RISCV::PseudoMV_FPR32INX:
114     return expandMV_FPR32INX(MBB, MBBI);
115   case RISCV::PseudoRV32ZdinxSD:
116     return expandRV32ZdinxStore(MBB, MBBI);
117   case RISCV::PseudoRV32ZdinxLD:
118     return expandRV32ZdinxLoad(MBB, MBBI);
119   case RISCV::PseudoCCMOVGPRNoX0:
120   case RISCV::PseudoCCMOVGPR:
121   case RISCV::PseudoCCADD:
122   case RISCV::PseudoCCSUB:
123   case RISCV::PseudoCCAND:
124   case RISCV::PseudoCCOR:
125   case RISCV::PseudoCCXOR:
126   case RISCV::PseudoCCADDW:
127   case RISCV::PseudoCCSUBW:
128   case RISCV::PseudoCCSLL:
129   case RISCV::PseudoCCSRL:
130   case RISCV::PseudoCCSRA:
131   case RISCV::PseudoCCADDI:
132   case RISCV::PseudoCCSLLI:
133   case RISCV::PseudoCCSRLI:
134   case RISCV::PseudoCCSRAI:
135   case RISCV::PseudoCCANDI:
136   case RISCV::PseudoCCORI:
137   case RISCV::PseudoCCXORI:
138   case RISCV::PseudoCCSLLW:
139   case RISCV::PseudoCCSRLW:
140   case RISCV::PseudoCCSRAW:
141   case RISCV::PseudoCCADDIW:
142   case RISCV::PseudoCCSLLIW:
143   case RISCV::PseudoCCSRLIW:
144   case RISCV::PseudoCCSRAIW:
145   case RISCV::PseudoCCANDN:
146   case RISCV::PseudoCCORN:
147   case RISCV::PseudoCCXNOR:
148     return expandCCOp(MBB, MBBI, NextMBBI);
149   case RISCV::PseudoVMCLR_M_B1:
150   case RISCV::PseudoVMCLR_M_B2:
151   case RISCV::PseudoVMCLR_M_B4:
152   case RISCV::PseudoVMCLR_M_B8:
153   case RISCV::PseudoVMCLR_M_B16:
154   case RISCV::PseudoVMCLR_M_B32:
155   case RISCV::PseudoVMCLR_M_B64:
156     // vmclr.m vd => vmxor.mm vd, vd, vd
157     return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXOR_MM);
158   case RISCV::PseudoVMSET_M_B1:
159   case RISCV::PseudoVMSET_M_B2:
160   case RISCV::PseudoVMSET_M_B4:
161   case RISCV::PseudoVMSET_M_B8:
162   case RISCV::PseudoVMSET_M_B16:
163   case RISCV::PseudoVMSET_M_B32:
164   case RISCV::PseudoVMSET_M_B64:
165     // vmset.m vd => vmxnor.mm vd, vd, vd
166     return expandVMSET_VMCLR(MBB, MBBI, RISCV::VMXNOR_MM);
167   }
168 
169   return false;
170 }
171 
172 bool RISCVExpandPseudo::expandCCOp(MachineBasicBlock &MBB,
173                                    MachineBasicBlock::iterator MBBI,
174                                    MachineBasicBlock::iterator &NextMBBI) {
175 
176   MachineFunction *MF = MBB.getParent();
177   MachineInstr &MI = *MBBI;
178   DebugLoc DL = MI.getDebugLoc();
179 
180   MachineBasicBlock *TrueBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
181   MachineBasicBlock *MergeBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
182 
183   MF->insert(++MBB.getIterator(), TrueBB);
184   MF->insert(++TrueBB->getIterator(), MergeBB);
185 
186   // We want to copy the "true" value when the condition is true which means
187   // we need to invert the branch condition to jump over TrueBB when the
188   // condition is false.
189   auto CC = static_cast<RISCVCC::CondCode>(MI.getOperand(3).getImm());
190   CC = RISCVCC::getOppositeBranchCondition(CC);
191 
192   // Insert branch instruction.
193   BuildMI(MBB, MBBI, DL, TII->getBrCond(CC))
194       .addReg(MI.getOperand(1).getReg())
195       .addReg(MI.getOperand(2).getReg())
196       .addMBB(MergeBB);
197 
198   Register DestReg = MI.getOperand(0).getReg();
199   assert(MI.getOperand(4).getReg() == DestReg);
200 
201   if (MI.getOpcode() == RISCV::PseudoCCMOVGPR ||
202       MI.getOpcode() == RISCV::PseudoCCMOVGPRNoX0) {
203     // Add MV.
204     BuildMI(TrueBB, DL, TII->get(RISCV::ADDI), DestReg)
205         .add(MI.getOperand(5))
206         .addImm(0);
207   } else {
208     unsigned NewOpc;
209     switch (MI.getOpcode()) {
210     default:
211       llvm_unreachable("Unexpected opcode!");
212     case RISCV::PseudoCCADD:   NewOpc = RISCV::ADD;   break;
213     case RISCV::PseudoCCSUB:   NewOpc = RISCV::SUB;   break;
214     case RISCV::PseudoCCSLL:   NewOpc = RISCV::SLL;   break;
215     case RISCV::PseudoCCSRL:   NewOpc = RISCV::SRL;   break;
216     case RISCV::PseudoCCSRA:   NewOpc = RISCV::SRA;   break;
217     case RISCV::PseudoCCAND:   NewOpc = RISCV::AND;   break;
218     case RISCV::PseudoCCOR:    NewOpc = RISCV::OR;    break;
219     case RISCV::PseudoCCXOR:   NewOpc = RISCV::XOR;   break;
220     case RISCV::PseudoCCADDI:  NewOpc = RISCV::ADDI;  break;
221     case RISCV::PseudoCCSLLI:  NewOpc = RISCV::SLLI;  break;
222     case RISCV::PseudoCCSRLI:  NewOpc = RISCV::SRLI;  break;
223     case RISCV::PseudoCCSRAI:  NewOpc = RISCV::SRAI;  break;
224     case RISCV::PseudoCCANDI:  NewOpc = RISCV::ANDI;  break;
225     case RISCV::PseudoCCORI:   NewOpc = RISCV::ORI;   break;
226     case RISCV::PseudoCCXORI:  NewOpc = RISCV::XORI;  break;
227     case RISCV::PseudoCCADDW:  NewOpc = RISCV::ADDW;  break;
228     case RISCV::PseudoCCSUBW:  NewOpc = RISCV::SUBW;  break;
229     case RISCV::PseudoCCSLLW:  NewOpc = RISCV::SLLW;  break;
230     case RISCV::PseudoCCSRLW:  NewOpc = RISCV::SRLW;  break;
231     case RISCV::PseudoCCSRAW:  NewOpc = RISCV::SRAW;  break;
232     case RISCV::PseudoCCADDIW: NewOpc = RISCV::ADDIW; break;
233     case RISCV::PseudoCCSLLIW: NewOpc = RISCV::SLLIW; break;
234     case RISCV::PseudoCCSRLIW: NewOpc = RISCV::SRLIW; break;
235     case RISCV::PseudoCCSRAIW: NewOpc = RISCV::SRAIW; break;
236     case RISCV::PseudoCCANDN:  NewOpc = RISCV::ANDN;  break;
237     case RISCV::PseudoCCORN:   NewOpc = RISCV::ORN;   break;
238     case RISCV::PseudoCCXNOR:  NewOpc = RISCV::XNOR;  break;
239     }
240     BuildMI(TrueBB, DL, TII->get(NewOpc), DestReg)
241         .add(MI.getOperand(5))
242         .add(MI.getOperand(6));
243   }
244 
245   TrueBB->addSuccessor(MergeBB);
246 
247   MergeBB->splice(MergeBB->end(), &MBB, MI, MBB.end());
248   MergeBB->transferSuccessors(&MBB);
249 
250   MBB.addSuccessor(TrueBB);
251   MBB.addSuccessor(MergeBB);
252 
253   NextMBBI = MBB.end();
254   MI.eraseFromParent();
255 
256   // Make sure live-ins are correctly attached to this new basic block.
257   LivePhysRegs LiveRegs;
258   computeAndAddLiveIns(LiveRegs, *TrueBB);
259   computeAndAddLiveIns(LiveRegs, *MergeBB);
260 
261   return true;
262 }
263 
264 bool RISCVExpandPseudo::expandVMSET_VMCLR(MachineBasicBlock &MBB,
265                                           MachineBasicBlock::iterator MBBI,
266                                           unsigned Opcode) {
267   DebugLoc DL = MBBI->getDebugLoc();
268   Register DstReg = MBBI->getOperand(0).getReg();
269   const MCInstrDesc &Desc = TII->get(Opcode);
270   BuildMI(MBB, MBBI, DL, Desc, DstReg)
271       .addReg(DstReg, RegState::Undef)
272       .addReg(DstReg, RegState::Undef);
273   MBBI->eraseFromParent(); // The pseudo instruction is gone now.
274   return true;
275 }
276 
277 bool RISCVExpandPseudo::expandMV_FPR16INX(MachineBasicBlock &MBB,
278                                           MachineBasicBlock::iterator MBBI) {
279   DebugLoc DL = MBBI->getDebugLoc();
280   const TargetRegisterInfo *TRI = STI->getRegisterInfo();
281   Register DstReg = TRI->getMatchingSuperReg(
282       MBBI->getOperand(0).getReg(), RISCV::sub_16, &RISCV::GPRRegClass);
283   Register SrcReg = TRI->getMatchingSuperReg(
284       MBBI->getOperand(1).getReg(), RISCV::sub_16, &RISCV::GPRRegClass);
285 
286   BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DstReg)
287       .addReg(SrcReg, getKillRegState(MBBI->getOperand(1).isKill()))
288       .addImm(0);
289 
290   MBBI->eraseFromParent(); // The pseudo instruction is gone now.
291   return true;
292 }
293 
294 bool RISCVExpandPseudo::expandMV_FPR32INX(MachineBasicBlock &MBB,
295                                           MachineBasicBlock::iterator MBBI) {
296   DebugLoc DL = MBBI->getDebugLoc();
297   const TargetRegisterInfo *TRI = STI->getRegisterInfo();
298   Register DstReg = TRI->getMatchingSuperReg(
299       MBBI->getOperand(0).getReg(), RISCV::sub_32, &RISCV::GPRRegClass);
300   Register SrcReg = TRI->getMatchingSuperReg(
301       MBBI->getOperand(1).getReg(), RISCV::sub_32, &RISCV::GPRRegClass);
302 
303   BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), DstReg)
304       .addReg(SrcReg, getKillRegState(MBBI->getOperand(1).isKill()))
305       .addImm(0);
306 
307   MBBI->eraseFromParent(); // The pseudo instruction is gone now.
308   return true;
309 }
310 
311 // This function expands the PseudoRV32ZdinxSD for storing a double-precision
312 // floating-point value into memory by generating an equivalent instruction
313 // sequence for RV32.
314 bool RISCVExpandPseudo::expandRV32ZdinxStore(MachineBasicBlock &MBB,
315                                              MachineBasicBlock::iterator MBBI) {
316   DebugLoc DL = MBBI->getDebugLoc();
317   const TargetRegisterInfo *TRI = STI->getRegisterInfo();
318   Register Lo =
319       TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_gpr_even);
320   Register Hi =
321       TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_gpr_odd);
322 
323   auto MIBLo = BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW))
324                    .addReg(Lo, getKillRegState(MBBI->getOperand(0).isKill()))
325                    .addReg(MBBI->getOperand(1).getReg())
326                    .add(MBBI->getOperand(2));
327 
328   MachineInstrBuilder MIBHi;
329   if (MBBI->getOperand(2).isGlobal() || MBBI->getOperand(2).isCPI()) {
330     assert(MBBI->getOperand(2).getOffset() % 8 == 0);
331     MBBI->getOperand(2).setOffset(MBBI->getOperand(2).getOffset() + 4);
332     MIBHi = BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW))
333                 .addReg(Hi, getKillRegState(MBBI->getOperand(0).isKill()))
334                 .add(MBBI->getOperand(1))
335                 .add(MBBI->getOperand(2));
336   } else {
337     assert(isInt<12>(MBBI->getOperand(2).getImm() + 4));
338     MIBHi = BuildMI(MBB, MBBI, DL, TII->get(RISCV::SW))
339                 .addReg(Hi, getKillRegState(MBBI->getOperand(0).isKill()))
340                 .add(MBBI->getOperand(1))
341                 .addImm(MBBI->getOperand(2).getImm() + 4);
342   }
343 
344   MachineFunction *MF = MBB.getParent();
345   SmallVector<MachineMemOperand *> NewLoMMOs;
346   SmallVector<MachineMemOperand *> NewHiMMOs;
347   for (const MachineMemOperand *MMO : MBBI->memoperands()) {
348     NewLoMMOs.push_back(MF->getMachineMemOperand(MMO, 0, 4));
349     NewHiMMOs.push_back(MF->getMachineMemOperand(MMO, 4, 4));
350   }
351   MIBLo.setMemRefs(NewLoMMOs);
352   MIBHi.setMemRefs(NewHiMMOs);
353 
354   MBBI->eraseFromParent();
355   return true;
356 }
357 
358 // This function expands PseudoRV32ZdinxLoad for loading a double-precision
359 // floating-point value from memory into an equivalent instruction sequence for
360 // RV32.
361 bool RISCVExpandPseudo::expandRV32ZdinxLoad(MachineBasicBlock &MBB,
362                                             MachineBasicBlock::iterator MBBI) {
363   DebugLoc DL = MBBI->getDebugLoc();
364   const TargetRegisterInfo *TRI = STI->getRegisterInfo();
365   Register Lo =
366       TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_gpr_even);
367   Register Hi =
368       TRI->getSubReg(MBBI->getOperand(0).getReg(), RISCV::sub_gpr_odd);
369 
370   MachineInstrBuilder MIBLo, MIBHi;
371 
372   // If the register of operand 1 is equal to the Lo register, then swap the
373   // order of loading the Lo and Hi statements.
374   bool IsOp1EqualToLo = Lo == MBBI->getOperand(1).getReg();
375   // Order: Lo, Hi
376   if (!IsOp1EqualToLo) {
377     MIBLo = BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Lo)
378                 .addReg(MBBI->getOperand(1).getReg())
379                 .add(MBBI->getOperand(2));
380   }
381 
382   if (MBBI->getOperand(2).isGlobal() || MBBI->getOperand(2).isCPI()) {
383     auto Offset = MBBI->getOperand(2).getOffset();
384     assert(Offset % 8 == 0);
385     MBBI->getOperand(2).setOffset(Offset + 4);
386     MIBHi = BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Hi)
387                 .addReg(MBBI->getOperand(1).getReg())
388                 .add(MBBI->getOperand(2));
389     MBBI->getOperand(2).setOffset(Offset);
390   } else {
391     assert(isInt<12>(MBBI->getOperand(2).getImm() + 4));
392     MIBHi = BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Hi)
393                 .addReg(MBBI->getOperand(1).getReg())
394                 .addImm(MBBI->getOperand(2).getImm() + 4);
395   }
396 
397   // Order: Hi, Lo
398   if (IsOp1EqualToLo) {
399     MIBLo = BuildMI(MBB, MBBI, DL, TII->get(RISCV::LW), Lo)
400                 .addReg(MBBI->getOperand(1).getReg())
401                 .add(MBBI->getOperand(2));
402   }
403 
404   MachineFunction *MF = MBB.getParent();
405   SmallVector<MachineMemOperand *> NewLoMMOs;
406   SmallVector<MachineMemOperand *> NewHiMMOs;
407   for (const MachineMemOperand *MMO : MBBI->memoperands()) {
408     NewLoMMOs.push_back(MF->getMachineMemOperand(MMO, 0, 4));
409     NewHiMMOs.push_back(MF->getMachineMemOperand(MMO, 4, 4));
410   }
411   MIBLo.setMemRefs(NewLoMMOs);
412   MIBHi.setMemRefs(NewHiMMOs);
413 
414   MBBI->eraseFromParent();
415   return true;
416 }
417 
418 class RISCVPreRAExpandPseudo : public MachineFunctionPass {
419 public:
420   const RISCVSubtarget *STI;
421   const RISCVInstrInfo *TII;
422   static char ID;
423 
424   RISCVPreRAExpandPseudo() : MachineFunctionPass(ID) {}
425 
426   bool runOnMachineFunction(MachineFunction &MF) override;
427 
428   void getAnalysisUsage(AnalysisUsage &AU) const override {
429     AU.setPreservesCFG();
430     MachineFunctionPass::getAnalysisUsage(AU);
431   }
432   StringRef getPassName() const override {
433     return RISCV_PRERA_EXPAND_PSEUDO_NAME;
434   }
435 
436 private:
437   bool expandMBB(MachineBasicBlock &MBB);
438   bool expandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
439                 MachineBasicBlock::iterator &NextMBBI);
440   bool expandAuipcInstPair(MachineBasicBlock &MBB,
441                            MachineBasicBlock::iterator MBBI,
442                            MachineBasicBlock::iterator &NextMBBI,
443                            unsigned FlagsHi, unsigned SecondOpcode);
444   bool expandLoadLocalAddress(MachineBasicBlock &MBB,
445                               MachineBasicBlock::iterator MBBI,
446                               MachineBasicBlock::iterator &NextMBBI);
447   bool expandLoadGlobalAddress(MachineBasicBlock &MBB,
448                                MachineBasicBlock::iterator MBBI,
449                                MachineBasicBlock::iterator &NextMBBI);
450   bool expandLoadTLSIEAddress(MachineBasicBlock &MBB,
451                               MachineBasicBlock::iterator MBBI,
452                               MachineBasicBlock::iterator &NextMBBI);
453   bool expandLoadTLSGDAddress(MachineBasicBlock &MBB,
454                               MachineBasicBlock::iterator MBBI,
455                               MachineBasicBlock::iterator &NextMBBI);
456   bool expandLoadTLSDescAddress(MachineBasicBlock &MBB,
457                                 MachineBasicBlock::iterator MBBI,
458                                 MachineBasicBlock::iterator &NextMBBI);
459 
460 #ifndef NDEBUG
461   unsigned getInstSizeInBytes(const MachineFunction &MF) const {
462     unsigned Size = 0;
463     for (auto &MBB : MF)
464       for (auto &MI : MBB)
465         Size += TII->getInstSizeInBytes(MI);
466     return Size;
467   }
468 #endif
469 };
470 
471 char RISCVPreRAExpandPseudo::ID = 0;
472 
473 bool RISCVPreRAExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
474   STI = &MF.getSubtarget<RISCVSubtarget>();
475   TII = STI->getInstrInfo();
476 
477 #ifndef NDEBUG
478   const unsigned OldSize = getInstSizeInBytes(MF);
479 #endif
480 
481   bool Modified = false;
482   for (auto &MBB : MF)
483     Modified |= expandMBB(MBB);
484 
485 #ifndef NDEBUG
486   const unsigned NewSize = getInstSizeInBytes(MF);
487   assert(OldSize >= NewSize);
488 #endif
489   return Modified;
490 }
491 
492 bool RISCVPreRAExpandPseudo::expandMBB(MachineBasicBlock &MBB) {
493   bool Modified = false;
494 
495   MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
496   while (MBBI != E) {
497     MachineBasicBlock::iterator NMBBI = std::next(MBBI);
498     Modified |= expandMI(MBB, MBBI, NMBBI);
499     MBBI = NMBBI;
500   }
501 
502   return Modified;
503 }
504 
505 bool RISCVPreRAExpandPseudo::expandMI(MachineBasicBlock &MBB,
506                                       MachineBasicBlock::iterator MBBI,
507                                       MachineBasicBlock::iterator &NextMBBI) {
508 
509   switch (MBBI->getOpcode()) {
510   case RISCV::PseudoLLA:
511     return expandLoadLocalAddress(MBB, MBBI, NextMBBI);
512   case RISCV::PseudoLGA:
513     return expandLoadGlobalAddress(MBB, MBBI, NextMBBI);
514   case RISCV::PseudoLA_TLS_IE:
515     return expandLoadTLSIEAddress(MBB, MBBI, NextMBBI);
516   case RISCV::PseudoLA_TLS_GD:
517     return expandLoadTLSGDAddress(MBB, MBBI, NextMBBI);
518   case RISCV::PseudoLA_TLSDESC:
519     return expandLoadTLSDescAddress(MBB, MBBI, NextMBBI);
520   }
521   return false;
522 }
523 
524 bool RISCVPreRAExpandPseudo::expandAuipcInstPair(
525     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
526     MachineBasicBlock::iterator &NextMBBI, unsigned FlagsHi,
527     unsigned SecondOpcode) {
528   MachineFunction *MF = MBB.getParent();
529   MachineInstr &MI = *MBBI;
530   DebugLoc DL = MI.getDebugLoc();
531 
532   Register DestReg = MI.getOperand(0).getReg();
533   Register ScratchReg =
534       MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
535 
536   MachineOperand &Symbol = MI.getOperand(1);
537   Symbol.setTargetFlags(FlagsHi);
538   MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("pcrel_hi");
539 
540   MachineInstr *MIAUIPC =
541       BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol);
542   MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol);
543 
544   MachineInstr *SecondMI =
545       BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg)
546           .addReg(ScratchReg)
547           .addSym(AUIPCSymbol, RISCVII::MO_PCREL_LO);
548 
549   if (MI.hasOneMemOperand())
550     SecondMI->addMemOperand(*MF, *MI.memoperands_begin());
551 
552   MI.eraseFromParent();
553   return true;
554 }
555 
556 bool RISCVPreRAExpandPseudo::expandLoadLocalAddress(
557     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
558     MachineBasicBlock::iterator &NextMBBI) {
559   return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_PCREL_HI,
560                              RISCV::ADDI);
561 }
562 
563 bool RISCVPreRAExpandPseudo::expandLoadGlobalAddress(
564     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
565     MachineBasicBlock::iterator &NextMBBI) {
566   unsigned SecondOpcode = STI->is64Bit() ? RISCV::LD : RISCV::LW;
567   return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_GOT_HI,
568                              SecondOpcode);
569 }
570 
571 bool RISCVPreRAExpandPseudo::expandLoadTLSIEAddress(
572     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
573     MachineBasicBlock::iterator &NextMBBI) {
574   unsigned SecondOpcode = STI->is64Bit() ? RISCV::LD : RISCV::LW;
575   return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GOT_HI,
576                              SecondOpcode);
577 }
578 
579 bool RISCVPreRAExpandPseudo::expandLoadTLSGDAddress(
580     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
581     MachineBasicBlock::iterator &NextMBBI) {
582   return expandAuipcInstPair(MBB, MBBI, NextMBBI, RISCVII::MO_TLS_GD_HI,
583                              RISCV::ADDI);
584 }
585 
586 bool RISCVPreRAExpandPseudo::expandLoadTLSDescAddress(
587     MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI,
588     MachineBasicBlock::iterator &NextMBBI) {
589   MachineFunction *MF = MBB.getParent();
590   MachineInstr &MI = *MBBI;
591   DebugLoc DL = MI.getDebugLoc();
592 
593   const auto &STI = MF->getSubtarget<RISCVSubtarget>();
594   unsigned SecondOpcode = STI.is64Bit() ? RISCV::LD : RISCV::LW;
595 
596   Register FinalReg = MI.getOperand(0).getReg();
597   Register DestReg =
598       MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
599   Register ScratchReg =
600       MF->getRegInfo().createVirtualRegister(&RISCV::GPRRegClass);
601 
602   MachineOperand &Symbol = MI.getOperand(1);
603   Symbol.setTargetFlags(RISCVII::MO_TLSDESC_HI);
604   MCSymbol *AUIPCSymbol = MF->getContext().createNamedTempSymbol("tlsdesc_hi");
605 
606   MachineInstr *MIAUIPC =
607       BuildMI(MBB, MBBI, DL, TII->get(RISCV::AUIPC), ScratchReg).add(Symbol);
608   MIAUIPC->setPreInstrSymbol(*MF, AUIPCSymbol);
609 
610   BuildMI(MBB, MBBI, DL, TII->get(SecondOpcode), DestReg)
611       .addReg(ScratchReg)
612       .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_LOAD_LO);
613 
614   BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADDI), RISCV::X10)
615       .addReg(ScratchReg)
616       .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_ADD_LO);
617 
618   BuildMI(MBB, MBBI, DL, TII->get(RISCV::PseudoTLSDESCCall), RISCV::X5)
619       .addReg(DestReg)
620       .addImm(0)
621       .addSym(AUIPCSymbol, RISCVII::MO_TLSDESC_CALL);
622 
623   BuildMI(MBB, MBBI, DL, TII->get(RISCV::ADD), FinalReg)
624       .addReg(RISCV::X10)
625       .addReg(RISCV::X4);
626 
627   MI.eraseFromParent();
628   return true;
629 }
630 
631 } // end of anonymous namespace
632 
633 INITIALIZE_PASS(RISCVExpandPseudo, "riscv-expand-pseudo",
634                 RISCV_EXPAND_PSEUDO_NAME, false, false)
635 
636 INITIALIZE_PASS(RISCVPreRAExpandPseudo, "riscv-prera-expand-pseudo",
637                 RISCV_PRERA_EXPAND_PSEUDO_NAME, false, false)
638 
639 namespace llvm {
640 
641 FunctionPass *createRISCVExpandPseudoPass() { return new RISCVExpandPseudo(); }
642 FunctionPass *createRISCVPreRAExpandPseudoPass() { return new RISCVPreRAExpandPseudo(); }
643 
644 } // end of namespace llvm
645