1 //===------- X86ExpandPseudo.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 to allow proper scheduling, if-conversion, other late 11 // optimizations, or simply the encoding of the instructions. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "X86.h" 16 #include "X86FrameLowering.h" 17 #include "X86InstrBuilder.h" 18 #include "X86InstrInfo.h" 19 #include "X86MachineFunctionInfo.h" 20 #include "X86Subtarget.h" 21 #include "llvm/Analysis/EHPersonalities.h" 22 #include "llvm/CodeGen/MachineFunctionPass.h" 23 #include "llvm/CodeGen/MachineInstrBuilder.h" 24 #include "llvm/CodeGen/Passes.h" // For IDs of passes that are preserved. 25 #include "llvm/IR/GlobalValue.h" 26 #include "llvm/Target/TargetMachine.h" 27 using namespace llvm; 28 29 #define DEBUG_TYPE "x86-pseudo" 30 #define X86_EXPAND_PSEUDO_NAME "X86 pseudo instruction expansion pass" 31 32 namespace { 33 class X86ExpandPseudo : public MachineFunctionPass { 34 public: 35 static char ID; 36 X86ExpandPseudo() : MachineFunctionPass(ID) {} 37 38 void getAnalysisUsage(AnalysisUsage &AU) const override { 39 AU.setPreservesCFG(); 40 AU.addPreservedID(MachineLoopInfoID); 41 AU.addPreservedID(MachineDominatorsID); 42 MachineFunctionPass::getAnalysisUsage(AU); 43 } 44 45 const X86Subtarget *STI = nullptr; 46 const X86InstrInfo *TII = nullptr; 47 const X86RegisterInfo *TRI = nullptr; 48 const X86MachineFunctionInfo *X86FI = nullptr; 49 const X86FrameLowering *X86FL = nullptr; 50 51 bool runOnMachineFunction(MachineFunction &Fn) override; 52 53 MachineFunctionProperties getRequiredProperties() const override { 54 return MachineFunctionProperties().set( 55 MachineFunctionProperties::Property::NoVRegs); 56 } 57 58 StringRef getPassName() const override { 59 return "X86 pseudo instruction expansion pass"; 60 } 61 62 private: 63 void ExpandICallBranchFunnel(MachineBasicBlock *MBB, 64 MachineBasicBlock::iterator MBBI); 65 66 bool ExpandMI(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI); 67 bool ExpandMBB(MachineBasicBlock &MBB); 68 69 /// This function expands pseudos which affects control flow. 70 /// It is done in separate pass to simplify blocks navigation in main 71 /// pass(calling ExpandMBB). 72 bool ExpandPseudosWhichAffectControlFlow(MachineFunction &MF); 73 74 /// Expand X86::VASTART_SAVE_XMM_REGS into set of xmm copying instructions, 75 /// placed into separate block guarded by check for al register(for SystemV 76 /// abi). 77 void ExpandVastartSaveXmmRegs( 78 MachineBasicBlock *MBB, 79 MachineBasicBlock::iterator VAStartPseudoInstr) const; 80 }; 81 char X86ExpandPseudo::ID = 0; 82 83 } // End anonymous namespace. 84 85 INITIALIZE_PASS(X86ExpandPseudo, DEBUG_TYPE, X86_EXPAND_PSEUDO_NAME, false, 86 false) 87 88 void X86ExpandPseudo::ExpandICallBranchFunnel( 89 MachineBasicBlock *MBB, MachineBasicBlock::iterator MBBI) { 90 MachineBasicBlock *JTMBB = MBB; 91 MachineInstr *JTInst = &*MBBI; 92 MachineFunction *MF = MBB->getParent(); 93 const BasicBlock *BB = MBB->getBasicBlock(); 94 auto InsPt = MachineFunction::iterator(MBB); 95 ++InsPt; 96 97 std::vector<std::pair<MachineBasicBlock *, unsigned>> TargetMBBs; 98 DebugLoc DL = JTInst->getDebugLoc(); 99 MachineOperand Selector = JTInst->getOperand(0); 100 const GlobalValue *CombinedGlobal = JTInst->getOperand(1).getGlobal(); 101 102 auto CmpTarget = [&](unsigned Target) { 103 if (Selector.isReg()) 104 MBB->addLiveIn(Selector.getReg()); 105 BuildMI(*MBB, MBBI, DL, TII->get(X86::LEA64r), X86::R11) 106 .addReg(X86::RIP) 107 .addImm(1) 108 .addReg(0) 109 .addGlobalAddress(CombinedGlobal, 110 JTInst->getOperand(2 + 2 * Target).getImm()) 111 .addReg(0); 112 BuildMI(*MBB, MBBI, DL, TII->get(X86::CMP64rr)) 113 .add(Selector) 114 .addReg(X86::R11); 115 }; 116 117 auto CreateMBB = [&]() { 118 auto *NewMBB = MF->CreateMachineBasicBlock(BB); 119 MBB->addSuccessor(NewMBB); 120 if (!MBB->isLiveIn(X86::EFLAGS)) 121 MBB->addLiveIn(X86::EFLAGS); 122 return NewMBB; 123 }; 124 125 auto EmitCondJump = [&](unsigned CC, MachineBasicBlock *ThenMBB) { 126 BuildMI(*MBB, MBBI, DL, TII->get(X86::JCC_1)).addMBB(ThenMBB).addImm(CC); 127 128 auto *ElseMBB = CreateMBB(); 129 MF->insert(InsPt, ElseMBB); 130 MBB = ElseMBB; 131 MBBI = MBB->end(); 132 }; 133 134 auto EmitCondJumpTarget = [&](unsigned CC, unsigned Target) { 135 auto *ThenMBB = CreateMBB(); 136 TargetMBBs.push_back({ThenMBB, Target}); 137 EmitCondJump(CC, ThenMBB); 138 }; 139 140 auto EmitTailCall = [&](unsigned Target) { 141 BuildMI(*MBB, MBBI, DL, TII->get(X86::TAILJMPd64)) 142 .add(JTInst->getOperand(3 + 2 * Target)); 143 }; 144 145 std::function<void(unsigned, unsigned)> EmitBranchFunnel = 146 [&](unsigned FirstTarget, unsigned NumTargets) { 147 if (NumTargets == 1) { 148 EmitTailCall(FirstTarget); 149 return; 150 } 151 152 if (NumTargets == 2) { 153 CmpTarget(FirstTarget + 1); 154 EmitCondJumpTarget(X86::COND_B, FirstTarget); 155 EmitTailCall(FirstTarget + 1); 156 return; 157 } 158 159 if (NumTargets < 6) { 160 CmpTarget(FirstTarget + 1); 161 EmitCondJumpTarget(X86::COND_B, FirstTarget); 162 EmitCondJumpTarget(X86::COND_E, FirstTarget + 1); 163 EmitBranchFunnel(FirstTarget + 2, NumTargets - 2); 164 return; 165 } 166 167 auto *ThenMBB = CreateMBB(); 168 CmpTarget(FirstTarget + (NumTargets / 2)); 169 EmitCondJump(X86::COND_B, ThenMBB); 170 EmitCondJumpTarget(X86::COND_E, FirstTarget + (NumTargets / 2)); 171 EmitBranchFunnel(FirstTarget + (NumTargets / 2) + 1, 172 NumTargets - (NumTargets / 2) - 1); 173 174 MF->insert(InsPt, ThenMBB); 175 MBB = ThenMBB; 176 MBBI = MBB->end(); 177 EmitBranchFunnel(FirstTarget, NumTargets / 2); 178 }; 179 180 EmitBranchFunnel(0, (JTInst->getNumOperands() - 2) / 2); 181 for (auto P : TargetMBBs) { 182 MF->insert(InsPt, P.first); 183 BuildMI(P.first, DL, TII->get(X86::TAILJMPd64)) 184 .add(JTInst->getOperand(3 + 2 * P.second)); 185 } 186 JTMBB->erase(JTInst); 187 } 188 189 /// If \p MBBI is a pseudo instruction, this method expands 190 /// it to the corresponding (sequence of) actual instruction(s). 191 /// \returns true if \p MBBI has been expanded. 192 bool X86ExpandPseudo::ExpandMI(MachineBasicBlock &MBB, 193 MachineBasicBlock::iterator MBBI) { 194 MachineInstr &MI = *MBBI; 195 unsigned Opcode = MI.getOpcode(); 196 DebugLoc DL = MBBI->getDebugLoc(); 197 switch (Opcode) { 198 default: 199 return false; 200 case X86::TCRETURNdi: 201 case X86::TCRETURNdicc: 202 case X86::TCRETURNri: 203 case X86::TCRETURNmi: 204 case X86::TCRETURNdi64: 205 case X86::TCRETURNdi64cc: 206 case X86::TCRETURNri64: 207 case X86::TCRETURNmi64: { 208 bool isMem = Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64; 209 MachineOperand &JumpTarget = MBBI->getOperand(0); 210 MachineOperand &StackAdjust = MBBI->getOperand(isMem ? X86::AddrNumOperands 211 : 1); 212 assert(StackAdjust.isImm() && "Expecting immediate value."); 213 214 // Adjust stack pointer. 215 int StackAdj = StackAdjust.getImm(); 216 int MaxTCDelta = X86FI->getTCReturnAddrDelta(); 217 int Offset = 0; 218 assert(MaxTCDelta <= 0 && "MaxTCDelta should never be positive"); 219 220 // Incoporate the retaddr area. 221 Offset = StackAdj - MaxTCDelta; 222 assert(Offset >= 0 && "Offset should never be negative"); 223 224 if (Opcode == X86::TCRETURNdicc || Opcode == X86::TCRETURNdi64cc) { 225 assert(Offset == 0 && "Conditional tail call cannot adjust the stack."); 226 } 227 228 if (Offset) { 229 // Check for possible merge with preceding ADD instruction. 230 Offset += X86FL->mergeSPUpdates(MBB, MBBI, true); 231 X86FL->emitSPUpdate(MBB, MBBI, DL, Offset, /*InEpilogue=*/true); 232 } 233 234 // Jump to label or value in register. 235 bool IsWin64 = STI->isTargetWin64(); 236 if (Opcode == X86::TCRETURNdi || Opcode == X86::TCRETURNdicc || 237 Opcode == X86::TCRETURNdi64 || Opcode == X86::TCRETURNdi64cc) { 238 unsigned Op; 239 switch (Opcode) { 240 case X86::TCRETURNdi: 241 Op = X86::TAILJMPd; 242 break; 243 case X86::TCRETURNdicc: 244 Op = X86::TAILJMPd_CC; 245 break; 246 case X86::TCRETURNdi64cc: 247 assert(!MBB.getParent()->hasWinCFI() && 248 "Conditional tail calls confuse " 249 "the Win64 unwinder."); 250 Op = X86::TAILJMPd64_CC; 251 break; 252 default: 253 // Note: Win64 uses REX prefixes indirect jumps out of functions, but 254 // not direct ones. 255 Op = X86::TAILJMPd64; 256 break; 257 } 258 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op)); 259 if (JumpTarget.isGlobal()) { 260 MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(), 261 JumpTarget.getTargetFlags()); 262 } else { 263 assert(JumpTarget.isSymbol()); 264 MIB.addExternalSymbol(JumpTarget.getSymbolName(), 265 JumpTarget.getTargetFlags()); 266 } 267 if (Op == X86::TAILJMPd_CC || Op == X86::TAILJMPd64_CC) { 268 MIB.addImm(MBBI->getOperand(2).getImm()); 269 } 270 271 } else if (Opcode == X86::TCRETURNmi || Opcode == X86::TCRETURNmi64) { 272 unsigned Op = (Opcode == X86::TCRETURNmi) 273 ? X86::TAILJMPm 274 : (IsWin64 ? X86::TAILJMPm64_REX : X86::TAILJMPm64); 275 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, DL, TII->get(Op)); 276 for (unsigned i = 0; i != X86::AddrNumOperands; ++i) 277 MIB.add(MBBI->getOperand(i)); 278 } else if (Opcode == X86::TCRETURNri64) { 279 JumpTarget.setIsKill(); 280 BuildMI(MBB, MBBI, DL, 281 TII->get(IsWin64 ? X86::TAILJMPr64_REX : X86::TAILJMPr64)) 282 .add(JumpTarget); 283 } else { 284 JumpTarget.setIsKill(); 285 BuildMI(MBB, MBBI, DL, TII->get(X86::TAILJMPr)) 286 .add(JumpTarget); 287 } 288 289 MachineInstr &NewMI = *std::prev(MBBI); 290 NewMI.copyImplicitOps(*MBBI->getParent()->getParent(), *MBBI); 291 292 // Update the call site info. 293 if (MBBI->isCandidateForCallSiteEntry()) 294 MBB.getParent()->moveCallSiteInfo(&*MBBI, &NewMI); 295 296 // Delete the pseudo instruction TCRETURN. 297 MBB.erase(MBBI); 298 299 return true; 300 } 301 case X86::EH_RETURN: 302 case X86::EH_RETURN64: { 303 MachineOperand &DestAddr = MBBI->getOperand(0); 304 assert(DestAddr.isReg() && "Offset should be in register!"); 305 const bool Uses64BitFramePtr = 306 STI->isTarget64BitLP64() || STI->isTargetNaCl64(); 307 Register StackPtr = TRI->getStackRegister(); 308 BuildMI(MBB, MBBI, DL, 309 TII->get(Uses64BitFramePtr ? X86::MOV64rr : X86::MOV32rr), StackPtr) 310 .addReg(DestAddr.getReg()); 311 // The EH_RETURN pseudo is really removed during the MC Lowering. 312 return true; 313 } 314 case X86::IRET: { 315 // Adjust stack to erase error code 316 int64_t StackAdj = MBBI->getOperand(0).getImm(); 317 X86FL->emitSPUpdate(MBB, MBBI, DL, StackAdj, true); 318 // Replace pseudo with machine iret 319 unsigned RetOp = STI->is64Bit() ? X86::IRET64 : X86::IRET32; 320 // Use UIRET if UINTR is present (except for building kernel) 321 if (STI->is64Bit() && STI->hasUINTR() && 322 MBB.getParent()->getTarget().getCodeModel() != CodeModel::Kernel) 323 RetOp = X86::UIRET; 324 BuildMI(MBB, MBBI, DL, TII->get(RetOp)); 325 MBB.erase(MBBI); 326 return true; 327 } 328 case X86::RET: { 329 // Adjust stack to erase error code 330 int64_t StackAdj = MBBI->getOperand(0).getImm(); 331 MachineInstrBuilder MIB; 332 if (StackAdj == 0) { 333 MIB = BuildMI(MBB, MBBI, DL, 334 TII->get(STI->is64Bit() ? X86::RETQ : X86::RETL)); 335 } else if (isUInt<16>(StackAdj)) { 336 MIB = BuildMI(MBB, MBBI, DL, 337 TII->get(STI->is64Bit() ? X86::RETIQ : X86::RETIL)) 338 .addImm(StackAdj); 339 } else { 340 assert(!STI->is64Bit() && 341 "shouldn't need to do this for x86_64 targets!"); 342 // A ret can only handle immediates as big as 2**16-1. If we need to pop 343 // off bytes before the return address, we must do it manually. 344 BuildMI(MBB, MBBI, DL, TII->get(X86::POP32r)).addReg(X86::ECX, RegState::Define); 345 X86FL->emitSPUpdate(MBB, MBBI, DL, StackAdj, /*InEpilogue=*/true); 346 BuildMI(MBB, MBBI, DL, TII->get(X86::PUSH32r)).addReg(X86::ECX); 347 MIB = BuildMI(MBB, MBBI, DL, TII->get(X86::RETL)); 348 } 349 for (unsigned I = 1, E = MBBI->getNumOperands(); I != E; ++I) 350 MIB.add(MBBI->getOperand(I)); 351 MBB.erase(MBBI); 352 return true; 353 } 354 case X86::LCMPXCHG16B_SAVE_RBX: { 355 // Perform the following transformation. 356 // SaveRbx = pseudocmpxchg Addr, <4 opds for the address>, InArg, SaveRbx 357 // => 358 // RBX = InArg 359 // actualcmpxchg Addr 360 // RBX = SaveRbx 361 const MachineOperand &InArg = MBBI->getOperand(6); 362 Register SaveRbx = MBBI->getOperand(7).getReg(); 363 364 // Copy the input argument of the pseudo into the argument of the 365 // actual instruction. 366 // NOTE: We don't copy the kill flag since the input might be the same reg 367 // as one of the other operands of LCMPXCHG16B. 368 TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, InArg.getReg(), false); 369 // Create the actual instruction. 370 MachineInstr *NewInstr = BuildMI(MBB, MBBI, DL, TII->get(X86::LCMPXCHG16B)); 371 // Copy the operands related to the address. 372 for (unsigned Idx = 1; Idx < 6; ++Idx) 373 NewInstr->addOperand(MBBI->getOperand(Idx)); 374 // Finally, restore the value of RBX. 375 TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, SaveRbx, 376 /*SrcIsKill*/ true); 377 378 // Delete the pseudo. 379 MBBI->eraseFromParent(); 380 return true; 381 } 382 // Loading/storing mask pairs requires two kmov operations. The second one of 383 // these needs a 2 byte displacement relative to the specified address (with 384 // 32 bit spill size). The pairs of 1bit masks up to 16 bit masks all use the 385 // same spill size, they all are stored using MASKPAIR16STORE, loaded using 386 // MASKPAIR16LOAD. 387 // 388 // The displacement value might wrap around in theory, thus the asserts in 389 // both cases. 390 case X86::MASKPAIR16LOAD: { 391 int64_t Disp = MBBI->getOperand(1 + X86::AddrDisp).getImm(); 392 assert(Disp >= 0 && Disp <= INT32_MAX - 2 && "Unexpected displacement"); 393 Register Reg = MBBI->getOperand(0).getReg(); 394 bool DstIsDead = MBBI->getOperand(0).isDead(); 395 Register Reg0 = TRI->getSubReg(Reg, X86::sub_mask_0); 396 Register Reg1 = TRI->getSubReg(Reg, X86::sub_mask_1); 397 398 auto MIBLo = BuildMI(MBB, MBBI, DL, TII->get(X86::KMOVWkm)) 399 .addReg(Reg0, RegState::Define | getDeadRegState(DstIsDead)); 400 auto MIBHi = BuildMI(MBB, MBBI, DL, TII->get(X86::KMOVWkm)) 401 .addReg(Reg1, RegState::Define | getDeadRegState(DstIsDead)); 402 403 for (int i = 0; i < X86::AddrNumOperands; ++i) { 404 MIBLo.add(MBBI->getOperand(1 + i)); 405 if (i == X86::AddrDisp) 406 MIBHi.addImm(Disp + 2); 407 else 408 MIBHi.add(MBBI->getOperand(1 + i)); 409 } 410 411 // Split the memory operand, adjusting the offset and size for the halves. 412 MachineMemOperand *OldMMO = MBBI->memoperands().front(); 413 MachineFunction *MF = MBB.getParent(); 414 MachineMemOperand *MMOLo = MF->getMachineMemOperand(OldMMO, 0, 2); 415 MachineMemOperand *MMOHi = MF->getMachineMemOperand(OldMMO, 2, 2); 416 417 MIBLo.setMemRefs(MMOLo); 418 MIBHi.setMemRefs(MMOHi); 419 420 // Delete the pseudo. 421 MBB.erase(MBBI); 422 return true; 423 } 424 case X86::MASKPAIR16STORE: { 425 int64_t Disp = MBBI->getOperand(X86::AddrDisp).getImm(); 426 assert(Disp >= 0 && Disp <= INT32_MAX - 2 && "Unexpected displacement"); 427 Register Reg = MBBI->getOperand(X86::AddrNumOperands).getReg(); 428 bool SrcIsKill = MBBI->getOperand(X86::AddrNumOperands).isKill(); 429 Register Reg0 = TRI->getSubReg(Reg, X86::sub_mask_0); 430 Register Reg1 = TRI->getSubReg(Reg, X86::sub_mask_1); 431 432 auto MIBLo = BuildMI(MBB, MBBI, DL, TII->get(X86::KMOVWmk)); 433 auto MIBHi = BuildMI(MBB, MBBI, DL, TII->get(X86::KMOVWmk)); 434 435 for (int i = 0; i < X86::AddrNumOperands; ++i) { 436 MIBLo.add(MBBI->getOperand(i)); 437 if (i == X86::AddrDisp) 438 MIBHi.addImm(Disp + 2); 439 else 440 MIBHi.add(MBBI->getOperand(i)); 441 } 442 MIBLo.addReg(Reg0, getKillRegState(SrcIsKill)); 443 MIBHi.addReg(Reg1, getKillRegState(SrcIsKill)); 444 445 // Split the memory operand, adjusting the offset and size for the halves. 446 MachineMemOperand *OldMMO = MBBI->memoperands().front(); 447 MachineFunction *MF = MBB.getParent(); 448 MachineMemOperand *MMOLo = MF->getMachineMemOperand(OldMMO, 0, 2); 449 MachineMemOperand *MMOHi = MF->getMachineMemOperand(OldMMO, 2, 2); 450 451 MIBLo.setMemRefs(MMOLo); 452 MIBHi.setMemRefs(MMOHi); 453 454 // Delete the pseudo. 455 MBB.erase(MBBI); 456 return true; 457 } 458 case X86::MWAITX_SAVE_RBX: { 459 // Perform the following transformation. 460 // SaveRbx = pseudomwaitx InArg, SaveRbx 461 // => 462 // [E|R]BX = InArg 463 // actualmwaitx 464 // [E|R]BX = SaveRbx 465 const MachineOperand &InArg = MBBI->getOperand(1); 466 // Copy the input argument of the pseudo into the argument of the 467 // actual instruction. 468 TII->copyPhysReg(MBB, MBBI, DL, X86::EBX, InArg.getReg(), InArg.isKill()); 469 // Create the actual instruction. 470 BuildMI(MBB, MBBI, DL, TII->get(X86::MWAITXrrr)); 471 // Finally, restore the value of RBX. 472 Register SaveRbx = MBBI->getOperand(2).getReg(); 473 TII->copyPhysReg(MBB, MBBI, DL, X86::RBX, SaveRbx, /*SrcIsKill*/ true); 474 // Delete the pseudo. 475 MBBI->eraseFromParent(); 476 return true; 477 } 478 case TargetOpcode::ICALL_BRANCH_FUNNEL: 479 ExpandICallBranchFunnel(&MBB, MBBI); 480 return true; 481 case X86::PTILELOADDV: { 482 for (unsigned i = 2; i > 0; --i) 483 MI.RemoveOperand(i); 484 MI.setDesc(TII->get(X86::TILELOADD)); 485 return true; 486 } 487 case X86::PTDPBSSDV: 488 case X86::PTDPBSUDV: 489 case X86::PTDPBUSDV: 490 case X86::PTDPBUUDV: 491 case X86::PTDPBF16PSV: { 492 MI.untieRegOperand(4); 493 for (unsigned i = 3; i > 0; --i) 494 MI.RemoveOperand(i); 495 unsigned Opc; 496 switch (Opcode) { 497 case X86::PTDPBSSDV: Opc = X86::TDPBSSD; break; 498 case X86::PTDPBSUDV: Opc = X86::TDPBSUD; break; 499 case X86::PTDPBUSDV: Opc = X86::TDPBUSD; break; 500 case X86::PTDPBUUDV: Opc = X86::TDPBUUD; break; 501 case X86::PTDPBF16PSV: Opc = X86::TDPBF16PS; break; 502 default: llvm_unreachable("Impossible Opcode!"); 503 } 504 MI.setDesc(TII->get(Opc)); 505 MI.tieOperands(0, 1); 506 return true; 507 } 508 case X86::PTILESTOREDV: { 509 for (int i = 1; i >= 0; --i) 510 MI.RemoveOperand(i); 511 MI.setDesc(TII->get(X86::TILESTORED)); 512 return true; 513 } 514 case X86::PTILEZEROV: { 515 for (int i = 2; i > 0; --i) // Remove row, col 516 MI.RemoveOperand(i); 517 MI.setDesc(TII->get(X86::TILEZERO)); 518 return true; 519 } 520 } 521 llvm_unreachable("Previous switch has a fallthrough?"); 522 } 523 524 // This function creates additional block for storing varargs guarded 525 // registers. It adds check for %al into entry block, to skip 526 // GuardedRegsBlk if xmm registers should not be stored. 527 // 528 // EntryBlk[VAStartPseudoInstr] EntryBlk 529 // | | . 530 // | | . 531 // | | GuardedRegsBlk 532 // | => | . 533 // | | . 534 // | TailBlk 535 // | | 536 // | | 537 // 538 void X86ExpandPseudo::ExpandVastartSaveXmmRegs( 539 MachineBasicBlock *EntryBlk, 540 MachineBasicBlock::iterator VAStartPseudoInstr) const { 541 assert(VAStartPseudoInstr->getOpcode() == X86::VASTART_SAVE_XMM_REGS); 542 543 MachineFunction *Func = EntryBlk->getParent(); 544 const TargetInstrInfo *TII = STI->getInstrInfo(); 545 DebugLoc DL = VAStartPseudoInstr->getDebugLoc(); 546 Register CountReg = VAStartPseudoInstr->getOperand(0).getReg(); 547 548 // Calculate liveins for newly created blocks. 549 LivePhysRegs LiveRegs(*STI->getRegisterInfo()); 550 SmallVector<std::pair<MCPhysReg, const MachineOperand *>, 8> Clobbers; 551 552 LiveRegs.addLiveIns(*EntryBlk); 553 for (MachineInstr &MI : EntryBlk->instrs()) { 554 if (MI.getOpcode() == VAStartPseudoInstr->getOpcode()) 555 break; 556 557 LiveRegs.stepForward(MI, Clobbers); 558 } 559 560 // Create the new basic blocks. One block contains all the XMM stores, 561 // and another block is the final destination regardless of whether any 562 // stores were performed. 563 const BasicBlock *LLVMBlk = EntryBlk->getBasicBlock(); 564 MachineFunction::iterator EntryBlkIter = ++EntryBlk->getIterator(); 565 MachineBasicBlock *GuardedRegsBlk = Func->CreateMachineBasicBlock(LLVMBlk); 566 MachineBasicBlock *TailBlk = Func->CreateMachineBasicBlock(LLVMBlk); 567 Func->insert(EntryBlkIter, GuardedRegsBlk); 568 Func->insert(EntryBlkIter, TailBlk); 569 570 // Transfer the remainder of EntryBlk and its successor edges to TailBlk. 571 TailBlk->splice(TailBlk->begin(), EntryBlk, 572 std::next(MachineBasicBlock::iterator(VAStartPseudoInstr)), 573 EntryBlk->end()); 574 TailBlk->transferSuccessorsAndUpdatePHIs(EntryBlk); 575 576 int64_t FrameIndex = VAStartPseudoInstr->getOperand(1).getImm(); 577 Register BaseReg; 578 uint64_t FrameOffset = 579 X86FL->getFrameIndexReference(*Func, FrameIndex, BaseReg).getFixed(); 580 uint64_t VarArgsRegsOffset = VAStartPseudoInstr->getOperand(2).getImm(); 581 582 // TODO: add support for YMM and ZMM here. 583 unsigned MOVOpc = STI->hasAVX() ? X86::VMOVAPSmr : X86::MOVAPSmr; 584 585 // In the XMM save block, save all the XMM argument registers. 586 for (int64_t OpndIdx = 3, RegIdx = 0; 587 OpndIdx < VAStartPseudoInstr->getNumOperands() - 1; 588 OpndIdx++, RegIdx++) { 589 590 int64_t Offset = FrameOffset + VarArgsRegsOffset + RegIdx * 16; 591 592 MachineMemOperand *MMO = Func->getMachineMemOperand( 593 MachinePointerInfo::getFixedStack(*Func, FrameIndex, Offset), 594 MachineMemOperand::MOStore, 595 /*Size=*/16, Align(16)); 596 597 BuildMI(GuardedRegsBlk, DL, TII->get(MOVOpc)) 598 .addReg(BaseReg) 599 .addImm(/*Scale=*/1) 600 .addReg(/*IndexReg=*/0) 601 .addImm(/*Disp=*/Offset) 602 .addReg(/*Segment=*/0) 603 .addReg(VAStartPseudoInstr->getOperand(OpndIdx).getReg()) 604 .addMemOperand(MMO); 605 assert(Register::isPhysicalRegister( 606 VAStartPseudoInstr->getOperand(OpndIdx).getReg())); 607 } 608 609 // The original block will now fall through to the GuardedRegsBlk. 610 EntryBlk->addSuccessor(GuardedRegsBlk); 611 // The GuardedRegsBlk will fall through to the TailBlk. 612 GuardedRegsBlk->addSuccessor(TailBlk); 613 614 if (!STI->isCallingConvWin64(Func->getFunction().getCallingConv())) { 615 // If %al is 0, branch around the XMM save block. 616 BuildMI(EntryBlk, DL, TII->get(X86::TEST8rr)) 617 .addReg(CountReg) 618 .addReg(CountReg); 619 BuildMI(EntryBlk, DL, TII->get(X86::JCC_1)) 620 .addMBB(TailBlk) 621 .addImm(X86::COND_E); 622 EntryBlk->addSuccessor(TailBlk); 623 } 624 625 // Add liveins to the created block. 626 addLiveIns(*GuardedRegsBlk, LiveRegs); 627 addLiveIns(*TailBlk, LiveRegs); 628 629 // Delete the pseudo. 630 VAStartPseudoInstr->eraseFromParent(); 631 } 632 633 /// Expand all pseudo instructions contained in \p MBB. 634 /// \returns true if any expansion occurred for \p MBB. 635 bool X86ExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { 636 bool Modified = false; 637 638 // MBBI may be invalidated by the expansion. 639 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 640 while (MBBI != E) { 641 MachineBasicBlock::iterator NMBBI = std::next(MBBI); 642 Modified |= ExpandMI(MBB, MBBI); 643 MBBI = NMBBI; 644 } 645 646 return Modified; 647 } 648 649 bool X86ExpandPseudo::ExpandPseudosWhichAffectControlFlow(MachineFunction &MF) { 650 // Currently pseudo which affects control flow is only 651 // X86::VASTART_SAVE_XMM_REGS which is located in Entry block. 652 // So we do not need to evaluate other blocks. 653 for (MachineInstr &Instr : MF.front().instrs()) { 654 if (Instr.getOpcode() == X86::VASTART_SAVE_XMM_REGS) { 655 ExpandVastartSaveXmmRegs(&(MF.front()), Instr); 656 return true; 657 } 658 } 659 660 return false; 661 } 662 663 bool X86ExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 664 STI = &static_cast<const X86Subtarget &>(MF.getSubtarget()); 665 TII = STI->getInstrInfo(); 666 TRI = STI->getRegisterInfo(); 667 X86FI = MF.getInfo<X86MachineFunctionInfo>(); 668 X86FL = STI->getFrameLowering(); 669 670 bool Modified = ExpandPseudosWhichAffectControlFlow(MF); 671 672 for (MachineBasicBlock &MBB : MF) 673 Modified |= ExpandMBB(MBB); 674 return Modified; 675 } 676 677 /// Returns an instance of the pseudo instruction expansion pass. 678 FunctionPass *llvm::createX86ExpandPseudoPass() { 679 return new X86ExpandPseudo(); 680 } 681