1 //===- AArch64InstrInfo.cpp - AArch64 Instruction Information -------------===// 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 the AArch64 implementation of the TargetInstrInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "AArch64InstrInfo.h" 14 #include "AArch64MachineFunctionInfo.h" 15 #include "AArch64Subtarget.h" 16 #include "MCTargetDesc/AArch64AddressingModes.h" 17 #include "Utils/AArch64BaseInfo.h" 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/ADT/SmallVector.h" 21 #include "llvm/CodeGen/MachineBasicBlock.h" 22 #include "llvm/CodeGen/MachineFrameInfo.h" 23 #include "llvm/CodeGen/MachineFunction.h" 24 #include "llvm/CodeGen/MachineInstr.h" 25 #include "llvm/CodeGen/MachineInstrBuilder.h" 26 #include "llvm/CodeGen/MachineMemOperand.h" 27 #include "llvm/CodeGen/MachineModuleInfo.h" 28 #include "llvm/CodeGen/MachineOperand.h" 29 #include "llvm/CodeGen/MachineRegisterInfo.h" 30 #include "llvm/CodeGen/StackMaps.h" 31 #include "llvm/CodeGen/TargetRegisterInfo.h" 32 #include "llvm/CodeGen/TargetSubtargetInfo.h" 33 #include "llvm/IR/DebugInfoMetadata.h" 34 #include "llvm/IR/DebugLoc.h" 35 #include "llvm/IR/GlobalValue.h" 36 #include "llvm/MC/MCAsmInfo.h" 37 #include "llvm/MC/MCInst.h" 38 #include "llvm/MC/MCInstBuilder.h" 39 #include "llvm/MC/MCInstrDesc.h" 40 #include "llvm/Support/Casting.h" 41 #include "llvm/Support/CodeGen.h" 42 #include "llvm/Support/CommandLine.h" 43 #include "llvm/Support/Compiler.h" 44 #include "llvm/Support/ErrorHandling.h" 45 #include "llvm/Support/MathExtras.h" 46 #include "llvm/Target/TargetMachine.h" 47 #include "llvm/Target/TargetOptions.h" 48 #include <cassert> 49 #include <cstdint> 50 #include <iterator> 51 #include <utility> 52 53 using namespace llvm; 54 55 #define GET_INSTRINFO_CTOR_DTOR 56 #include "AArch64GenInstrInfo.inc" 57 58 static cl::opt<unsigned> TBZDisplacementBits( 59 "aarch64-tbz-offset-bits", cl::Hidden, cl::init(14), 60 cl::desc("Restrict range of TB[N]Z instructions (DEBUG)")); 61 62 static cl::opt<unsigned> CBZDisplacementBits( 63 "aarch64-cbz-offset-bits", cl::Hidden, cl::init(19), 64 cl::desc("Restrict range of CB[N]Z instructions (DEBUG)")); 65 66 static cl::opt<unsigned> 67 BCCDisplacementBits("aarch64-bcc-offset-bits", cl::Hidden, cl::init(19), 68 cl::desc("Restrict range of Bcc instructions (DEBUG)")); 69 70 AArch64InstrInfo::AArch64InstrInfo(const AArch64Subtarget &STI) 71 : AArch64GenInstrInfo(AArch64::ADJCALLSTACKDOWN, AArch64::ADJCALLSTACKUP, 72 AArch64::CATCHRET), 73 RI(STI.getTargetTriple()), Subtarget(STI) {} 74 75 /// GetInstSize - Return the number of bytes of code the specified 76 /// instruction may be. This returns the maximum number of bytes. 77 unsigned AArch64InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const { 78 const MachineBasicBlock &MBB = *MI.getParent(); 79 const MachineFunction *MF = MBB.getParent(); 80 const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo(); 81 82 { 83 auto Op = MI.getOpcode(); 84 if (Op == AArch64::INLINEASM || Op == AArch64::INLINEASM_BR) 85 return getInlineAsmLength(MI.getOperand(0).getSymbolName(), *MAI); 86 } 87 88 // Meta-instructions emit no code. 89 if (MI.isMetaInstruction()) 90 return 0; 91 92 // FIXME: We currently only handle pseudoinstructions that don't get expanded 93 // before the assembly printer. 94 unsigned NumBytes = 0; 95 const MCInstrDesc &Desc = MI.getDesc(); 96 switch (Desc.getOpcode()) { 97 default: 98 // Anything not explicitly designated otherwise is a normal 4-byte insn. 99 NumBytes = 4; 100 break; 101 case TargetOpcode::STACKMAP: 102 // The upper bound for a stackmap intrinsic is the full length of its shadow 103 NumBytes = StackMapOpers(&MI).getNumPatchBytes(); 104 assert(NumBytes % 4 == 0 && "Invalid number of NOP bytes requested!"); 105 break; 106 case TargetOpcode::PATCHPOINT: 107 // The size of the patchpoint intrinsic is the number of bytes requested 108 NumBytes = PatchPointOpers(&MI).getNumPatchBytes(); 109 assert(NumBytes % 4 == 0 && "Invalid number of NOP bytes requested!"); 110 break; 111 case TargetOpcode::STATEPOINT: 112 NumBytes = StatepointOpers(&MI).getNumPatchBytes(); 113 assert(NumBytes % 4 == 0 && "Invalid number of NOP bytes requested!"); 114 // No patch bytes means a normal call inst is emitted 115 if (NumBytes == 0) 116 NumBytes = 4; 117 break; 118 case AArch64::TLSDESC_CALLSEQ: 119 // This gets lowered to an instruction sequence which takes 16 bytes 120 NumBytes = 16; 121 break; 122 case AArch64::SpeculationBarrierISBDSBEndBB: 123 // This gets lowered to 2 4-byte instructions. 124 NumBytes = 8; 125 break; 126 case AArch64::SpeculationBarrierSBEndBB: 127 // This gets lowered to 1 4-byte instructions. 128 NumBytes = 4; 129 break; 130 case AArch64::JumpTableDest32: 131 case AArch64::JumpTableDest16: 132 case AArch64::JumpTableDest8: 133 case AArch64::MOPSMemoryCopyPseudo: 134 case AArch64::MOPSMemoryMovePseudo: 135 case AArch64::MOPSMemorySetPseudo: 136 case AArch64::MOPSMemorySetTaggingPseudo: 137 NumBytes = 12; 138 break; 139 case AArch64::SPACE: 140 NumBytes = MI.getOperand(1).getImm(); 141 break; 142 case AArch64::StoreSwiftAsyncContext: 143 NumBytes = 20; 144 break; 145 case TargetOpcode::BUNDLE: 146 NumBytes = getInstBundleLength(MI); 147 break; 148 } 149 150 return NumBytes; 151 } 152 153 unsigned AArch64InstrInfo::getInstBundleLength(const MachineInstr &MI) const { 154 unsigned Size = 0; 155 MachineBasicBlock::const_instr_iterator I = MI.getIterator(); 156 MachineBasicBlock::const_instr_iterator E = MI.getParent()->instr_end(); 157 while (++I != E && I->isInsideBundle()) { 158 assert(!I->isBundle() && "No nested bundle!"); 159 Size += getInstSizeInBytes(*I); 160 } 161 return Size; 162 } 163 164 static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, 165 SmallVectorImpl<MachineOperand> &Cond) { 166 // Block ends with fall-through condbranch. 167 switch (LastInst->getOpcode()) { 168 default: 169 llvm_unreachable("Unknown branch instruction?"); 170 case AArch64::Bcc: 171 Target = LastInst->getOperand(1).getMBB(); 172 Cond.push_back(LastInst->getOperand(0)); 173 break; 174 case AArch64::CBZW: 175 case AArch64::CBZX: 176 case AArch64::CBNZW: 177 case AArch64::CBNZX: 178 Target = LastInst->getOperand(1).getMBB(); 179 Cond.push_back(MachineOperand::CreateImm(-1)); 180 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); 181 Cond.push_back(LastInst->getOperand(0)); 182 break; 183 case AArch64::TBZW: 184 case AArch64::TBZX: 185 case AArch64::TBNZW: 186 case AArch64::TBNZX: 187 Target = LastInst->getOperand(2).getMBB(); 188 Cond.push_back(MachineOperand::CreateImm(-1)); 189 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); 190 Cond.push_back(LastInst->getOperand(0)); 191 Cond.push_back(LastInst->getOperand(1)); 192 } 193 } 194 195 static unsigned getBranchDisplacementBits(unsigned Opc) { 196 switch (Opc) { 197 default: 198 llvm_unreachable("unexpected opcode!"); 199 case AArch64::B: 200 return 64; 201 case AArch64::TBNZW: 202 case AArch64::TBZW: 203 case AArch64::TBNZX: 204 case AArch64::TBZX: 205 return TBZDisplacementBits; 206 case AArch64::CBNZW: 207 case AArch64::CBZW: 208 case AArch64::CBNZX: 209 case AArch64::CBZX: 210 return CBZDisplacementBits; 211 case AArch64::Bcc: 212 return BCCDisplacementBits; 213 } 214 } 215 216 bool AArch64InstrInfo::isBranchOffsetInRange(unsigned BranchOp, 217 int64_t BrOffset) const { 218 unsigned Bits = getBranchDisplacementBits(BranchOp); 219 assert(Bits >= 3 && "max branch displacement must be enough to jump" 220 "over conditional branch expansion"); 221 return isIntN(Bits, BrOffset / 4); 222 } 223 224 MachineBasicBlock * 225 AArch64InstrInfo::getBranchDestBlock(const MachineInstr &MI) const { 226 switch (MI.getOpcode()) { 227 default: 228 llvm_unreachable("unexpected opcode!"); 229 case AArch64::B: 230 return MI.getOperand(0).getMBB(); 231 case AArch64::TBZW: 232 case AArch64::TBNZW: 233 case AArch64::TBZX: 234 case AArch64::TBNZX: 235 return MI.getOperand(2).getMBB(); 236 case AArch64::CBZW: 237 case AArch64::CBNZW: 238 case AArch64::CBZX: 239 case AArch64::CBNZX: 240 case AArch64::Bcc: 241 return MI.getOperand(1).getMBB(); 242 } 243 } 244 245 // Branch analysis. 246 bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB, 247 MachineBasicBlock *&TBB, 248 MachineBasicBlock *&FBB, 249 SmallVectorImpl<MachineOperand> &Cond, 250 bool AllowModify) const { 251 // If the block has no terminators, it just falls into the block after it. 252 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 253 if (I == MBB.end()) 254 return false; 255 256 // Skip over SpeculationBarrierEndBB terminators 257 if (I->getOpcode() == AArch64::SpeculationBarrierISBDSBEndBB || 258 I->getOpcode() == AArch64::SpeculationBarrierSBEndBB) { 259 --I; 260 } 261 262 if (!isUnpredicatedTerminator(*I)) 263 return false; 264 265 // Get the last instruction in the block. 266 MachineInstr *LastInst = &*I; 267 268 // If there is only one terminator instruction, process it. 269 unsigned LastOpc = LastInst->getOpcode(); 270 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 271 if (isUncondBranchOpcode(LastOpc)) { 272 TBB = LastInst->getOperand(0).getMBB(); 273 return false; 274 } 275 if (isCondBranchOpcode(LastOpc)) { 276 // Block ends with fall-through condbranch. 277 parseCondBranch(LastInst, TBB, Cond); 278 return false; 279 } 280 return true; // Can't handle indirect branch. 281 } 282 283 // Get the instruction before it if it is a terminator. 284 MachineInstr *SecondLastInst = &*I; 285 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 286 287 // If AllowModify is true and the block ends with two or more unconditional 288 // branches, delete all but the first unconditional branch. 289 if (AllowModify && isUncondBranchOpcode(LastOpc)) { 290 while (isUncondBranchOpcode(SecondLastOpc)) { 291 LastInst->eraseFromParent(); 292 LastInst = SecondLastInst; 293 LastOpc = LastInst->getOpcode(); 294 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 295 // Return now the only terminator is an unconditional branch. 296 TBB = LastInst->getOperand(0).getMBB(); 297 return false; 298 } else { 299 SecondLastInst = &*I; 300 SecondLastOpc = SecondLastInst->getOpcode(); 301 } 302 } 303 } 304 305 // If we're allowed to modify and the block ends in a unconditional branch 306 // which could simply fallthrough, remove the branch. (Note: This case only 307 // matters when we can't understand the whole sequence, otherwise it's also 308 // handled by BranchFolding.cpp.) 309 if (AllowModify && isUncondBranchOpcode(LastOpc) && 310 MBB.isLayoutSuccessor(getBranchDestBlock(*LastInst))) { 311 LastInst->eraseFromParent(); 312 LastInst = SecondLastInst; 313 LastOpc = LastInst->getOpcode(); 314 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 315 assert(!isUncondBranchOpcode(LastOpc) && 316 "unreachable unconditional branches removed above"); 317 318 if (isCondBranchOpcode(LastOpc)) { 319 // Block ends with fall-through condbranch. 320 parseCondBranch(LastInst, TBB, Cond); 321 return false; 322 } 323 return true; // Can't handle indirect branch. 324 } else { 325 SecondLastInst = &*I; 326 SecondLastOpc = SecondLastInst->getOpcode(); 327 } 328 } 329 330 // If there are three terminators, we don't know what sort of block this is. 331 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I)) 332 return true; 333 334 // If the block ends with a B and a Bcc, handle it. 335 if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 336 parseCondBranch(SecondLastInst, TBB, Cond); 337 FBB = LastInst->getOperand(0).getMBB(); 338 return false; 339 } 340 341 // If the block ends with two unconditional branches, handle it. The second 342 // one is not executed, so remove it. 343 if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 344 TBB = SecondLastInst->getOperand(0).getMBB(); 345 I = LastInst; 346 if (AllowModify) 347 I->eraseFromParent(); 348 return false; 349 } 350 351 // ...likewise if it ends with an indirect branch followed by an unconditional 352 // branch. 353 if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 354 I = LastInst; 355 if (AllowModify) 356 I->eraseFromParent(); 357 return true; 358 } 359 360 // Otherwise, can't handle this. 361 return true; 362 } 363 364 bool AArch64InstrInfo::analyzeBranchPredicate(MachineBasicBlock &MBB, 365 MachineBranchPredicate &MBP, 366 bool AllowModify) const { 367 // For the moment, handle only a block which ends with a cb(n)zx followed by 368 // a fallthrough. Why this? Because it is a common form. 369 // TODO: Should we handle b.cc? 370 371 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 372 if (I == MBB.end()) 373 return true; 374 375 // Skip over SpeculationBarrierEndBB terminators 376 if (I->getOpcode() == AArch64::SpeculationBarrierISBDSBEndBB || 377 I->getOpcode() == AArch64::SpeculationBarrierSBEndBB) { 378 --I; 379 } 380 381 if (!isUnpredicatedTerminator(*I)) 382 return true; 383 384 // Get the last instruction in the block. 385 MachineInstr *LastInst = &*I; 386 unsigned LastOpc = LastInst->getOpcode(); 387 if (!isCondBranchOpcode(LastOpc)) 388 return true; 389 390 switch (LastOpc) { 391 default: 392 return true; 393 case AArch64::CBZW: 394 case AArch64::CBZX: 395 case AArch64::CBNZW: 396 case AArch64::CBNZX: 397 break; 398 }; 399 400 MBP.TrueDest = LastInst->getOperand(1).getMBB(); 401 assert(MBP.TrueDest && "expected!"); 402 MBP.FalseDest = MBB.getNextNode(); 403 404 MBP.ConditionDef = nullptr; 405 MBP.SingleUseCondition = false; 406 407 MBP.LHS = LastInst->getOperand(0); 408 MBP.RHS = MachineOperand::CreateImm(0); 409 MBP.Predicate = LastOpc == AArch64::CBNZX ? MachineBranchPredicate::PRED_NE 410 : MachineBranchPredicate::PRED_EQ; 411 return false; 412 } 413 414 bool AArch64InstrInfo::reverseBranchCondition( 415 SmallVectorImpl<MachineOperand> &Cond) const { 416 if (Cond[0].getImm() != -1) { 417 // Regular Bcc 418 AArch64CC::CondCode CC = (AArch64CC::CondCode)(int)Cond[0].getImm(); 419 Cond[0].setImm(AArch64CC::getInvertedCondCode(CC)); 420 } else { 421 // Folded compare-and-branch 422 switch (Cond[1].getImm()) { 423 default: 424 llvm_unreachable("Unknown conditional branch!"); 425 case AArch64::CBZW: 426 Cond[1].setImm(AArch64::CBNZW); 427 break; 428 case AArch64::CBNZW: 429 Cond[1].setImm(AArch64::CBZW); 430 break; 431 case AArch64::CBZX: 432 Cond[1].setImm(AArch64::CBNZX); 433 break; 434 case AArch64::CBNZX: 435 Cond[1].setImm(AArch64::CBZX); 436 break; 437 case AArch64::TBZW: 438 Cond[1].setImm(AArch64::TBNZW); 439 break; 440 case AArch64::TBNZW: 441 Cond[1].setImm(AArch64::TBZW); 442 break; 443 case AArch64::TBZX: 444 Cond[1].setImm(AArch64::TBNZX); 445 break; 446 case AArch64::TBNZX: 447 Cond[1].setImm(AArch64::TBZX); 448 break; 449 } 450 } 451 452 return false; 453 } 454 455 unsigned AArch64InstrInfo::removeBranch(MachineBasicBlock &MBB, 456 int *BytesRemoved) const { 457 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 458 if (I == MBB.end()) 459 return 0; 460 461 if (!isUncondBranchOpcode(I->getOpcode()) && 462 !isCondBranchOpcode(I->getOpcode())) 463 return 0; 464 465 // Remove the branch. 466 I->eraseFromParent(); 467 468 I = MBB.end(); 469 470 if (I == MBB.begin()) { 471 if (BytesRemoved) 472 *BytesRemoved = 4; 473 return 1; 474 } 475 --I; 476 if (!isCondBranchOpcode(I->getOpcode())) { 477 if (BytesRemoved) 478 *BytesRemoved = 4; 479 return 1; 480 } 481 482 // Remove the branch. 483 I->eraseFromParent(); 484 if (BytesRemoved) 485 *BytesRemoved = 8; 486 487 return 2; 488 } 489 490 void AArch64InstrInfo::instantiateCondBranch( 491 MachineBasicBlock &MBB, const DebugLoc &DL, MachineBasicBlock *TBB, 492 ArrayRef<MachineOperand> Cond) const { 493 if (Cond[0].getImm() != -1) { 494 // Regular Bcc 495 BuildMI(&MBB, DL, get(AArch64::Bcc)).addImm(Cond[0].getImm()).addMBB(TBB); 496 } else { 497 // Folded compare-and-branch 498 // Note that we use addOperand instead of addReg to keep the flags. 499 const MachineInstrBuilder MIB = 500 BuildMI(&MBB, DL, get(Cond[1].getImm())).add(Cond[2]); 501 if (Cond.size() > 3) 502 MIB.addImm(Cond[3].getImm()); 503 MIB.addMBB(TBB); 504 } 505 } 506 507 unsigned AArch64InstrInfo::insertBranch( 508 MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, 509 ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const { 510 // Shouldn't be a fall through. 511 assert(TBB && "insertBranch must not be told to insert a fallthrough"); 512 513 if (!FBB) { 514 if (Cond.empty()) // Unconditional branch? 515 BuildMI(&MBB, DL, get(AArch64::B)).addMBB(TBB); 516 else 517 instantiateCondBranch(MBB, DL, TBB, Cond); 518 519 if (BytesAdded) 520 *BytesAdded = 4; 521 522 return 1; 523 } 524 525 // Two-way conditional branch. 526 instantiateCondBranch(MBB, DL, TBB, Cond); 527 BuildMI(&MBB, DL, get(AArch64::B)).addMBB(FBB); 528 529 if (BytesAdded) 530 *BytesAdded = 8; 531 532 return 2; 533 } 534 535 // Find the original register that VReg is copied from. 536 static unsigned removeCopies(const MachineRegisterInfo &MRI, unsigned VReg) { 537 while (Register::isVirtualRegister(VReg)) { 538 const MachineInstr *DefMI = MRI.getVRegDef(VReg); 539 if (!DefMI->isFullCopy()) 540 return VReg; 541 VReg = DefMI->getOperand(1).getReg(); 542 } 543 return VReg; 544 } 545 546 // Determine if VReg is defined by an instruction that can be folded into a 547 // csel instruction. If so, return the folded opcode, and the replacement 548 // register. 549 static unsigned canFoldIntoCSel(const MachineRegisterInfo &MRI, unsigned VReg, 550 unsigned *NewVReg = nullptr) { 551 VReg = removeCopies(MRI, VReg); 552 if (!Register::isVirtualRegister(VReg)) 553 return 0; 554 555 bool Is64Bit = AArch64::GPR64allRegClass.hasSubClassEq(MRI.getRegClass(VReg)); 556 const MachineInstr *DefMI = MRI.getVRegDef(VReg); 557 unsigned Opc = 0; 558 unsigned SrcOpNum = 0; 559 switch (DefMI->getOpcode()) { 560 case AArch64::ADDSXri: 561 case AArch64::ADDSWri: 562 // if NZCV is used, do not fold. 563 if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) == -1) 564 return 0; 565 // fall-through to ADDXri and ADDWri. 566 LLVM_FALLTHROUGH; 567 case AArch64::ADDXri: 568 case AArch64::ADDWri: 569 // add x, 1 -> csinc. 570 if (!DefMI->getOperand(2).isImm() || DefMI->getOperand(2).getImm() != 1 || 571 DefMI->getOperand(3).getImm() != 0) 572 return 0; 573 SrcOpNum = 1; 574 Opc = Is64Bit ? AArch64::CSINCXr : AArch64::CSINCWr; 575 break; 576 577 case AArch64::ORNXrr: 578 case AArch64::ORNWrr: { 579 // not x -> csinv, represented as orn dst, xzr, src. 580 unsigned ZReg = removeCopies(MRI, DefMI->getOperand(1).getReg()); 581 if (ZReg != AArch64::XZR && ZReg != AArch64::WZR) 582 return 0; 583 SrcOpNum = 2; 584 Opc = Is64Bit ? AArch64::CSINVXr : AArch64::CSINVWr; 585 break; 586 } 587 588 case AArch64::SUBSXrr: 589 case AArch64::SUBSWrr: 590 // if NZCV is used, do not fold. 591 if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) == -1) 592 return 0; 593 // fall-through to SUBXrr and SUBWrr. 594 LLVM_FALLTHROUGH; 595 case AArch64::SUBXrr: 596 case AArch64::SUBWrr: { 597 // neg x -> csneg, represented as sub dst, xzr, src. 598 unsigned ZReg = removeCopies(MRI, DefMI->getOperand(1).getReg()); 599 if (ZReg != AArch64::XZR && ZReg != AArch64::WZR) 600 return 0; 601 SrcOpNum = 2; 602 Opc = Is64Bit ? AArch64::CSNEGXr : AArch64::CSNEGWr; 603 break; 604 } 605 default: 606 return 0; 607 } 608 assert(Opc && SrcOpNum && "Missing parameters"); 609 610 if (NewVReg) 611 *NewVReg = DefMI->getOperand(SrcOpNum).getReg(); 612 return Opc; 613 } 614 615 bool AArch64InstrInfo::canInsertSelect(const MachineBasicBlock &MBB, 616 ArrayRef<MachineOperand> Cond, 617 Register DstReg, Register TrueReg, 618 Register FalseReg, int &CondCycles, 619 int &TrueCycles, 620 int &FalseCycles) const { 621 // Check register classes. 622 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 623 const TargetRegisterClass *RC = 624 RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); 625 if (!RC) 626 return false; 627 628 // Also need to check the dest regclass, in case we're trying to optimize 629 // something like: 630 // %1(gpr) = PHI %2(fpr), bb1, %(fpr), bb2 631 if (!RI.getCommonSubClass(RC, MRI.getRegClass(DstReg))) 632 return false; 633 634 // Expanding cbz/tbz requires an extra cycle of latency on the condition. 635 unsigned ExtraCondLat = Cond.size() != 1; 636 637 // GPRs are handled by csel. 638 // FIXME: Fold in x+1, -x, and ~x when applicable. 639 if (AArch64::GPR64allRegClass.hasSubClassEq(RC) || 640 AArch64::GPR32allRegClass.hasSubClassEq(RC)) { 641 // Single-cycle csel, csinc, csinv, and csneg. 642 CondCycles = 1 + ExtraCondLat; 643 TrueCycles = FalseCycles = 1; 644 if (canFoldIntoCSel(MRI, TrueReg)) 645 TrueCycles = 0; 646 else if (canFoldIntoCSel(MRI, FalseReg)) 647 FalseCycles = 0; 648 return true; 649 } 650 651 // Scalar floating point is handled by fcsel. 652 // FIXME: Form fabs, fmin, and fmax when applicable. 653 if (AArch64::FPR64RegClass.hasSubClassEq(RC) || 654 AArch64::FPR32RegClass.hasSubClassEq(RC)) { 655 CondCycles = 5 + ExtraCondLat; 656 TrueCycles = FalseCycles = 2; 657 return true; 658 } 659 660 // Can't do vectors. 661 return false; 662 } 663 664 void AArch64InstrInfo::insertSelect(MachineBasicBlock &MBB, 665 MachineBasicBlock::iterator I, 666 const DebugLoc &DL, Register DstReg, 667 ArrayRef<MachineOperand> Cond, 668 Register TrueReg, Register FalseReg) const { 669 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 670 671 // Parse the condition code, see parseCondBranch() above. 672 AArch64CC::CondCode CC; 673 switch (Cond.size()) { 674 default: 675 llvm_unreachable("Unknown condition opcode in Cond"); 676 case 1: // b.cc 677 CC = AArch64CC::CondCode(Cond[0].getImm()); 678 break; 679 case 3: { // cbz/cbnz 680 // We must insert a compare against 0. 681 bool Is64Bit; 682 switch (Cond[1].getImm()) { 683 default: 684 llvm_unreachable("Unknown branch opcode in Cond"); 685 case AArch64::CBZW: 686 Is64Bit = false; 687 CC = AArch64CC::EQ; 688 break; 689 case AArch64::CBZX: 690 Is64Bit = true; 691 CC = AArch64CC::EQ; 692 break; 693 case AArch64::CBNZW: 694 Is64Bit = false; 695 CC = AArch64CC::NE; 696 break; 697 case AArch64::CBNZX: 698 Is64Bit = true; 699 CC = AArch64CC::NE; 700 break; 701 } 702 Register SrcReg = Cond[2].getReg(); 703 if (Is64Bit) { 704 // cmp reg, #0 is actually subs xzr, reg, #0. 705 MRI.constrainRegClass(SrcReg, &AArch64::GPR64spRegClass); 706 BuildMI(MBB, I, DL, get(AArch64::SUBSXri), AArch64::XZR) 707 .addReg(SrcReg) 708 .addImm(0) 709 .addImm(0); 710 } else { 711 MRI.constrainRegClass(SrcReg, &AArch64::GPR32spRegClass); 712 BuildMI(MBB, I, DL, get(AArch64::SUBSWri), AArch64::WZR) 713 .addReg(SrcReg) 714 .addImm(0) 715 .addImm(0); 716 } 717 break; 718 } 719 case 4: { // tbz/tbnz 720 // We must insert a tst instruction. 721 switch (Cond[1].getImm()) { 722 default: 723 llvm_unreachable("Unknown branch opcode in Cond"); 724 case AArch64::TBZW: 725 case AArch64::TBZX: 726 CC = AArch64CC::EQ; 727 break; 728 case AArch64::TBNZW: 729 case AArch64::TBNZX: 730 CC = AArch64CC::NE; 731 break; 732 } 733 // cmp reg, #foo is actually ands xzr, reg, #1<<foo. 734 if (Cond[1].getImm() == AArch64::TBZW || Cond[1].getImm() == AArch64::TBNZW) 735 BuildMI(MBB, I, DL, get(AArch64::ANDSWri), AArch64::WZR) 736 .addReg(Cond[2].getReg()) 737 .addImm( 738 AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 32)); 739 else 740 BuildMI(MBB, I, DL, get(AArch64::ANDSXri), AArch64::XZR) 741 .addReg(Cond[2].getReg()) 742 .addImm( 743 AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 64)); 744 break; 745 } 746 } 747 748 unsigned Opc = 0; 749 const TargetRegisterClass *RC = nullptr; 750 bool TryFold = false; 751 if (MRI.constrainRegClass(DstReg, &AArch64::GPR64RegClass)) { 752 RC = &AArch64::GPR64RegClass; 753 Opc = AArch64::CSELXr; 754 TryFold = true; 755 } else if (MRI.constrainRegClass(DstReg, &AArch64::GPR32RegClass)) { 756 RC = &AArch64::GPR32RegClass; 757 Opc = AArch64::CSELWr; 758 TryFold = true; 759 } else if (MRI.constrainRegClass(DstReg, &AArch64::FPR64RegClass)) { 760 RC = &AArch64::FPR64RegClass; 761 Opc = AArch64::FCSELDrrr; 762 } else if (MRI.constrainRegClass(DstReg, &AArch64::FPR32RegClass)) { 763 RC = &AArch64::FPR32RegClass; 764 Opc = AArch64::FCSELSrrr; 765 } 766 assert(RC && "Unsupported regclass"); 767 768 // Try folding simple instructions into the csel. 769 if (TryFold) { 770 unsigned NewVReg = 0; 771 unsigned FoldedOpc = canFoldIntoCSel(MRI, TrueReg, &NewVReg); 772 if (FoldedOpc) { 773 // The folded opcodes csinc, csinc and csneg apply the operation to 774 // FalseReg, so we need to invert the condition. 775 CC = AArch64CC::getInvertedCondCode(CC); 776 TrueReg = FalseReg; 777 } else 778 FoldedOpc = canFoldIntoCSel(MRI, FalseReg, &NewVReg); 779 780 // Fold the operation. Leave any dead instructions for DCE to clean up. 781 if (FoldedOpc) { 782 FalseReg = NewVReg; 783 Opc = FoldedOpc; 784 // The extends the live range of NewVReg. 785 MRI.clearKillFlags(NewVReg); 786 } 787 } 788 789 // Pull all virtual register into the appropriate class. 790 MRI.constrainRegClass(TrueReg, RC); 791 MRI.constrainRegClass(FalseReg, RC); 792 793 // Insert the csel. 794 BuildMI(MBB, I, DL, get(Opc), DstReg) 795 .addReg(TrueReg) 796 .addReg(FalseReg) 797 .addImm(CC); 798 } 799 800 /// Returns true if a MOVi32imm or MOVi64imm can be expanded to an ORRxx. 801 static bool canBeExpandedToORR(const MachineInstr &MI, unsigned BitSize) { 802 uint64_t Imm = MI.getOperand(1).getImm(); 803 uint64_t UImm = Imm << (64 - BitSize) >> (64 - BitSize); 804 uint64_t Encoding; 805 return AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding); 806 } 807 808 // FIXME: this implementation should be micro-architecture dependent, so a 809 // micro-architecture target hook should be introduced here in future. 810 bool AArch64InstrInfo::isAsCheapAsAMove(const MachineInstr &MI) const { 811 if (!Subtarget.hasCustomCheapAsMoveHandling()) 812 return MI.isAsCheapAsAMove(); 813 814 const unsigned Opcode = MI.getOpcode(); 815 816 // Firstly, check cases gated by features. 817 818 if (Subtarget.hasZeroCycleZeroingFP()) { 819 if (Opcode == AArch64::FMOVH0 || 820 Opcode == AArch64::FMOVS0 || 821 Opcode == AArch64::FMOVD0) 822 return true; 823 } 824 825 if (Subtarget.hasZeroCycleZeroingGP()) { 826 if (Opcode == TargetOpcode::COPY && 827 (MI.getOperand(1).getReg() == AArch64::WZR || 828 MI.getOperand(1).getReg() == AArch64::XZR)) 829 return true; 830 } 831 832 // Secondly, check cases specific to sub-targets. 833 834 if (Subtarget.hasExynosCheapAsMoveHandling()) { 835 if (isExynosCheapAsMove(MI)) 836 return true; 837 838 return MI.isAsCheapAsAMove(); 839 } 840 841 // Finally, check generic cases. 842 843 switch (Opcode) { 844 default: 845 return false; 846 847 // add/sub on register without shift 848 case AArch64::ADDWri: 849 case AArch64::ADDXri: 850 case AArch64::SUBWri: 851 case AArch64::SUBXri: 852 return (MI.getOperand(3).getImm() == 0); 853 854 // logical ops on immediate 855 case AArch64::ANDWri: 856 case AArch64::ANDXri: 857 case AArch64::EORWri: 858 case AArch64::EORXri: 859 case AArch64::ORRWri: 860 case AArch64::ORRXri: 861 return true; 862 863 // logical ops on register without shift 864 case AArch64::ANDWrr: 865 case AArch64::ANDXrr: 866 case AArch64::BICWrr: 867 case AArch64::BICXrr: 868 case AArch64::EONWrr: 869 case AArch64::EONXrr: 870 case AArch64::EORWrr: 871 case AArch64::EORXrr: 872 case AArch64::ORNWrr: 873 case AArch64::ORNXrr: 874 case AArch64::ORRWrr: 875 case AArch64::ORRXrr: 876 return true; 877 878 // If MOVi32imm or MOVi64imm can be expanded into ORRWri or 879 // ORRXri, it is as cheap as MOV 880 case AArch64::MOVi32imm: 881 return canBeExpandedToORR(MI, 32); 882 case AArch64::MOVi64imm: 883 return canBeExpandedToORR(MI, 64); 884 } 885 886 llvm_unreachable("Unknown opcode to check as cheap as a move!"); 887 } 888 889 bool AArch64InstrInfo::isFalkorShiftExtFast(const MachineInstr &MI) { 890 switch (MI.getOpcode()) { 891 default: 892 return false; 893 894 case AArch64::ADDWrs: 895 case AArch64::ADDXrs: 896 case AArch64::ADDSWrs: 897 case AArch64::ADDSXrs: { 898 unsigned Imm = MI.getOperand(3).getImm(); 899 unsigned ShiftVal = AArch64_AM::getShiftValue(Imm); 900 if (ShiftVal == 0) 901 return true; 902 return AArch64_AM::getShiftType(Imm) == AArch64_AM::LSL && ShiftVal <= 5; 903 } 904 905 case AArch64::ADDWrx: 906 case AArch64::ADDXrx: 907 case AArch64::ADDXrx64: 908 case AArch64::ADDSWrx: 909 case AArch64::ADDSXrx: 910 case AArch64::ADDSXrx64: { 911 unsigned Imm = MI.getOperand(3).getImm(); 912 switch (AArch64_AM::getArithExtendType(Imm)) { 913 default: 914 return false; 915 case AArch64_AM::UXTB: 916 case AArch64_AM::UXTH: 917 case AArch64_AM::UXTW: 918 case AArch64_AM::UXTX: 919 return AArch64_AM::getArithShiftValue(Imm) <= 4; 920 } 921 } 922 923 case AArch64::SUBWrs: 924 case AArch64::SUBSWrs: { 925 unsigned Imm = MI.getOperand(3).getImm(); 926 unsigned ShiftVal = AArch64_AM::getShiftValue(Imm); 927 return ShiftVal == 0 || 928 (AArch64_AM::getShiftType(Imm) == AArch64_AM::ASR && ShiftVal == 31); 929 } 930 931 case AArch64::SUBXrs: 932 case AArch64::SUBSXrs: { 933 unsigned Imm = MI.getOperand(3).getImm(); 934 unsigned ShiftVal = AArch64_AM::getShiftValue(Imm); 935 return ShiftVal == 0 || 936 (AArch64_AM::getShiftType(Imm) == AArch64_AM::ASR && ShiftVal == 63); 937 } 938 939 case AArch64::SUBWrx: 940 case AArch64::SUBXrx: 941 case AArch64::SUBXrx64: 942 case AArch64::SUBSWrx: 943 case AArch64::SUBSXrx: 944 case AArch64::SUBSXrx64: { 945 unsigned Imm = MI.getOperand(3).getImm(); 946 switch (AArch64_AM::getArithExtendType(Imm)) { 947 default: 948 return false; 949 case AArch64_AM::UXTB: 950 case AArch64_AM::UXTH: 951 case AArch64_AM::UXTW: 952 case AArch64_AM::UXTX: 953 return AArch64_AM::getArithShiftValue(Imm) == 0; 954 } 955 } 956 957 case AArch64::LDRBBroW: 958 case AArch64::LDRBBroX: 959 case AArch64::LDRBroW: 960 case AArch64::LDRBroX: 961 case AArch64::LDRDroW: 962 case AArch64::LDRDroX: 963 case AArch64::LDRHHroW: 964 case AArch64::LDRHHroX: 965 case AArch64::LDRHroW: 966 case AArch64::LDRHroX: 967 case AArch64::LDRQroW: 968 case AArch64::LDRQroX: 969 case AArch64::LDRSBWroW: 970 case AArch64::LDRSBWroX: 971 case AArch64::LDRSBXroW: 972 case AArch64::LDRSBXroX: 973 case AArch64::LDRSHWroW: 974 case AArch64::LDRSHWroX: 975 case AArch64::LDRSHXroW: 976 case AArch64::LDRSHXroX: 977 case AArch64::LDRSWroW: 978 case AArch64::LDRSWroX: 979 case AArch64::LDRSroW: 980 case AArch64::LDRSroX: 981 case AArch64::LDRWroW: 982 case AArch64::LDRWroX: 983 case AArch64::LDRXroW: 984 case AArch64::LDRXroX: 985 case AArch64::PRFMroW: 986 case AArch64::PRFMroX: 987 case AArch64::STRBBroW: 988 case AArch64::STRBBroX: 989 case AArch64::STRBroW: 990 case AArch64::STRBroX: 991 case AArch64::STRDroW: 992 case AArch64::STRDroX: 993 case AArch64::STRHHroW: 994 case AArch64::STRHHroX: 995 case AArch64::STRHroW: 996 case AArch64::STRHroX: 997 case AArch64::STRQroW: 998 case AArch64::STRQroX: 999 case AArch64::STRSroW: 1000 case AArch64::STRSroX: 1001 case AArch64::STRWroW: 1002 case AArch64::STRWroX: 1003 case AArch64::STRXroW: 1004 case AArch64::STRXroX: { 1005 unsigned IsSigned = MI.getOperand(3).getImm(); 1006 return !IsSigned; 1007 } 1008 } 1009 } 1010 1011 bool AArch64InstrInfo::isSEHInstruction(const MachineInstr &MI) { 1012 unsigned Opc = MI.getOpcode(); 1013 switch (Opc) { 1014 default: 1015 return false; 1016 case AArch64::SEH_StackAlloc: 1017 case AArch64::SEH_SaveFPLR: 1018 case AArch64::SEH_SaveFPLR_X: 1019 case AArch64::SEH_SaveReg: 1020 case AArch64::SEH_SaveReg_X: 1021 case AArch64::SEH_SaveRegP: 1022 case AArch64::SEH_SaveRegP_X: 1023 case AArch64::SEH_SaveFReg: 1024 case AArch64::SEH_SaveFReg_X: 1025 case AArch64::SEH_SaveFRegP: 1026 case AArch64::SEH_SaveFRegP_X: 1027 case AArch64::SEH_SetFP: 1028 case AArch64::SEH_AddFP: 1029 case AArch64::SEH_Nop: 1030 case AArch64::SEH_PrologEnd: 1031 case AArch64::SEH_EpilogStart: 1032 case AArch64::SEH_EpilogEnd: 1033 return true; 1034 } 1035 } 1036 1037 bool AArch64InstrInfo::isCoalescableExtInstr(const MachineInstr &MI, 1038 Register &SrcReg, Register &DstReg, 1039 unsigned &SubIdx) const { 1040 switch (MI.getOpcode()) { 1041 default: 1042 return false; 1043 case AArch64::SBFMXri: // aka sxtw 1044 case AArch64::UBFMXri: // aka uxtw 1045 // Check for the 32 -> 64 bit extension case, these instructions can do 1046 // much more. 1047 if (MI.getOperand(2).getImm() != 0 || MI.getOperand(3).getImm() != 31) 1048 return false; 1049 // This is a signed or unsigned 32 -> 64 bit extension. 1050 SrcReg = MI.getOperand(1).getReg(); 1051 DstReg = MI.getOperand(0).getReg(); 1052 SubIdx = AArch64::sub_32; 1053 return true; 1054 } 1055 } 1056 1057 bool AArch64InstrInfo::areMemAccessesTriviallyDisjoint( 1058 const MachineInstr &MIa, const MachineInstr &MIb) const { 1059 const TargetRegisterInfo *TRI = &getRegisterInfo(); 1060 const MachineOperand *BaseOpA = nullptr, *BaseOpB = nullptr; 1061 int64_t OffsetA = 0, OffsetB = 0; 1062 unsigned WidthA = 0, WidthB = 0; 1063 bool OffsetAIsScalable = false, OffsetBIsScalable = false; 1064 1065 assert(MIa.mayLoadOrStore() && "MIa must be a load or store."); 1066 assert(MIb.mayLoadOrStore() && "MIb must be a load or store."); 1067 1068 if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() || 1069 MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef()) 1070 return false; 1071 1072 // Retrieve the base, offset from the base and width. Width 1073 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4, 8). If 1074 // base are identical, and the offset of a lower memory access + 1075 // the width doesn't overlap the offset of a higher memory access, 1076 // then the memory accesses are different. 1077 // If OffsetAIsScalable and OffsetBIsScalable are both true, they 1078 // are assumed to have the same scale (vscale). 1079 if (getMemOperandWithOffsetWidth(MIa, BaseOpA, OffsetA, OffsetAIsScalable, 1080 WidthA, TRI) && 1081 getMemOperandWithOffsetWidth(MIb, BaseOpB, OffsetB, OffsetBIsScalable, 1082 WidthB, TRI)) { 1083 if (BaseOpA->isIdenticalTo(*BaseOpB) && 1084 OffsetAIsScalable == OffsetBIsScalable) { 1085 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB; 1086 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA; 1087 int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB; 1088 if (LowOffset + LowWidth <= HighOffset) 1089 return true; 1090 } 1091 } 1092 return false; 1093 } 1094 1095 bool AArch64InstrInfo::isSchedulingBoundary(const MachineInstr &MI, 1096 const MachineBasicBlock *MBB, 1097 const MachineFunction &MF) const { 1098 if (TargetInstrInfo::isSchedulingBoundary(MI, MBB, MF)) 1099 return true; 1100 switch (MI.getOpcode()) { 1101 case AArch64::HINT: 1102 // CSDB hints are scheduling barriers. 1103 if (MI.getOperand(0).getImm() == 0x14) 1104 return true; 1105 break; 1106 case AArch64::DSB: 1107 case AArch64::ISB: 1108 // DSB and ISB also are scheduling barriers. 1109 return true; 1110 default:; 1111 } 1112 return isSEHInstruction(MI); 1113 } 1114 1115 /// analyzeCompare - For a comparison instruction, return the source registers 1116 /// in SrcReg and SrcReg2, and the value it compares against in CmpValue. 1117 /// Return true if the comparison instruction can be analyzed. 1118 bool AArch64InstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg, 1119 Register &SrcReg2, int64_t &CmpMask, 1120 int64_t &CmpValue) const { 1121 // The first operand can be a frame index where we'd normally expect a 1122 // register. 1123 assert(MI.getNumOperands() >= 2 && "All AArch64 cmps should have 2 operands"); 1124 if (!MI.getOperand(1).isReg()) 1125 return false; 1126 1127 switch (MI.getOpcode()) { 1128 default: 1129 break; 1130 case AArch64::PTEST_PP: 1131 SrcReg = MI.getOperand(0).getReg(); 1132 SrcReg2 = MI.getOperand(1).getReg(); 1133 // Not sure about the mask and value for now... 1134 CmpMask = ~0; 1135 CmpValue = 0; 1136 return true; 1137 case AArch64::SUBSWrr: 1138 case AArch64::SUBSWrs: 1139 case AArch64::SUBSWrx: 1140 case AArch64::SUBSXrr: 1141 case AArch64::SUBSXrs: 1142 case AArch64::SUBSXrx: 1143 case AArch64::ADDSWrr: 1144 case AArch64::ADDSWrs: 1145 case AArch64::ADDSWrx: 1146 case AArch64::ADDSXrr: 1147 case AArch64::ADDSXrs: 1148 case AArch64::ADDSXrx: 1149 // Replace SUBSWrr with SUBWrr if NZCV is not used. 1150 SrcReg = MI.getOperand(1).getReg(); 1151 SrcReg2 = MI.getOperand(2).getReg(); 1152 CmpMask = ~0; 1153 CmpValue = 0; 1154 return true; 1155 case AArch64::SUBSWri: 1156 case AArch64::ADDSWri: 1157 case AArch64::SUBSXri: 1158 case AArch64::ADDSXri: 1159 SrcReg = MI.getOperand(1).getReg(); 1160 SrcReg2 = 0; 1161 CmpMask = ~0; 1162 CmpValue = MI.getOperand(2).getImm(); 1163 return true; 1164 case AArch64::ANDSWri: 1165 case AArch64::ANDSXri: 1166 // ANDS does not use the same encoding scheme as the others xxxS 1167 // instructions. 1168 SrcReg = MI.getOperand(1).getReg(); 1169 SrcReg2 = 0; 1170 CmpMask = ~0; 1171 CmpValue = AArch64_AM::decodeLogicalImmediate( 1172 MI.getOperand(2).getImm(), 1173 MI.getOpcode() == AArch64::ANDSWri ? 32 : 64); 1174 return true; 1175 } 1176 1177 return false; 1178 } 1179 1180 static bool UpdateOperandRegClass(MachineInstr &Instr) { 1181 MachineBasicBlock *MBB = Instr.getParent(); 1182 assert(MBB && "Can't get MachineBasicBlock here"); 1183 MachineFunction *MF = MBB->getParent(); 1184 assert(MF && "Can't get MachineFunction here"); 1185 const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 1186 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 1187 MachineRegisterInfo *MRI = &MF->getRegInfo(); 1188 1189 for (unsigned OpIdx = 0, EndIdx = Instr.getNumOperands(); OpIdx < EndIdx; 1190 ++OpIdx) { 1191 MachineOperand &MO = Instr.getOperand(OpIdx); 1192 const TargetRegisterClass *OpRegCstraints = 1193 Instr.getRegClassConstraint(OpIdx, TII, TRI); 1194 1195 // If there's no constraint, there's nothing to do. 1196 if (!OpRegCstraints) 1197 continue; 1198 // If the operand is a frame index, there's nothing to do here. 1199 // A frame index operand will resolve correctly during PEI. 1200 if (MO.isFI()) 1201 continue; 1202 1203 assert(MO.isReg() && 1204 "Operand has register constraints without being a register!"); 1205 1206 Register Reg = MO.getReg(); 1207 if (Register::isPhysicalRegister(Reg)) { 1208 if (!OpRegCstraints->contains(Reg)) 1209 return false; 1210 } else if (!OpRegCstraints->hasSubClassEq(MRI->getRegClass(Reg)) && 1211 !MRI->constrainRegClass(Reg, OpRegCstraints)) 1212 return false; 1213 } 1214 1215 return true; 1216 } 1217 1218 /// Return the opcode that does not set flags when possible - otherwise 1219 /// return the original opcode. The caller is responsible to do the actual 1220 /// substitution and legality checking. 1221 static unsigned convertToNonFlagSettingOpc(const MachineInstr &MI) { 1222 // Don't convert all compare instructions, because for some the zero register 1223 // encoding becomes the sp register. 1224 bool MIDefinesZeroReg = false; 1225 if (MI.definesRegister(AArch64::WZR) || MI.definesRegister(AArch64::XZR)) 1226 MIDefinesZeroReg = true; 1227 1228 switch (MI.getOpcode()) { 1229 default: 1230 return MI.getOpcode(); 1231 case AArch64::ADDSWrr: 1232 return AArch64::ADDWrr; 1233 case AArch64::ADDSWri: 1234 return MIDefinesZeroReg ? AArch64::ADDSWri : AArch64::ADDWri; 1235 case AArch64::ADDSWrs: 1236 return MIDefinesZeroReg ? AArch64::ADDSWrs : AArch64::ADDWrs; 1237 case AArch64::ADDSWrx: 1238 return AArch64::ADDWrx; 1239 case AArch64::ADDSXrr: 1240 return AArch64::ADDXrr; 1241 case AArch64::ADDSXri: 1242 return MIDefinesZeroReg ? AArch64::ADDSXri : AArch64::ADDXri; 1243 case AArch64::ADDSXrs: 1244 return MIDefinesZeroReg ? AArch64::ADDSXrs : AArch64::ADDXrs; 1245 case AArch64::ADDSXrx: 1246 return AArch64::ADDXrx; 1247 case AArch64::SUBSWrr: 1248 return AArch64::SUBWrr; 1249 case AArch64::SUBSWri: 1250 return MIDefinesZeroReg ? AArch64::SUBSWri : AArch64::SUBWri; 1251 case AArch64::SUBSWrs: 1252 return MIDefinesZeroReg ? AArch64::SUBSWrs : AArch64::SUBWrs; 1253 case AArch64::SUBSWrx: 1254 return AArch64::SUBWrx; 1255 case AArch64::SUBSXrr: 1256 return AArch64::SUBXrr; 1257 case AArch64::SUBSXri: 1258 return MIDefinesZeroReg ? AArch64::SUBSXri : AArch64::SUBXri; 1259 case AArch64::SUBSXrs: 1260 return MIDefinesZeroReg ? AArch64::SUBSXrs : AArch64::SUBXrs; 1261 case AArch64::SUBSXrx: 1262 return AArch64::SUBXrx; 1263 } 1264 } 1265 1266 enum AccessKind { AK_Write = 0x01, AK_Read = 0x10, AK_All = 0x11 }; 1267 1268 /// True when condition flags are accessed (either by writing or reading) 1269 /// on the instruction trace starting at From and ending at To. 1270 /// 1271 /// Note: If From and To are from different blocks it's assumed CC are accessed 1272 /// on the path. 1273 static bool areCFlagsAccessedBetweenInstrs( 1274 MachineBasicBlock::iterator From, MachineBasicBlock::iterator To, 1275 const TargetRegisterInfo *TRI, const AccessKind AccessToCheck = AK_All) { 1276 // Early exit if To is at the beginning of the BB. 1277 if (To == To->getParent()->begin()) 1278 return true; 1279 1280 // Check whether the instructions are in the same basic block 1281 // If not, assume the condition flags might get modified somewhere. 1282 if (To->getParent() != From->getParent()) 1283 return true; 1284 1285 // From must be above To. 1286 assert(std::any_of( 1287 ++To.getReverse(), To->getParent()->rend(), 1288 [From](MachineInstr &MI) { return MI.getIterator() == From; })); 1289 1290 // We iterate backward starting at \p To until we hit \p From. 1291 for (const MachineInstr &Instr : 1292 instructionsWithoutDebug(++To.getReverse(), From.getReverse())) { 1293 if (((AccessToCheck & AK_Write) && 1294 Instr.modifiesRegister(AArch64::NZCV, TRI)) || 1295 ((AccessToCheck & AK_Read) && Instr.readsRegister(AArch64::NZCV, TRI))) 1296 return true; 1297 } 1298 return false; 1299 } 1300 1301 /// optimizePTestInstr - Attempt to remove a ptest of a predicate-generating 1302 /// operation which could set the flags in an identical manner 1303 bool AArch64InstrInfo::optimizePTestInstr( 1304 MachineInstr *PTest, unsigned MaskReg, unsigned PredReg, 1305 const MachineRegisterInfo *MRI) const { 1306 auto *Mask = MRI->getUniqueVRegDef(MaskReg); 1307 auto *Pred = MRI->getUniqueVRegDef(PredReg); 1308 auto NewOp = Pred->getOpcode(); 1309 bool OpChanged = false; 1310 1311 unsigned MaskOpcode = Mask->getOpcode(); 1312 unsigned PredOpcode = Pred->getOpcode(); 1313 bool PredIsPTestLike = isPTestLikeOpcode(PredOpcode); 1314 bool PredIsWhileLike = isWhileOpcode(PredOpcode); 1315 1316 if (isPTrueOpcode(MaskOpcode) && (PredIsPTestLike || PredIsWhileLike)) { 1317 // For PTEST(PTRUE, OTHER_INST), PTEST is redundant when PTRUE doesn't 1318 // deactivate any lanes OTHER_INST might set. 1319 uint64_t MaskElementSize = getElementSizeForOpcode(MaskOpcode); 1320 uint64_t PredElementSize = getElementSizeForOpcode(PredOpcode); 1321 1322 // Must be an all active predicate of matching element size. 1323 if ((PredElementSize != MaskElementSize) || 1324 (Mask->getOperand(1).getImm() != 31)) 1325 return false; 1326 1327 // Fallthough to simply remove the PTEST. 1328 } else if ((Mask == Pred) && (PredIsPTestLike || PredIsWhileLike)) { 1329 // For PTEST(PG, PG), PTEST is redundant when PG is the result of an 1330 // instruction that sets the flags as PTEST would. 1331 1332 // Fallthough to simply remove the PTEST. 1333 } else if (PredIsPTestLike) { 1334 // For PTEST(PG_1, PTEST_LIKE(PG2, ...)), PTEST is redundant when both 1335 // instructions use the same predicate. 1336 auto PTestLikeMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg()); 1337 if (Mask != PTestLikeMask) 1338 return false; 1339 1340 // Fallthough to simply remove the PTEST. 1341 } else { 1342 switch (Pred->getOpcode()) { 1343 case AArch64::BRKB_PPzP: 1344 case AArch64::BRKPB_PPzPP: { 1345 // Op 0 is chain, 1 is the mask, 2 the previous predicate to 1346 // propagate, 3 the new predicate. 1347 1348 // Check to see if our mask is the same as the brkpb's. If 1349 // not the resulting flag bits may be different and we 1350 // can't remove the ptest. 1351 auto *PredMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg()); 1352 if (Mask != PredMask) 1353 return false; 1354 1355 // Switch to the new opcode 1356 NewOp = Pred->getOpcode() == AArch64::BRKB_PPzP ? AArch64::BRKBS_PPzP 1357 : AArch64::BRKPBS_PPzPP; 1358 OpChanged = true; 1359 break; 1360 } 1361 case AArch64::BRKN_PPzP: { 1362 auto *PredMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg()); 1363 if (Mask != PredMask) 1364 return false; 1365 1366 NewOp = AArch64::BRKNS_PPzP; 1367 OpChanged = true; 1368 break; 1369 } 1370 case AArch64::RDFFR_PPz: { 1371 // rdffr p1.b, PredMask=p0/z <--- Definition of Pred 1372 // ptest Mask=p0, Pred=p1.b <--- If equal masks, remove this and use 1373 // `rdffrs p1.b, p0/z` above. 1374 auto *PredMask = MRI->getUniqueVRegDef(Pred->getOperand(1).getReg()); 1375 if (Mask != PredMask) 1376 return false; 1377 1378 NewOp = AArch64::RDFFRS_PPz; 1379 OpChanged = true; 1380 break; 1381 } 1382 default: 1383 // Bail out if we don't recognize the input 1384 return false; 1385 } 1386 } 1387 1388 const TargetRegisterInfo *TRI = &getRegisterInfo(); 1389 1390 // If another instruction between Pred and PTest accesses flags, don't remove 1391 // the ptest or update the earlier instruction to modify them. 1392 if (areCFlagsAccessedBetweenInstrs(Pred, PTest, TRI)) 1393 return false; 1394 1395 // If we pass all the checks, it's safe to remove the PTEST and use the flags 1396 // as they are prior to PTEST. Sometimes this requires the tested PTEST 1397 // operand to be replaced with an equivalent instruction that also sets the 1398 // flags. 1399 Pred->setDesc(get(NewOp)); 1400 PTest->eraseFromParent(); 1401 if (OpChanged) { 1402 bool succeeded = UpdateOperandRegClass(*Pred); 1403 (void)succeeded; 1404 assert(succeeded && "Operands have incompatible register classes!"); 1405 Pred->addRegisterDefined(AArch64::NZCV, TRI); 1406 } 1407 1408 // Ensure that the flags def is live. 1409 if (Pred->registerDefIsDead(AArch64::NZCV, TRI)) { 1410 unsigned i = 0, e = Pred->getNumOperands(); 1411 for (; i != e; ++i) { 1412 MachineOperand &MO = Pred->getOperand(i); 1413 if (MO.isReg() && MO.isDef() && MO.getReg() == AArch64::NZCV) { 1414 MO.setIsDead(false); 1415 break; 1416 } 1417 } 1418 } 1419 return true; 1420 } 1421 1422 /// Try to optimize a compare instruction. A compare instruction is an 1423 /// instruction which produces AArch64::NZCV. It can be truly compare 1424 /// instruction 1425 /// when there are no uses of its destination register. 1426 /// 1427 /// The following steps are tried in order: 1428 /// 1. Convert CmpInstr into an unconditional version. 1429 /// 2. Remove CmpInstr if above there is an instruction producing a needed 1430 /// condition code or an instruction which can be converted into such an 1431 /// instruction. 1432 /// Only comparison with zero is supported. 1433 bool AArch64InstrInfo::optimizeCompareInstr( 1434 MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask, 1435 int64_t CmpValue, const MachineRegisterInfo *MRI) const { 1436 assert(CmpInstr.getParent()); 1437 assert(MRI); 1438 1439 // Replace SUBSWrr with SUBWrr if NZCV is not used. 1440 int DeadNZCVIdx = CmpInstr.findRegisterDefOperandIdx(AArch64::NZCV, true); 1441 if (DeadNZCVIdx != -1) { 1442 if (CmpInstr.definesRegister(AArch64::WZR) || 1443 CmpInstr.definesRegister(AArch64::XZR)) { 1444 CmpInstr.eraseFromParent(); 1445 return true; 1446 } 1447 unsigned Opc = CmpInstr.getOpcode(); 1448 unsigned NewOpc = convertToNonFlagSettingOpc(CmpInstr); 1449 if (NewOpc == Opc) 1450 return false; 1451 const MCInstrDesc &MCID = get(NewOpc); 1452 CmpInstr.setDesc(MCID); 1453 CmpInstr.RemoveOperand(DeadNZCVIdx); 1454 bool succeeded = UpdateOperandRegClass(CmpInstr); 1455 (void)succeeded; 1456 assert(succeeded && "Some operands reg class are incompatible!"); 1457 return true; 1458 } 1459 1460 if (CmpInstr.getOpcode() == AArch64::PTEST_PP) 1461 return optimizePTestInstr(&CmpInstr, SrcReg, SrcReg2, MRI); 1462 1463 if (SrcReg2 != 0) 1464 return false; 1465 1466 // CmpInstr is a Compare instruction if destination register is not used. 1467 if (!MRI->use_nodbg_empty(CmpInstr.getOperand(0).getReg())) 1468 return false; 1469 1470 if (CmpValue == 0 && substituteCmpToZero(CmpInstr, SrcReg, *MRI)) 1471 return true; 1472 return (CmpValue == 0 || CmpValue == 1) && 1473 removeCmpToZeroOrOne(CmpInstr, SrcReg, CmpValue, *MRI); 1474 } 1475 1476 /// Get opcode of S version of Instr. 1477 /// If Instr is S version its opcode is returned. 1478 /// AArch64::INSTRUCTION_LIST_END is returned if Instr does not have S version 1479 /// or we are not interested in it. 1480 static unsigned sForm(MachineInstr &Instr) { 1481 switch (Instr.getOpcode()) { 1482 default: 1483 return AArch64::INSTRUCTION_LIST_END; 1484 1485 case AArch64::ADDSWrr: 1486 case AArch64::ADDSWri: 1487 case AArch64::ADDSXrr: 1488 case AArch64::ADDSXri: 1489 case AArch64::SUBSWrr: 1490 case AArch64::SUBSWri: 1491 case AArch64::SUBSXrr: 1492 case AArch64::SUBSXri: 1493 return Instr.getOpcode(); 1494 1495 case AArch64::ADDWrr: 1496 return AArch64::ADDSWrr; 1497 case AArch64::ADDWri: 1498 return AArch64::ADDSWri; 1499 case AArch64::ADDXrr: 1500 return AArch64::ADDSXrr; 1501 case AArch64::ADDXri: 1502 return AArch64::ADDSXri; 1503 case AArch64::ADCWr: 1504 return AArch64::ADCSWr; 1505 case AArch64::ADCXr: 1506 return AArch64::ADCSXr; 1507 case AArch64::SUBWrr: 1508 return AArch64::SUBSWrr; 1509 case AArch64::SUBWri: 1510 return AArch64::SUBSWri; 1511 case AArch64::SUBXrr: 1512 return AArch64::SUBSXrr; 1513 case AArch64::SUBXri: 1514 return AArch64::SUBSXri; 1515 case AArch64::SBCWr: 1516 return AArch64::SBCSWr; 1517 case AArch64::SBCXr: 1518 return AArch64::SBCSXr; 1519 case AArch64::ANDWri: 1520 return AArch64::ANDSWri; 1521 case AArch64::ANDXri: 1522 return AArch64::ANDSXri; 1523 } 1524 } 1525 1526 /// Check if AArch64::NZCV should be alive in successors of MBB. 1527 static bool areCFlagsAliveInSuccessors(const MachineBasicBlock *MBB) { 1528 for (auto *BB : MBB->successors()) 1529 if (BB->isLiveIn(AArch64::NZCV)) 1530 return true; 1531 return false; 1532 } 1533 1534 /// \returns The condition code operand index for \p Instr if it is a branch 1535 /// or select and -1 otherwise. 1536 static int 1537 findCondCodeUseOperandIdxForBranchOrSelect(const MachineInstr &Instr) { 1538 switch (Instr.getOpcode()) { 1539 default: 1540 return -1; 1541 1542 case AArch64::Bcc: { 1543 int Idx = Instr.findRegisterUseOperandIdx(AArch64::NZCV); 1544 assert(Idx >= 2); 1545 return Idx - 2; 1546 } 1547 1548 case AArch64::CSINVWr: 1549 case AArch64::CSINVXr: 1550 case AArch64::CSINCWr: 1551 case AArch64::CSINCXr: 1552 case AArch64::CSELWr: 1553 case AArch64::CSELXr: 1554 case AArch64::CSNEGWr: 1555 case AArch64::CSNEGXr: 1556 case AArch64::FCSELSrrr: 1557 case AArch64::FCSELDrrr: { 1558 int Idx = Instr.findRegisterUseOperandIdx(AArch64::NZCV); 1559 assert(Idx >= 1); 1560 return Idx - 1; 1561 } 1562 } 1563 } 1564 1565 namespace { 1566 1567 struct UsedNZCV { 1568 bool N = false; 1569 bool Z = false; 1570 bool C = false; 1571 bool V = false; 1572 1573 UsedNZCV() = default; 1574 1575 UsedNZCV &operator|=(const UsedNZCV &UsedFlags) { 1576 this->N |= UsedFlags.N; 1577 this->Z |= UsedFlags.Z; 1578 this->C |= UsedFlags.C; 1579 this->V |= UsedFlags.V; 1580 return *this; 1581 } 1582 }; 1583 1584 } // end anonymous namespace 1585 1586 /// Find a condition code used by the instruction. 1587 /// Returns AArch64CC::Invalid if either the instruction does not use condition 1588 /// codes or we don't optimize CmpInstr in the presence of such instructions. 1589 static AArch64CC::CondCode findCondCodeUsedByInstr(const MachineInstr &Instr) { 1590 int CCIdx = findCondCodeUseOperandIdxForBranchOrSelect(Instr); 1591 return CCIdx >= 0 ? static_cast<AArch64CC::CondCode>( 1592 Instr.getOperand(CCIdx).getImm()) 1593 : AArch64CC::Invalid; 1594 } 1595 1596 static UsedNZCV getUsedNZCV(AArch64CC::CondCode CC) { 1597 assert(CC != AArch64CC::Invalid); 1598 UsedNZCV UsedFlags; 1599 switch (CC) { 1600 default: 1601 break; 1602 1603 case AArch64CC::EQ: // Z set 1604 case AArch64CC::NE: // Z clear 1605 UsedFlags.Z = true; 1606 break; 1607 1608 case AArch64CC::HI: // Z clear and C set 1609 case AArch64CC::LS: // Z set or C clear 1610 UsedFlags.Z = true; 1611 LLVM_FALLTHROUGH; 1612 case AArch64CC::HS: // C set 1613 case AArch64CC::LO: // C clear 1614 UsedFlags.C = true; 1615 break; 1616 1617 case AArch64CC::MI: // N set 1618 case AArch64CC::PL: // N clear 1619 UsedFlags.N = true; 1620 break; 1621 1622 case AArch64CC::VS: // V set 1623 case AArch64CC::VC: // V clear 1624 UsedFlags.V = true; 1625 break; 1626 1627 case AArch64CC::GT: // Z clear, N and V the same 1628 case AArch64CC::LE: // Z set, N and V differ 1629 UsedFlags.Z = true; 1630 LLVM_FALLTHROUGH; 1631 case AArch64CC::GE: // N and V the same 1632 case AArch64CC::LT: // N and V differ 1633 UsedFlags.N = true; 1634 UsedFlags.V = true; 1635 break; 1636 } 1637 return UsedFlags; 1638 } 1639 1640 /// \returns Conditions flags used after \p CmpInstr in its MachineBB if they 1641 /// are not containing C or V flags and NZCV flags are not alive in successors 1642 /// of the same \p CmpInstr and \p MI parent. \returns None otherwise. 1643 /// 1644 /// Collect instructions using that flags in \p CCUseInstrs if provided. 1645 static Optional<UsedNZCV> 1646 examineCFlagsUse(MachineInstr &MI, MachineInstr &CmpInstr, 1647 const TargetRegisterInfo &TRI, 1648 SmallVectorImpl<MachineInstr *> *CCUseInstrs = nullptr) { 1649 MachineBasicBlock *CmpParent = CmpInstr.getParent(); 1650 if (MI.getParent() != CmpParent) 1651 return None; 1652 1653 if (areCFlagsAliveInSuccessors(CmpParent)) 1654 return None; 1655 1656 UsedNZCV NZCVUsedAfterCmp; 1657 for (MachineInstr &Instr : instructionsWithoutDebug( 1658 std::next(CmpInstr.getIterator()), CmpParent->instr_end())) { 1659 if (Instr.readsRegister(AArch64::NZCV, &TRI)) { 1660 AArch64CC::CondCode CC = findCondCodeUsedByInstr(Instr); 1661 if (CC == AArch64CC::Invalid) // Unsupported conditional instruction 1662 return None; 1663 NZCVUsedAfterCmp |= getUsedNZCV(CC); 1664 if (CCUseInstrs) 1665 CCUseInstrs->push_back(&Instr); 1666 } 1667 if (Instr.modifiesRegister(AArch64::NZCV, &TRI)) 1668 break; 1669 } 1670 if (NZCVUsedAfterCmp.C || NZCVUsedAfterCmp.V) 1671 return None; 1672 return NZCVUsedAfterCmp; 1673 } 1674 1675 static bool isADDSRegImm(unsigned Opcode) { 1676 return Opcode == AArch64::ADDSWri || Opcode == AArch64::ADDSXri; 1677 } 1678 1679 static bool isSUBSRegImm(unsigned Opcode) { 1680 return Opcode == AArch64::SUBSWri || Opcode == AArch64::SUBSXri; 1681 } 1682 1683 /// Check if CmpInstr can be substituted by MI. 1684 /// 1685 /// CmpInstr can be substituted: 1686 /// - CmpInstr is either 'ADDS %vreg, 0' or 'SUBS %vreg, 0' 1687 /// - and, MI and CmpInstr are from the same MachineBB 1688 /// - and, condition flags are not alive in successors of the CmpInstr parent 1689 /// - and, if MI opcode is the S form there must be no defs of flags between 1690 /// MI and CmpInstr 1691 /// or if MI opcode is not the S form there must be neither defs of flags 1692 /// nor uses of flags between MI and CmpInstr. 1693 /// - and C/V flags are not used after CmpInstr 1694 static bool canInstrSubstituteCmpInstr(MachineInstr &MI, MachineInstr &CmpInstr, 1695 const TargetRegisterInfo &TRI) { 1696 assert(sForm(MI) != AArch64::INSTRUCTION_LIST_END); 1697 1698 const unsigned CmpOpcode = CmpInstr.getOpcode(); 1699 if (!isADDSRegImm(CmpOpcode) && !isSUBSRegImm(CmpOpcode)) 1700 return false; 1701 1702 if (!examineCFlagsUse(MI, CmpInstr, TRI)) 1703 return false; 1704 1705 AccessKind AccessToCheck = AK_Write; 1706 if (sForm(MI) != MI.getOpcode()) 1707 AccessToCheck = AK_All; 1708 return !areCFlagsAccessedBetweenInstrs(&MI, &CmpInstr, &TRI, AccessToCheck); 1709 } 1710 1711 /// Substitute an instruction comparing to zero with another instruction 1712 /// which produces needed condition flags. 1713 /// 1714 /// Return true on success. 1715 bool AArch64InstrInfo::substituteCmpToZero( 1716 MachineInstr &CmpInstr, unsigned SrcReg, 1717 const MachineRegisterInfo &MRI) const { 1718 // Get the unique definition of SrcReg. 1719 MachineInstr *MI = MRI.getUniqueVRegDef(SrcReg); 1720 if (!MI) 1721 return false; 1722 1723 const TargetRegisterInfo &TRI = getRegisterInfo(); 1724 1725 unsigned NewOpc = sForm(*MI); 1726 if (NewOpc == AArch64::INSTRUCTION_LIST_END) 1727 return false; 1728 1729 if (!canInstrSubstituteCmpInstr(*MI, CmpInstr, TRI)) 1730 return false; 1731 1732 // Update the instruction to set NZCV. 1733 MI->setDesc(get(NewOpc)); 1734 CmpInstr.eraseFromParent(); 1735 bool succeeded = UpdateOperandRegClass(*MI); 1736 (void)succeeded; 1737 assert(succeeded && "Some operands reg class are incompatible!"); 1738 MI->addRegisterDefined(AArch64::NZCV, &TRI); 1739 return true; 1740 } 1741 1742 /// \returns True if \p CmpInstr can be removed. 1743 /// 1744 /// \p IsInvertCC is true if, after removing \p CmpInstr, condition 1745 /// codes used in \p CCUseInstrs must be inverted. 1746 static bool canCmpInstrBeRemoved(MachineInstr &MI, MachineInstr &CmpInstr, 1747 int CmpValue, const TargetRegisterInfo &TRI, 1748 SmallVectorImpl<MachineInstr *> &CCUseInstrs, 1749 bool &IsInvertCC) { 1750 assert((CmpValue == 0 || CmpValue == 1) && 1751 "Only comparisons to 0 or 1 considered for removal!"); 1752 1753 // MI is 'CSINCWr %vreg, wzr, wzr, <cc>' or 'CSINCXr %vreg, xzr, xzr, <cc>' 1754 unsigned MIOpc = MI.getOpcode(); 1755 if (MIOpc == AArch64::CSINCWr) { 1756 if (MI.getOperand(1).getReg() != AArch64::WZR || 1757 MI.getOperand(2).getReg() != AArch64::WZR) 1758 return false; 1759 } else if (MIOpc == AArch64::CSINCXr) { 1760 if (MI.getOperand(1).getReg() != AArch64::XZR || 1761 MI.getOperand(2).getReg() != AArch64::XZR) 1762 return false; 1763 } else { 1764 return false; 1765 } 1766 AArch64CC::CondCode MICC = findCondCodeUsedByInstr(MI); 1767 if (MICC == AArch64CC::Invalid) 1768 return false; 1769 1770 // NZCV needs to be defined 1771 if (MI.findRegisterDefOperandIdx(AArch64::NZCV, true) != -1) 1772 return false; 1773 1774 // CmpInstr is 'ADDS %vreg, 0' or 'SUBS %vreg, 0' or 'SUBS %vreg, 1' 1775 const unsigned CmpOpcode = CmpInstr.getOpcode(); 1776 bool IsSubsRegImm = isSUBSRegImm(CmpOpcode); 1777 if (CmpValue && !IsSubsRegImm) 1778 return false; 1779 if (!CmpValue && !IsSubsRegImm && !isADDSRegImm(CmpOpcode)) 1780 return false; 1781 1782 // MI conditions allowed: eq, ne, mi, pl 1783 UsedNZCV MIUsedNZCV = getUsedNZCV(MICC); 1784 if (MIUsedNZCV.C || MIUsedNZCV.V) 1785 return false; 1786 1787 Optional<UsedNZCV> NZCVUsedAfterCmp = 1788 examineCFlagsUse(MI, CmpInstr, TRI, &CCUseInstrs); 1789 // Condition flags are not used in CmpInstr basic block successors and only 1790 // Z or N flags allowed to be used after CmpInstr within its basic block 1791 if (!NZCVUsedAfterCmp) 1792 return false; 1793 // Z or N flag used after CmpInstr must correspond to the flag used in MI 1794 if ((MIUsedNZCV.Z && NZCVUsedAfterCmp->N) || 1795 (MIUsedNZCV.N && NZCVUsedAfterCmp->Z)) 1796 return false; 1797 // If CmpInstr is comparison to zero MI conditions are limited to eq, ne 1798 if (MIUsedNZCV.N && !CmpValue) 1799 return false; 1800 1801 // There must be no defs of flags between MI and CmpInstr 1802 if (areCFlagsAccessedBetweenInstrs(&MI, &CmpInstr, &TRI, AK_Write)) 1803 return false; 1804 1805 // Condition code is inverted in the following cases: 1806 // 1. MI condition is ne; CmpInstr is 'ADDS %vreg, 0' or 'SUBS %vreg, 0' 1807 // 2. MI condition is eq, pl; CmpInstr is 'SUBS %vreg, 1' 1808 IsInvertCC = (CmpValue && (MICC == AArch64CC::EQ || MICC == AArch64CC::PL)) || 1809 (!CmpValue && MICC == AArch64CC::NE); 1810 return true; 1811 } 1812 1813 /// Remove comparision in csinc-cmp sequence 1814 /// 1815 /// Examples: 1816 /// 1. \code 1817 /// csinc w9, wzr, wzr, ne 1818 /// cmp w9, #0 1819 /// b.eq 1820 /// \endcode 1821 /// to 1822 /// \code 1823 /// csinc w9, wzr, wzr, ne 1824 /// b.ne 1825 /// \endcode 1826 /// 1827 /// 2. \code 1828 /// csinc x2, xzr, xzr, mi 1829 /// cmp x2, #1 1830 /// b.pl 1831 /// \endcode 1832 /// to 1833 /// \code 1834 /// csinc x2, xzr, xzr, mi 1835 /// b.pl 1836 /// \endcode 1837 /// 1838 /// \param CmpInstr comparison instruction 1839 /// \return True when comparison removed 1840 bool AArch64InstrInfo::removeCmpToZeroOrOne( 1841 MachineInstr &CmpInstr, unsigned SrcReg, int CmpValue, 1842 const MachineRegisterInfo &MRI) const { 1843 MachineInstr *MI = MRI.getUniqueVRegDef(SrcReg); 1844 if (!MI) 1845 return false; 1846 const TargetRegisterInfo &TRI = getRegisterInfo(); 1847 SmallVector<MachineInstr *, 4> CCUseInstrs; 1848 bool IsInvertCC = false; 1849 if (!canCmpInstrBeRemoved(*MI, CmpInstr, CmpValue, TRI, CCUseInstrs, 1850 IsInvertCC)) 1851 return false; 1852 // Make transformation 1853 CmpInstr.eraseFromParent(); 1854 if (IsInvertCC) { 1855 // Invert condition codes in CmpInstr CC users 1856 for (MachineInstr *CCUseInstr : CCUseInstrs) { 1857 int Idx = findCondCodeUseOperandIdxForBranchOrSelect(*CCUseInstr); 1858 assert(Idx >= 0 && "Unexpected instruction using CC."); 1859 MachineOperand &CCOperand = CCUseInstr->getOperand(Idx); 1860 AArch64CC::CondCode CCUse = AArch64CC::getInvertedCondCode( 1861 static_cast<AArch64CC::CondCode>(CCOperand.getImm())); 1862 CCOperand.setImm(CCUse); 1863 } 1864 } 1865 return true; 1866 } 1867 1868 bool AArch64InstrInfo::expandPostRAPseudo(MachineInstr &MI) const { 1869 if (MI.getOpcode() != TargetOpcode::LOAD_STACK_GUARD && 1870 MI.getOpcode() != AArch64::CATCHRET) 1871 return false; 1872 1873 MachineBasicBlock &MBB = *MI.getParent(); 1874 auto &Subtarget = MBB.getParent()->getSubtarget<AArch64Subtarget>(); 1875 auto TRI = Subtarget.getRegisterInfo(); 1876 DebugLoc DL = MI.getDebugLoc(); 1877 1878 if (MI.getOpcode() == AArch64::CATCHRET) { 1879 // Skip to the first instruction before the epilog. 1880 const TargetInstrInfo *TII = 1881 MBB.getParent()->getSubtarget().getInstrInfo(); 1882 MachineBasicBlock *TargetMBB = MI.getOperand(0).getMBB(); 1883 auto MBBI = MachineBasicBlock::iterator(MI); 1884 MachineBasicBlock::iterator FirstEpilogSEH = std::prev(MBBI); 1885 while (FirstEpilogSEH->getFlag(MachineInstr::FrameDestroy) && 1886 FirstEpilogSEH != MBB.begin()) 1887 FirstEpilogSEH = std::prev(FirstEpilogSEH); 1888 if (FirstEpilogSEH != MBB.begin()) 1889 FirstEpilogSEH = std::next(FirstEpilogSEH); 1890 BuildMI(MBB, FirstEpilogSEH, DL, TII->get(AArch64::ADRP)) 1891 .addReg(AArch64::X0, RegState::Define) 1892 .addMBB(TargetMBB); 1893 BuildMI(MBB, FirstEpilogSEH, DL, TII->get(AArch64::ADDXri)) 1894 .addReg(AArch64::X0, RegState::Define) 1895 .addReg(AArch64::X0) 1896 .addMBB(TargetMBB) 1897 .addImm(0); 1898 return true; 1899 } 1900 1901 Register Reg = MI.getOperand(0).getReg(); 1902 Module &M = *MBB.getParent()->getFunction().getParent(); 1903 if (M.getStackProtectorGuard() == "sysreg") { 1904 const AArch64SysReg::SysReg *SrcReg = 1905 AArch64SysReg::lookupSysRegByName(M.getStackProtectorGuardReg()); 1906 if (!SrcReg) 1907 report_fatal_error("Unknown SysReg for Stack Protector Guard Register"); 1908 1909 // mrs xN, sysreg 1910 BuildMI(MBB, MI, DL, get(AArch64::MRS)) 1911 .addDef(Reg, RegState::Renamable) 1912 .addImm(SrcReg->Encoding); 1913 int Offset = M.getStackProtectorGuardOffset(); 1914 if (Offset >= 0 && Offset <= 32760 && Offset % 8 == 0) { 1915 // ldr xN, [xN, #offset] 1916 BuildMI(MBB, MI, DL, get(AArch64::LDRXui)) 1917 .addDef(Reg) 1918 .addUse(Reg, RegState::Kill) 1919 .addImm(Offset / 8); 1920 } else if (Offset >= -256 && Offset <= 255) { 1921 // ldur xN, [xN, #offset] 1922 BuildMI(MBB, MI, DL, get(AArch64::LDURXi)) 1923 .addDef(Reg) 1924 .addUse(Reg, RegState::Kill) 1925 .addImm(Offset); 1926 } else if (Offset >= -4095 && Offset <= 4095) { 1927 if (Offset > 0) { 1928 // add xN, xN, #offset 1929 BuildMI(MBB, MI, DL, get(AArch64::ADDXri)) 1930 .addDef(Reg) 1931 .addUse(Reg, RegState::Kill) 1932 .addImm(Offset) 1933 .addImm(0); 1934 } else { 1935 // sub xN, xN, #offset 1936 BuildMI(MBB, MI, DL, get(AArch64::SUBXri)) 1937 .addDef(Reg) 1938 .addUse(Reg, RegState::Kill) 1939 .addImm(-Offset) 1940 .addImm(0); 1941 } 1942 // ldr xN, [xN] 1943 BuildMI(MBB, MI, DL, get(AArch64::LDRXui)) 1944 .addDef(Reg) 1945 .addUse(Reg, RegState::Kill) 1946 .addImm(0); 1947 } else { 1948 // Cases that are larger than +/- 4095 and not a multiple of 8, or larger 1949 // than 23760. 1950 // It might be nice to use AArch64::MOVi32imm here, which would get 1951 // expanded in PreSched2 after PostRA, but our lone scratch Reg already 1952 // contains the MRS result. findScratchNonCalleeSaveRegister() in 1953 // AArch64FrameLowering might help us find such a scratch register 1954 // though. If we failed to find a scratch register, we could emit a 1955 // stream of add instructions to build up the immediate. Or, we could try 1956 // to insert a AArch64::MOVi32imm before register allocation so that we 1957 // didn't need to scavenge for a scratch register. 1958 report_fatal_error("Unable to encode Stack Protector Guard Offset"); 1959 } 1960 MBB.erase(MI); 1961 return true; 1962 } 1963 1964 const GlobalValue *GV = 1965 cast<GlobalValue>((*MI.memoperands_begin())->getValue()); 1966 const TargetMachine &TM = MBB.getParent()->getTarget(); 1967 unsigned OpFlags = Subtarget.ClassifyGlobalReference(GV, TM); 1968 const unsigned char MO_NC = AArch64II::MO_NC; 1969 1970 if ((OpFlags & AArch64II::MO_GOT) != 0) { 1971 BuildMI(MBB, MI, DL, get(AArch64::LOADgot), Reg) 1972 .addGlobalAddress(GV, 0, OpFlags); 1973 if (Subtarget.isTargetILP32()) { 1974 unsigned Reg32 = TRI->getSubReg(Reg, AArch64::sub_32); 1975 BuildMI(MBB, MI, DL, get(AArch64::LDRWui)) 1976 .addDef(Reg32, RegState::Dead) 1977 .addUse(Reg, RegState::Kill) 1978 .addImm(0) 1979 .addMemOperand(*MI.memoperands_begin()) 1980 .addDef(Reg, RegState::Implicit); 1981 } else { 1982 BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg) 1983 .addReg(Reg, RegState::Kill) 1984 .addImm(0) 1985 .addMemOperand(*MI.memoperands_begin()); 1986 } 1987 } else if (TM.getCodeModel() == CodeModel::Large) { 1988 assert(!Subtarget.isTargetILP32() && "how can large exist in ILP32?"); 1989 BuildMI(MBB, MI, DL, get(AArch64::MOVZXi), Reg) 1990 .addGlobalAddress(GV, 0, AArch64II::MO_G0 | MO_NC) 1991 .addImm(0); 1992 BuildMI(MBB, MI, DL, get(AArch64::MOVKXi), Reg) 1993 .addReg(Reg, RegState::Kill) 1994 .addGlobalAddress(GV, 0, AArch64II::MO_G1 | MO_NC) 1995 .addImm(16); 1996 BuildMI(MBB, MI, DL, get(AArch64::MOVKXi), Reg) 1997 .addReg(Reg, RegState::Kill) 1998 .addGlobalAddress(GV, 0, AArch64II::MO_G2 | MO_NC) 1999 .addImm(32); 2000 BuildMI(MBB, MI, DL, get(AArch64::MOVKXi), Reg) 2001 .addReg(Reg, RegState::Kill) 2002 .addGlobalAddress(GV, 0, AArch64II::MO_G3) 2003 .addImm(48); 2004 BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg) 2005 .addReg(Reg, RegState::Kill) 2006 .addImm(0) 2007 .addMemOperand(*MI.memoperands_begin()); 2008 } else if (TM.getCodeModel() == CodeModel::Tiny) { 2009 BuildMI(MBB, MI, DL, get(AArch64::ADR), Reg) 2010 .addGlobalAddress(GV, 0, OpFlags); 2011 } else { 2012 BuildMI(MBB, MI, DL, get(AArch64::ADRP), Reg) 2013 .addGlobalAddress(GV, 0, OpFlags | AArch64II::MO_PAGE); 2014 unsigned char LoFlags = OpFlags | AArch64II::MO_PAGEOFF | MO_NC; 2015 if (Subtarget.isTargetILP32()) { 2016 unsigned Reg32 = TRI->getSubReg(Reg, AArch64::sub_32); 2017 BuildMI(MBB, MI, DL, get(AArch64::LDRWui)) 2018 .addDef(Reg32, RegState::Dead) 2019 .addUse(Reg, RegState::Kill) 2020 .addGlobalAddress(GV, 0, LoFlags) 2021 .addMemOperand(*MI.memoperands_begin()) 2022 .addDef(Reg, RegState::Implicit); 2023 } else { 2024 BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg) 2025 .addReg(Reg, RegState::Kill) 2026 .addGlobalAddress(GV, 0, LoFlags) 2027 .addMemOperand(*MI.memoperands_begin()); 2028 } 2029 } 2030 2031 MBB.erase(MI); 2032 2033 return true; 2034 } 2035 2036 // Return true if this instruction simply sets its single destination register 2037 // to zero. This is equivalent to a register rename of the zero-register. 2038 bool AArch64InstrInfo::isGPRZero(const MachineInstr &MI) { 2039 switch (MI.getOpcode()) { 2040 default: 2041 break; 2042 case AArch64::MOVZWi: 2043 case AArch64::MOVZXi: // movz Rd, #0 (LSL #0) 2044 if (MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) { 2045 assert(MI.getDesc().getNumOperands() == 3 && 2046 MI.getOperand(2).getImm() == 0 && "invalid MOVZi operands"); 2047 return true; 2048 } 2049 break; 2050 case AArch64::ANDWri: // and Rd, Rzr, #imm 2051 return MI.getOperand(1).getReg() == AArch64::WZR; 2052 case AArch64::ANDXri: 2053 return MI.getOperand(1).getReg() == AArch64::XZR; 2054 case TargetOpcode::COPY: 2055 return MI.getOperand(1).getReg() == AArch64::WZR; 2056 } 2057 return false; 2058 } 2059 2060 // Return true if this instruction simply renames a general register without 2061 // modifying bits. 2062 bool AArch64InstrInfo::isGPRCopy(const MachineInstr &MI) { 2063 switch (MI.getOpcode()) { 2064 default: 2065 break; 2066 case TargetOpcode::COPY: { 2067 // GPR32 copies will by lowered to ORRXrs 2068 Register DstReg = MI.getOperand(0).getReg(); 2069 return (AArch64::GPR32RegClass.contains(DstReg) || 2070 AArch64::GPR64RegClass.contains(DstReg)); 2071 } 2072 case AArch64::ORRXrs: // orr Xd, Xzr, Xm (LSL #0) 2073 if (MI.getOperand(1).getReg() == AArch64::XZR) { 2074 assert(MI.getDesc().getNumOperands() == 4 && 2075 MI.getOperand(3).getImm() == 0 && "invalid ORRrs operands"); 2076 return true; 2077 } 2078 break; 2079 case AArch64::ADDXri: // add Xd, Xn, #0 (LSL #0) 2080 if (MI.getOperand(2).getImm() == 0) { 2081 assert(MI.getDesc().getNumOperands() == 4 && 2082 MI.getOperand(3).getImm() == 0 && "invalid ADDXri operands"); 2083 return true; 2084 } 2085 break; 2086 } 2087 return false; 2088 } 2089 2090 // Return true if this instruction simply renames a general register without 2091 // modifying bits. 2092 bool AArch64InstrInfo::isFPRCopy(const MachineInstr &MI) { 2093 switch (MI.getOpcode()) { 2094 default: 2095 break; 2096 case TargetOpcode::COPY: { 2097 Register DstReg = MI.getOperand(0).getReg(); 2098 return AArch64::FPR128RegClass.contains(DstReg); 2099 } 2100 case AArch64::ORRv16i8: 2101 if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) { 2102 assert(MI.getDesc().getNumOperands() == 3 && MI.getOperand(0).isReg() && 2103 "invalid ORRv16i8 operands"); 2104 return true; 2105 } 2106 break; 2107 } 2108 return false; 2109 } 2110 2111 unsigned AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr &MI, 2112 int &FrameIndex) const { 2113 switch (MI.getOpcode()) { 2114 default: 2115 break; 2116 case AArch64::LDRWui: 2117 case AArch64::LDRXui: 2118 case AArch64::LDRBui: 2119 case AArch64::LDRHui: 2120 case AArch64::LDRSui: 2121 case AArch64::LDRDui: 2122 case AArch64::LDRQui: 2123 if (MI.getOperand(0).getSubReg() == 0 && MI.getOperand(1).isFI() && 2124 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) { 2125 FrameIndex = MI.getOperand(1).getIndex(); 2126 return MI.getOperand(0).getReg(); 2127 } 2128 break; 2129 } 2130 2131 return 0; 2132 } 2133 2134 unsigned AArch64InstrInfo::isStoreToStackSlot(const MachineInstr &MI, 2135 int &FrameIndex) const { 2136 switch (MI.getOpcode()) { 2137 default: 2138 break; 2139 case AArch64::STRWui: 2140 case AArch64::STRXui: 2141 case AArch64::STRBui: 2142 case AArch64::STRHui: 2143 case AArch64::STRSui: 2144 case AArch64::STRDui: 2145 case AArch64::STRQui: 2146 case AArch64::LDR_PXI: 2147 case AArch64::STR_PXI: 2148 if (MI.getOperand(0).getSubReg() == 0 && MI.getOperand(1).isFI() && 2149 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) { 2150 FrameIndex = MI.getOperand(1).getIndex(); 2151 return MI.getOperand(0).getReg(); 2152 } 2153 break; 2154 } 2155 return 0; 2156 } 2157 2158 /// Check all MachineMemOperands for a hint to suppress pairing. 2159 bool AArch64InstrInfo::isLdStPairSuppressed(const MachineInstr &MI) { 2160 return llvm::any_of(MI.memoperands(), [](MachineMemOperand *MMO) { 2161 return MMO->getFlags() & MOSuppressPair; 2162 }); 2163 } 2164 2165 /// Set a flag on the first MachineMemOperand to suppress pairing. 2166 void AArch64InstrInfo::suppressLdStPair(MachineInstr &MI) { 2167 if (MI.memoperands_empty()) 2168 return; 2169 (*MI.memoperands_begin())->setFlags(MOSuppressPair); 2170 } 2171 2172 /// Check all MachineMemOperands for a hint that the load/store is strided. 2173 bool AArch64InstrInfo::isStridedAccess(const MachineInstr &MI) { 2174 return llvm::any_of(MI.memoperands(), [](MachineMemOperand *MMO) { 2175 return MMO->getFlags() & MOStridedAccess; 2176 }); 2177 } 2178 2179 bool AArch64InstrInfo::hasUnscaledLdStOffset(unsigned Opc) { 2180 switch (Opc) { 2181 default: 2182 return false; 2183 case AArch64::STURSi: 2184 case AArch64::STRSpre: 2185 case AArch64::STURDi: 2186 case AArch64::STRDpre: 2187 case AArch64::STURQi: 2188 case AArch64::STRQpre: 2189 case AArch64::STURBBi: 2190 case AArch64::STURHHi: 2191 case AArch64::STURWi: 2192 case AArch64::STRWpre: 2193 case AArch64::STURXi: 2194 case AArch64::STRXpre: 2195 case AArch64::LDURSi: 2196 case AArch64::LDRSpre: 2197 case AArch64::LDURDi: 2198 case AArch64::LDRDpre: 2199 case AArch64::LDURQi: 2200 case AArch64::LDRQpre: 2201 case AArch64::LDURWi: 2202 case AArch64::LDRWpre: 2203 case AArch64::LDURXi: 2204 case AArch64::LDRXpre: 2205 case AArch64::LDURSWi: 2206 case AArch64::LDURHHi: 2207 case AArch64::LDURBBi: 2208 case AArch64::LDURSBWi: 2209 case AArch64::LDURSHWi: 2210 return true; 2211 } 2212 } 2213 2214 Optional<unsigned> AArch64InstrInfo::getUnscaledLdSt(unsigned Opc) { 2215 switch (Opc) { 2216 default: return {}; 2217 case AArch64::PRFMui: return AArch64::PRFUMi; 2218 case AArch64::LDRXui: return AArch64::LDURXi; 2219 case AArch64::LDRWui: return AArch64::LDURWi; 2220 case AArch64::LDRBui: return AArch64::LDURBi; 2221 case AArch64::LDRHui: return AArch64::LDURHi; 2222 case AArch64::LDRSui: return AArch64::LDURSi; 2223 case AArch64::LDRDui: return AArch64::LDURDi; 2224 case AArch64::LDRQui: return AArch64::LDURQi; 2225 case AArch64::LDRBBui: return AArch64::LDURBBi; 2226 case AArch64::LDRHHui: return AArch64::LDURHHi; 2227 case AArch64::LDRSBXui: return AArch64::LDURSBXi; 2228 case AArch64::LDRSBWui: return AArch64::LDURSBWi; 2229 case AArch64::LDRSHXui: return AArch64::LDURSHXi; 2230 case AArch64::LDRSHWui: return AArch64::LDURSHWi; 2231 case AArch64::LDRSWui: return AArch64::LDURSWi; 2232 case AArch64::STRXui: return AArch64::STURXi; 2233 case AArch64::STRWui: return AArch64::STURWi; 2234 case AArch64::STRBui: return AArch64::STURBi; 2235 case AArch64::STRHui: return AArch64::STURHi; 2236 case AArch64::STRSui: return AArch64::STURSi; 2237 case AArch64::STRDui: return AArch64::STURDi; 2238 case AArch64::STRQui: return AArch64::STURQi; 2239 case AArch64::STRBBui: return AArch64::STURBBi; 2240 case AArch64::STRHHui: return AArch64::STURHHi; 2241 } 2242 } 2243 2244 unsigned AArch64InstrInfo::getLoadStoreImmIdx(unsigned Opc) { 2245 switch (Opc) { 2246 default: 2247 return 2; 2248 case AArch64::LDPXi: 2249 case AArch64::LDPDi: 2250 case AArch64::STPXi: 2251 case AArch64::STPDi: 2252 case AArch64::LDNPXi: 2253 case AArch64::LDNPDi: 2254 case AArch64::STNPXi: 2255 case AArch64::STNPDi: 2256 case AArch64::LDPQi: 2257 case AArch64::STPQi: 2258 case AArch64::LDNPQi: 2259 case AArch64::STNPQi: 2260 case AArch64::LDPWi: 2261 case AArch64::LDPSi: 2262 case AArch64::STPWi: 2263 case AArch64::STPSi: 2264 case AArch64::LDNPWi: 2265 case AArch64::LDNPSi: 2266 case AArch64::STNPWi: 2267 case AArch64::STNPSi: 2268 case AArch64::LDG: 2269 case AArch64::STGPi: 2270 2271 case AArch64::LD1B_IMM: 2272 case AArch64::LD1B_H_IMM: 2273 case AArch64::LD1B_S_IMM: 2274 case AArch64::LD1B_D_IMM: 2275 case AArch64::LD1SB_H_IMM: 2276 case AArch64::LD1SB_S_IMM: 2277 case AArch64::LD1SB_D_IMM: 2278 case AArch64::LD1H_IMM: 2279 case AArch64::LD1H_S_IMM: 2280 case AArch64::LD1H_D_IMM: 2281 case AArch64::LD1SH_S_IMM: 2282 case AArch64::LD1SH_D_IMM: 2283 case AArch64::LD1W_IMM: 2284 case AArch64::LD1W_D_IMM: 2285 case AArch64::LD1SW_D_IMM: 2286 case AArch64::LD1D_IMM: 2287 2288 case AArch64::ST1B_IMM: 2289 case AArch64::ST1B_H_IMM: 2290 case AArch64::ST1B_S_IMM: 2291 case AArch64::ST1B_D_IMM: 2292 case AArch64::ST1H_IMM: 2293 case AArch64::ST1H_S_IMM: 2294 case AArch64::ST1H_D_IMM: 2295 case AArch64::ST1W_IMM: 2296 case AArch64::ST1W_D_IMM: 2297 case AArch64::ST1D_IMM: 2298 2299 case AArch64::LD1RB_IMM: 2300 case AArch64::LD1RB_H_IMM: 2301 case AArch64::LD1RB_S_IMM: 2302 case AArch64::LD1RB_D_IMM: 2303 case AArch64::LD1RSB_H_IMM: 2304 case AArch64::LD1RSB_S_IMM: 2305 case AArch64::LD1RSB_D_IMM: 2306 case AArch64::LD1RH_IMM: 2307 case AArch64::LD1RH_S_IMM: 2308 case AArch64::LD1RH_D_IMM: 2309 case AArch64::LD1RSH_S_IMM: 2310 case AArch64::LD1RSH_D_IMM: 2311 case AArch64::LD1RW_IMM: 2312 case AArch64::LD1RW_D_IMM: 2313 case AArch64::LD1RSW_IMM: 2314 case AArch64::LD1RD_IMM: 2315 2316 case AArch64::LDNT1B_ZRI: 2317 case AArch64::LDNT1H_ZRI: 2318 case AArch64::LDNT1W_ZRI: 2319 case AArch64::LDNT1D_ZRI: 2320 case AArch64::STNT1B_ZRI: 2321 case AArch64::STNT1H_ZRI: 2322 case AArch64::STNT1W_ZRI: 2323 case AArch64::STNT1D_ZRI: 2324 2325 case AArch64::LDNF1B_IMM: 2326 case AArch64::LDNF1B_H_IMM: 2327 case AArch64::LDNF1B_S_IMM: 2328 case AArch64::LDNF1B_D_IMM: 2329 case AArch64::LDNF1SB_H_IMM: 2330 case AArch64::LDNF1SB_S_IMM: 2331 case AArch64::LDNF1SB_D_IMM: 2332 case AArch64::LDNF1H_IMM: 2333 case AArch64::LDNF1H_S_IMM: 2334 case AArch64::LDNF1H_D_IMM: 2335 case AArch64::LDNF1SH_S_IMM: 2336 case AArch64::LDNF1SH_D_IMM: 2337 case AArch64::LDNF1W_IMM: 2338 case AArch64::LDNF1W_D_IMM: 2339 case AArch64::LDNF1SW_D_IMM: 2340 case AArch64::LDNF1D_IMM: 2341 return 3; 2342 case AArch64::ADDG: 2343 case AArch64::STGOffset: 2344 case AArch64::LDR_PXI: 2345 case AArch64::STR_PXI: 2346 return 2; 2347 } 2348 } 2349 2350 bool AArch64InstrInfo::isPairableLdStInst(const MachineInstr &MI) { 2351 switch (MI.getOpcode()) { 2352 default: 2353 return false; 2354 // Scaled instructions. 2355 case AArch64::STRSui: 2356 case AArch64::STRDui: 2357 case AArch64::STRQui: 2358 case AArch64::STRXui: 2359 case AArch64::STRWui: 2360 case AArch64::LDRSui: 2361 case AArch64::LDRDui: 2362 case AArch64::LDRQui: 2363 case AArch64::LDRXui: 2364 case AArch64::LDRWui: 2365 case AArch64::LDRSWui: 2366 // Unscaled instructions. 2367 case AArch64::STURSi: 2368 case AArch64::STRSpre: 2369 case AArch64::STURDi: 2370 case AArch64::STRDpre: 2371 case AArch64::STURQi: 2372 case AArch64::STRQpre: 2373 case AArch64::STURWi: 2374 case AArch64::STRWpre: 2375 case AArch64::STURXi: 2376 case AArch64::STRXpre: 2377 case AArch64::LDURSi: 2378 case AArch64::LDRSpre: 2379 case AArch64::LDURDi: 2380 case AArch64::LDRDpre: 2381 case AArch64::LDURQi: 2382 case AArch64::LDRQpre: 2383 case AArch64::LDURWi: 2384 case AArch64::LDRWpre: 2385 case AArch64::LDURXi: 2386 case AArch64::LDRXpre: 2387 case AArch64::LDURSWi: 2388 return true; 2389 } 2390 } 2391 2392 unsigned AArch64InstrInfo::convertToFlagSettingOpc(unsigned Opc, 2393 bool &Is64Bit) { 2394 switch (Opc) { 2395 default: 2396 llvm_unreachable("Opcode has no flag setting equivalent!"); 2397 // 32-bit cases: 2398 case AArch64::ADDWri: 2399 Is64Bit = false; 2400 return AArch64::ADDSWri; 2401 case AArch64::ADDWrr: 2402 Is64Bit = false; 2403 return AArch64::ADDSWrr; 2404 case AArch64::ADDWrs: 2405 Is64Bit = false; 2406 return AArch64::ADDSWrs; 2407 case AArch64::ADDWrx: 2408 Is64Bit = false; 2409 return AArch64::ADDSWrx; 2410 case AArch64::ANDWri: 2411 Is64Bit = false; 2412 return AArch64::ANDSWri; 2413 case AArch64::ANDWrr: 2414 Is64Bit = false; 2415 return AArch64::ANDSWrr; 2416 case AArch64::ANDWrs: 2417 Is64Bit = false; 2418 return AArch64::ANDSWrs; 2419 case AArch64::BICWrr: 2420 Is64Bit = false; 2421 return AArch64::BICSWrr; 2422 case AArch64::BICWrs: 2423 Is64Bit = false; 2424 return AArch64::BICSWrs; 2425 case AArch64::SUBWri: 2426 Is64Bit = false; 2427 return AArch64::SUBSWri; 2428 case AArch64::SUBWrr: 2429 Is64Bit = false; 2430 return AArch64::SUBSWrr; 2431 case AArch64::SUBWrs: 2432 Is64Bit = false; 2433 return AArch64::SUBSWrs; 2434 case AArch64::SUBWrx: 2435 Is64Bit = false; 2436 return AArch64::SUBSWrx; 2437 // 64-bit cases: 2438 case AArch64::ADDXri: 2439 Is64Bit = true; 2440 return AArch64::ADDSXri; 2441 case AArch64::ADDXrr: 2442 Is64Bit = true; 2443 return AArch64::ADDSXrr; 2444 case AArch64::ADDXrs: 2445 Is64Bit = true; 2446 return AArch64::ADDSXrs; 2447 case AArch64::ADDXrx: 2448 Is64Bit = true; 2449 return AArch64::ADDSXrx; 2450 case AArch64::ANDXri: 2451 Is64Bit = true; 2452 return AArch64::ANDSXri; 2453 case AArch64::ANDXrr: 2454 Is64Bit = true; 2455 return AArch64::ANDSXrr; 2456 case AArch64::ANDXrs: 2457 Is64Bit = true; 2458 return AArch64::ANDSXrs; 2459 case AArch64::BICXrr: 2460 Is64Bit = true; 2461 return AArch64::BICSXrr; 2462 case AArch64::BICXrs: 2463 Is64Bit = true; 2464 return AArch64::BICSXrs; 2465 case AArch64::SUBXri: 2466 Is64Bit = true; 2467 return AArch64::SUBSXri; 2468 case AArch64::SUBXrr: 2469 Is64Bit = true; 2470 return AArch64::SUBSXrr; 2471 case AArch64::SUBXrs: 2472 Is64Bit = true; 2473 return AArch64::SUBSXrs; 2474 case AArch64::SUBXrx: 2475 Is64Bit = true; 2476 return AArch64::SUBSXrx; 2477 } 2478 } 2479 2480 // Is this a candidate for ld/st merging or pairing? For example, we don't 2481 // touch volatiles or load/stores that have a hint to avoid pair formation. 2482 bool AArch64InstrInfo::isCandidateToMergeOrPair(const MachineInstr &MI) const { 2483 2484 bool IsPreLdSt = isPreLdSt(MI); 2485 2486 // If this is a volatile load/store, don't mess with it. 2487 if (MI.hasOrderedMemoryRef()) 2488 return false; 2489 2490 // Make sure this is a reg/fi+imm (as opposed to an address reloc). 2491 // For Pre-inc LD/ST, the operand is shifted by one. 2492 assert((MI.getOperand(IsPreLdSt ? 2 : 1).isReg() || 2493 MI.getOperand(IsPreLdSt ? 2 : 1).isFI()) && 2494 "Expected a reg or frame index operand."); 2495 2496 // For Pre-indexed addressing quadword instructions, the third operand is the 2497 // immediate value. 2498 bool IsImmPreLdSt = IsPreLdSt && MI.getOperand(3).isImm(); 2499 2500 if (!MI.getOperand(2).isImm() && !IsImmPreLdSt) 2501 return false; 2502 2503 // Can't merge/pair if the instruction modifies the base register. 2504 // e.g., ldr x0, [x0] 2505 // This case will never occur with an FI base. 2506 // However, if the instruction is an LDR/STR<S,D,Q,W,X>pre, it can be merged. 2507 // For example: 2508 // ldr q0, [x11, #32]! 2509 // ldr q1, [x11, #16] 2510 // to 2511 // ldp q0, q1, [x11, #32]! 2512 if (MI.getOperand(1).isReg() && !IsPreLdSt) { 2513 Register BaseReg = MI.getOperand(1).getReg(); 2514 const TargetRegisterInfo *TRI = &getRegisterInfo(); 2515 if (MI.modifiesRegister(BaseReg, TRI)) 2516 return false; 2517 } 2518 2519 // Check if this load/store has a hint to avoid pair formation. 2520 // MachineMemOperands hints are set by the AArch64StorePairSuppress pass. 2521 if (isLdStPairSuppressed(MI)) 2522 return false; 2523 2524 // Do not pair any callee-save store/reload instructions in the 2525 // prologue/epilogue if the CFI information encoded the operations as separate 2526 // instructions, as that will cause the size of the actual prologue to mismatch 2527 // with the prologue size recorded in the Windows CFI. 2528 const MCAsmInfo *MAI = MI.getMF()->getTarget().getMCAsmInfo(); 2529 bool NeedsWinCFI = MAI->usesWindowsCFI() && 2530 MI.getMF()->getFunction().needsUnwindTableEntry(); 2531 if (NeedsWinCFI && (MI.getFlag(MachineInstr::FrameSetup) || 2532 MI.getFlag(MachineInstr::FrameDestroy))) 2533 return false; 2534 2535 // On some CPUs quad load/store pairs are slower than two single load/stores. 2536 if (Subtarget.isPaired128Slow()) { 2537 switch (MI.getOpcode()) { 2538 default: 2539 break; 2540 case AArch64::LDURQi: 2541 case AArch64::STURQi: 2542 case AArch64::LDRQui: 2543 case AArch64::STRQui: 2544 return false; 2545 } 2546 } 2547 2548 return true; 2549 } 2550 2551 bool AArch64InstrInfo::getMemOperandsWithOffsetWidth( 2552 const MachineInstr &LdSt, SmallVectorImpl<const MachineOperand *> &BaseOps, 2553 int64_t &Offset, bool &OffsetIsScalable, unsigned &Width, 2554 const TargetRegisterInfo *TRI) const { 2555 if (!LdSt.mayLoadOrStore()) 2556 return false; 2557 2558 const MachineOperand *BaseOp; 2559 if (!getMemOperandWithOffsetWidth(LdSt, BaseOp, Offset, OffsetIsScalable, 2560 Width, TRI)) 2561 return false; 2562 BaseOps.push_back(BaseOp); 2563 return true; 2564 } 2565 2566 Optional<ExtAddrMode> 2567 AArch64InstrInfo::getAddrModeFromMemoryOp(const MachineInstr &MemI, 2568 const TargetRegisterInfo *TRI) const { 2569 const MachineOperand *Base; // Filled with the base operand of MI. 2570 int64_t Offset; // Filled with the offset of MI. 2571 bool OffsetIsScalable; 2572 if (!getMemOperandWithOffset(MemI, Base, Offset, OffsetIsScalable, TRI)) 2573 return None; 2574 2575 if (!Base->isReg()) 2576 return None; 2577 ExtAddrMode AM; 2578 AM.BaseReg = Base->getReg(); 2579 AM.Displacement = Offset; 2580 AM.ScaledReg = 0; 2581 AM.Scale = 0; 2582 return AM; 2583 } 2584 2585 bool AArch64InstrInfo::getMemOperandWithOffsetWidth( 2586 const MachineInstr &LdSt, const MachineOperand *&BaseOp, int64_t &Offset, 2587 bool &OffsetIsScalable, unsigned &Width, 2588 const TargetRegisterInfo *TRI) const { 2589 assert(LdSt.mayLoadOrStore() && "Expected a memory operation."); 2590 // Handle only loads/stores with base register followed by immediate offset. 2591 if (LdSt.getNumExplicitOperands() == 3) { 2592 // Non-paired instruction (e.g., ldr x1, [x0, #8]). 2593 if ((!LdSt.getOperand(1).isReg() && !LdSt.getOperand(1).isFI()) || 2594 !LdSt.getOperand(2).isImm()) 2595 return false; 2596 } else if (LdSt.getNumExplicitOperands() == 4) { 2597 // Paired instruction (e.g., ldp x1, x2, [x0, #8]). 2598 if (!LdSt.getOperand(1).isReg() || 2599 (!LdSt.getOperand(2).isReg() && !LdSt.getOperand(2).isFI()) || 2600 !LdSt.getOperand(3).isImm()) 2601 return false; 2602 } else 2603 return false; 2604 2605 // Get the scaling factor for the instruction and set the width for the 2606 // instruction. 2607 TypeSize Scale(0U, false); 2608 int64_t Dummy1, Dummy2; 2609 2610 // If this returns false, then it's an instruction we don't want to handle. 2611 if (!getMemOpInfo(LdSt.getOpcode(), Scale, Width, Dummy1, Dummy2)) 2612 return false; 2613 2614 // Compute the offset. Offset is calculated as the immediate operand 2615 // multiplied by the scaling factor. Unscaled instructions have scaling factor 2616 // set to 1. 2617 if (LdSt.getNumExplicitOperands() == 3) { 2618 BaseOp = &LdSt.getOperand(1); 2619 Offset = LdSt.getOperand(2).getImm() * Scale.getKnownMinSize(); 2620 } else { 2621 assert(LdSt.getNumExplicitOperands() == 4 && "invalid number of operands"); 2622 BaseOp = &LdSt.getOperand(2); 2623 Offset = LdSt.getOperand(3).getImm() * Scale.getKnownMinSize(); 2624 } 2625 OffsetIsScalable = Scale.isScalable(); 2626 2627 if (!BaseOp->isReg() && !BaseOp->isFI()) 2628 return false; 2629 2630 return true; 2631 } 2632 2633 MachineOperand & 2634 AArch64InstrInfo::getMemOpBaseRegImmOfsOffsetOperand(MachineInstr &LdSt) const { 2635 assert(LdSt.mayLoadOrStore() && "Expected a memory operation."); 2636 MachineOperand &OfsOp = LdSt.getOperand(LdSt.getNumExplicitOperands() - 1); 2637 assert(OfsOp.isImm() && "Offset operand wasn't immediate."); 2638 return OfsOp; 2639 } 2640 2641 bool AArch64InstrInfo::getMemOpInfo(unsigned Opcode, TypeSize &Scale, 2642 unsigned &Width, int64_t &MinOffset, 2643 int64_t &MaxOffset) { 2644 const unsigned SVEMaxBytesPerVector = AArch64::SVEMaxBitsPerVector / 8; 2645 switch (Opcode) { 2646 // Not a memory operation or something we want to handle. 2647 default: 2648 Scale = TypeSize::Fixed(0); 2649 Width = 0; 2650 MinOffset = MaxOffset = 0; 2651 return false; 2652 case AArch64::STRWpost: 2653 case AArch64::LDRWpost: 2654 Width = 32; 2655 Scale = TypeSize::Fixed(4); 2656 MinOffset = -256; 2657 MaxOffset = 255; 2658 break; 2659 case AArch64::LDURQi: 2660 case AArch64::STURQi: 2661 Width = 16; 2662 Scale = TypeSize::Fixed(1); 2663 MinOffset = -256; 2664 MaxOffset = 255; 2665 break; 2666 case AArch64::PRFUMi: 2667 case AArch64::LDURXi: 2668 case AArch64::LDURDi: 2669 case AArch64::STURXi: 2670 case AArch64::STURDi: 2671 Width = 8; 2672 Scale = TypeSize::Fixed(1); 2673 MinOffset = -256; 2674 MaxOffset = 255; 2675 break; 2676 case AArch64::LDURWi: 2677 case AArch64::LDURSi: 2678 case AArch64::LDURSWi: 2679 case AArch64::STURWi: 2680 case AArch64::STURSi: 2681 Width = 4; 2682 Scale = TypeSize::Fixed(1); 2683 MinOffset = -256; 2684 MaxOffset = 255; 2685 break; 2686 case AArch64::LDURHi: 2687 case AArch64::LDURHHi: 2688 case AArch64::LDURSHXi: 2689 case AArch64::LDURSHWi: 2690 case AArch64::STURHi: 2691 case AArch64::STURHHi: 2692 Width = 2; 2693 Scale = TypeSize::Fixed(1); 2694 MinOffset = -256; 2695 MaxOffset = 255; 2696 break; 2697 case AArch64::LDURBi: 2698 case AArch64::LDURBBi: 2699 case AArch64::LDURSBXi: 2700 case AArch64::LDURSBWi: 2701 case AArch64::STURBi: 2702 case AArch64::STURBBi: 2703 Width = 1; 2704 Scale = TypeSize::Fixed(1); 2705 MinOffset = -256; 2706 MaxOffset = 255; 2707 break; 2708 case AArch64::LDPQi: 2709 case AArch64::LDNPQi: 2710 case AArch64::STPQi: 2711 case AArch64::STNPQi: 2712 Scale = TypeSize::Fixed(16); 2713 Width = 32; 2714 MinOffset = -64; 2715 MaxOffset = 63; 2716 break; 2717 case AArch64::LDRQui: 2718 case AArch64::STRQui: 2719 Scale = TypeSize::Fixed(16); 2720 Width = 16; 2721 MinOffset = 0; 2722 MaxOffset = 4095; 2723 break; 2724 case AArch64::LDPXi: 2725 case AArch64::LDPDi: 2726 case AArch64::LDNPXi: 2727 case AArch64::LDNPDi: 2728 case AArch64::STPXi: 2729 case AArch64::STPDi: 2730 case AArch64::STNPXi: 2731 case AArch64::STNPDi: 2732 Scale = TypeSize::Fixed(8); 2733 Width = 16; 2734 MinOffset = -64; 2735 MaxOffset = 63; 2736 break; 2737 case AArch64::PRFMui: 2738 case AArch64::LDRXui: 2739 case AArch64::LDRDui: 2740 case AArch64::STRXui: 2741 case AArch64::STRDui: 2742 Scale = TypeSize::Fixed(8); 2743 Width = 8; 2744 MinOffset = 0; 2745 MaxOffset = 4095; 2746 break; 2747 case AArch64::StoreSwiftAsyncContext: 2748 // Store is an STRXui, but there might be an ADDXri in the expansion too. 2749 Scale = TypeSize::Fixed(1); 2750 Width = 8; 2751 MinOffset = 0; 2752 MaxOffset = 4095; 2753 break; 2754 case AArch64::LDPWi: 2755 case AArch64::LDPSi: 2756 case AArch64::LDNPWi: 2757 case AArch64::LDNPSi: 2758 case AArch64::STPWi: 2759 case AArch64::STPSi: 2760 case AArch64::STNPWi: 2761 case AArch64::STNPSi: 2762 Scale = TypeSize::Fixed(4); 2763 Width = 8; 2764 MinOffset = -64; 2765 MaxOffset = 63; 2766 break; 2767 case AArch64::LDRWui: 2768 case AArch64::LDRSui: 2769 case AArch64::LDRSWui: 2770 case AArch64::STRWui: 2771 case AArch64::STRSui: 2772 Scale = TypeSize::Fixed(4); 2773 Width = 4; 2774 MinOffset = 0; 2775 MaxOffset = 4095; 2776 break; 2777 case AArch64::LDRHui: 2778 case AArch64::LDRHHui: 2779 case AArch64::LDRSHWui: 2780 case AArch64::LDRSHXui: 2781 case AArch64::STRHui: 2782 case AArch64::STRHHui: 2783 Scale = TypeSize::Fixed(2); 2784 Width = 2; 2785 MinOffset = 0; 2786 MaxOffset = 4095; 2787 break; 2788 case AArch64::LDRBui: 2789 case AArch64::LDRBBui: 2790 case AArch64::LDRSBWui: 2791 case AArch64::LDRSBXui: 2792 case AArch64::STRBui: 2793 case AArch64::STRBBui: 2794 Scale = TypeSize::Fixed(1); 2795 Width = 1; 2796 MinOffset = 0; 2797 MaxOffset = 4095; 2798 break; 2799 case AArch64::STPXpre: 2800 case AArch64::LDPXpost: 2801 case AArch64::STPDpre: 2802 case AArch64::LDPDpost: 2803 Scale = TypeSize::Fixed(8); 2804 Width = 8; 2805 MinOffset = -512; 2806 MaxOffset = 504; 2807 break; 2808 case AArch64::STPQpre: 2809 case AArch64::LDPQpost: 2810 Scale = TypeSize::Fixed(16); 2811 Width = 16; 2812 MinOffset = -1024; 2813 MaxOffset = 1008; 2814 break; 2815 case AArch64::STRXpre: 2816 case AArch64::STRDpre: 2817 case AArch64::LDRXpost: 2818 case AArch64::LDRDpost: 2819 Scale = TypeSize::Fixed(1); 2820 Width = 8; 2821 MinOffset = -256; 2822 MaxOffset = 255; 2823 break; 2824 case AArch64::STRQpre: 2825 case AArch64::LDRQpost: 2826 Scale = TypeSize::Fixed(1); 2827 Width = 16; 2828 MinOffset = -256; 2829 MaxOffset = 255; 2830 break; 2831 case AArch64::ADDG: 2832 Scale = TypeSize::Fixed(16); 2833 Width = 0; 2834 MinOffset = 0; 2835 MaxOffset = 63; 2836 break; 2837 case AArch64::TAGPstack: 2838 Scale = TypeSize::Fixed(16); 2839 Width = 0; 2840 // TAGP with a negative offset turns into SUBP, which has a maximum offset 2841 // of 63 (not 64!). 2842 MinOffset = -63; 2843 MaxOffset = 63; 2844 break; 2845 case AArch64::LDG: 2846 case AArch64::STGOffset: 2847 case AArch64::STZGOffset: 2848 Scale = TypeSize::Fixed(16); 2849 Width = 16; 2850 MinOffset = -256; 2851 MaxOffset = 255; 2852 break; 2853 case AArch64::STR_ZZZZXI: 2854 case AArch64::LDR_ZZZZXI: 2855 Scale = TypeSize::Scalable(16); 2856 Width = SVEMaxBytesPerVector * 4; 2857 MinOffset = -256; 2858 MaxOffset = 252; 2859 break; 2860 case AArch64::STR_ZZZXI: 2861 case AArch64::LDR_ZZZXI: 2862 Scale = TypeSize::Scalable(16); 2863 Width = SVEMaxBytesPerVector * 3; 2864 MinOffset = -256; 2865 MaxOffset = 253; 2866 break; 2867 case AArch64::STR_ZZXI: 2868 case AArch64::LDR_ZZXI: 2869 Scale = TypeSize::Scalable(16); 2870 Width = SVEMaxBytesPerVector * 2; 2871 MinOffset = -256; 2872 MaxOffset = 254; 2873 break; 2874 case AArch64::LDR_PXI: 2875 case AArch64::STR_PXI: 2876 Scale = TypeSize::Scalable(2); 2877 Width = SVEMaxBytesPerVector / 8; 2878 MinOffset = -256; 2879 MaxOffset = 255; 2880 break; 2881 case AArch64::LDR_ZXI: 2882 case AArch64::STR_ZXI: 2883 Scale = TypeSize::Scalable(16); 2884 Width = SVEMaxBytesPerVector; 2885 MinOffset = -256; 2886 MaxOffset = 255; 2887 break; 2888 case AArch64::LD1B_IMM: 2889 case AArch64::LD1H_IMM: 2890 case AArch64::LD1W_IMM: 2891 case AArch64::LD1D_IMM: 2892 case AArch64::LDNT1B_ZRI: 2893 case AArch64::LDNT1H_ZRI: 2894 case AArch64::LDNT1W_ZRI: 2895 case AArch64::LDNT1D_ZRI: 2896 case AArch64::ST1B_IMM: 2897 case AArch64::ST1H_IMM: 2898 case AArch64::ST1W_IMM: 2899 case AArch64::ST1D_IMM: 2900 case AArch64::STNT1B_ZRI: 2901 case AArch64::STNT1H_ZRI: 2902 case AArch64::STNT1W_ZRI: 2903 case AArch64::STNT1D_ZRI: 2904 case AArch64::LDNF1B_IMM: 2905 case AArch64::LDNF1H_IMM: 2906 case AArch64::LDNF1W_IMM: 2907 case AArch64::LDNF1D_IMM: 2908 // A full vectors worth of data 2909 // Width = mbytes * elements 2910 Scale = TypeSize::Scalable(16); 2911 Width = SVEMaxBytesPerVector; 2912 MinOffset = -8; 2913 MaxOffset = 7; 2914 break; 2915 case AArch64::LD1B_H_IMM: 2916 case AArch64::LD1SB_H_IMM: 2917 case AArch64::LD1H_S_IMM: 2918 case AArch64::LD1SH_S_IMM: 2919 case AArch64::LD1W_D_IMM: 2920 case AArch64::LD1SW_D_IMM: 2921 case AArch64::ST1B_H_IMM: 2922 case AArch64::ST1H_S_IMM: 2923 case AArch64::ST1W_D_IMM: 2924 case AArch64::LDNF1B_H_IMM: 2925 case AArch64::LDNF1SB_H_IMM: 2926 case AArch64::LDNF1H_S_IMM: 2927 case AArch64::LDNF1SH_S_IMM: 2928 case AArch64::LDNF1W_D_IMM: 2929 case AArch64::LDNF1SW_D_IMM: 2930 // A half vector worth of data 2931 // Width = mbytes * elements 2932 Scale = TypeSize::Scalable(8); 2933 Width = SVEMaxBytesPerVector / 2; 2934 MinOffset = -8; 2935 MaxOffset = 7; 2936 break; 2937 case AArch64::LD1B_S_IMM: 2938 case AArch64::LD1SB_S_IMM: 2939 case AArch64::LD1H_D_IMM: 2940 case AArch64::LD1SH_D_IMM: 2941 case AArch64::ST1B_S_IMM: 2942 case AArch64::ST1H_D_IMM: 2943 case AArch64::LDNF1B_S_IMM: 2944 case AArch64::LDNF1SB_S_IMM: 2945 case AArch64::LDNF1H_D_IMM: 2946 case AArch64::LDNF1SH_D_IMM: 2947 // A quarter vector worth of data 2948 // Width = mbytes * elements 2949 Scale = TypeSize::Scalable(4); 2950 Width = SVEMaxBytesPerVector / 4; 2951 MinOffset = -8; 2952 MaxOffset = 7; 2953 break; 2954 case AArch64::LD1B_D_IMM: 2955 case AArch64::LD1SB_D_IMM: 2956 case AArch64::ST1B_D_IMM: 2957 case AArch64::LDNF1B_D_IMM: 2958 case AArch64::LDNF1SB_D_IMM: 2959 // A eighth vector worth of data 2960 // Width = mbytes * elements 2961 Scale = TypeSize::Scalable(2); 2962 Width = SVEMaxBytesPerVector / 8; 2963 MinOffset = -8; 2964 MaxOffset = 7; 2965 break; 2966 case AArch64::ST2GOffset: 2967 case AArch64::STZ2GOffset: 2968 Scale = TypeSize::Fixed(16); 2969 Width = 32; 2970 MinOffset = -256; 2971 MaxOffset = 255; 2972 break; 2973 case AArch64::STGPi: 2974 Scale = TypeSize::Fixed(16); 2975 Width = 16; 2976 MinOffset = -64; 2977 MaxOffset = 63; 2978 break; 2979 case AArch64::LD1RB_IMM: 2980 case AArch64::LD1RB_H_IMM: 2981 case AArch64::LD1RB_S_IMM: 2982 case AArch64::LD1RB_D_IMM: 2983 case AArch64::LD1RSB_H_IMM: 2984 case AArch64::LD1RSB_S_IMM: 2985 case AArch64::LD1RSB_D_IMM: 2986 Scale = TypeSize::Fixed(1); 2987 Width = 1; 2988 MinOffset = 0; 2989 MaxOffset = 63; 2990 break; 2991 case AArch64::LD1RH_IMM: 2992 case AArch64::LD1RH_S_IMM: 2993 case AArch64::LD1RH_D_IMM: 2994 case AArch64::LD1RSH_S_IMM: 2995 case AArch64::LD1RSH_D_IMM: 2996 Scale = TypeSize::Fixed(2); 2997 Width = 2; 2998 MinOffset = 0; 2999 MaxOffset = 63; 3000 break; 3001 case AArch64::LD1RW_IMM: 3002 case AArch64::LD1RW_D_IMM: 3003 case AArch64::LD1RSW_IMM: 3004 Scale = TypeSize::Fixed(4); 3005 Width = 4; 3006 MinOffset = 0; 3007 MaxOffset = 63; 3008 break; 3009 case AArch64::LD1RD_IMM: 3010 Scale = TypeSize::Fixed(8); 3011 Width = 8; 3012 MinOffset = 0; 3013 MaxOffset = 63; 3014 break; 3015 } 3016 3017 return true; 3018 } 3019 3020 // Scaling factor for unscaled load or store. 3021 int AArch64InstrInfo::getMemScale(unsigned Opc) { 3022 switch (Opc) { 3023 default: 3024 llvm_unreachable("Opcode has unknown scale!"); 3025 case AArch64::LDRBBui: 3026 case AArch64::LDURBBi: 3027 case AArch64::LDRSBWui: 3028 case AArch64::LDURSBWi: 3029 case AArch64::STRBBui: 3030 case AArch64::STURBBi: 3031 return 1; 3032 case AArch64::LDRHHui: 3033 case AArch64::LDURHHi: 3034 case AArch64::LDRSHWui: 3035 case AArch64::LDURSHWi: 3036 case AArch64::STRHHui: 3037 case AArch64::STURHHi: 3038 return 2; 3039 case AArch64::LDRSui: 3040 case AArch64::LDURSi: 3041 case AArch64::LDRSpre: 3042 case AArch64::LDRSWui: 3043 case AArch64::LDURSWi: 3044 case AArch64::LDRWpre: 3045 case AArch64::LDRWui: 3046 case AArch64::LDURWi: 3047 case AArch64::STRSui: 3048 case AArch64::STURSi: 3049 case AArch64::STRSpre: 3050 case AArch64::STRWui: 3051 case AArch64::STURWi: 3052 case AArch64::STRWpre: 3053 case AArch64::LDPSi: 3054 case AArch64::LDPSWi: 3055 case AArch64::LDPWi: 3056 case AArch64::STPSi: 3057 case AArch64::STPWi: 3058 return 4; 3059 case AArch64::LDRDui: 3060 case AArch64::LDURDi: 3061 case AArch64::LDRDpre: 3062 case AArch64::LDRXui: 3063 case AArch64::LDURXi: 3064 case AArch64::LDRXpre: 3065 case AArch64::STRDui: 3066 case AArch64::STURDi: 3067 case AArch64::STRDpre: 3068 case AArch64::STRXui: 3069 case AArch64::STURXi: 3070 case AArch64::STRXpre: 3071 case AArch64::LDPDi: 3072 case AArch64::LDPXi: 3073 case AArch64::STPDi: 3074 case AArch64::STPXi: 3075 return 8; 3076 case AArch64::LDRQui: 3077 case AArch64::LDURQi: 3078 case AArch64::STRQui: 3079 case AArch64::STURQi: 3080 case AArch64::STRQpre: 3081 case AArch64::LDPQi: 3082 case AArch64::LDRQpre: 3083 case AArch64::STPQi: 3084 case AArch64::STGOffset: 3085 case AArch64::STZGOffset: 3086 case AArch64::ST2GOffset: 3087 case AArch64::STZ2GOffset: 3088 case AArch64::STGPi: 3089 return 16; 3090 } 3091 } 3092 3093 bool AArch64InstrInfo::isPreLd(const MachineInstr &MI) { 3094 switch (MI.getOpcode()) { 3095 default: 3096 return false; 3097 case AArch64::LDRWpre: 3098 case AArch64::LDRXpre: 3099 case AArch64::LDRSpre: 3100 case AArch64::LDRDpre: 3101 case AArch64::LDRQpre: 3102 return true; 3103 } 3104 } 3105 3106 bool AArch64InstrInfo::isPreSt(const MachineInstr &MI) { 3107 switch (MI.getOpcode()) { 3108 default: 3109 return false; 3110 case AArch64::STRWpre: 3111 case AArch64::STRXpre: 3112 case AArch64::STRSpre: 3113 case AArch64::STRDpre: 3114 case AArch64::STRQpre: 3115 return true; 3116 } 3117 } 3118 3119 bool AArch64InstrInfo::isPreLdSt(const MachineInstr &MI) { 3120 return isPreLd(MI) || isPreSt(MI); 3121 } 3122 3123 // Scale the unscaled offsets. Returns false if the unscaled offset can't be 3124 // scaled. 3125 static bool scaleOffset(unsigned Opc, int64_t &Offset) { 3126 int Scale = AArch64InstrInfo::getMemScale(Opc); 3127 3128 // If the byte-offset isn't a multiple of the stride, we can't scale this 3129 // offset. 3130 if (Offset % Scale != 0) 3131 return false; 3132 3133 // Convert the byte-offset used by unscaled into an "element" offset used 3134 // by the scaled pair load/store instructions. 3135 Offset /= Scale; 3136 return true; 3137 } 3138 3139 static bool canPairLdStOpc(unsigned FirstOpc, unsigned SecondOpc) { 3140 if (FirstOpc == SecondOpc) 3141 return true; 3142 // We can also pair sign-ext and zero-ext instructions. 3143 switch (FirstOpc) { 3144 default: 3145 return false; 3146 case AArch64::LDRWui: 3147 case AArch64::LDURWi: 3148 return SecondOpc == AArch64::LDRSWui || SecondOpc == AArch64::LDURSWi; 3149 case AArch64::LDRSWui: 3150 case AArch64::LDURSWi: 3151 return SecondOpc == AArch64::LDRWui || SecondOpc == AArch64::LDURWi; 3152 } 3153 // These instructions can't be paired based on their opcodes. 3154 return false; 3155 } 3156 3157 static bool shouldClusterFI(const MachineFrameInfo &MFI, int FI1, 3158 int64_t Offset1, unsigned Opcode1, int FI2, 3159 int64_t Offset2, unsigned Opcode2) { 3160 // Accesses through fixed stack object frame indices may access a different 3161 // fixed stack slot. Check that the object offsets + offsets match. 3162 if (MFI.isFixedObjectIndex(FI1) && MFI.isFixedObjectIndex(FI2)) { 3163 int64_t ObjectOffset1 = MFI.getObjectOffset(FI1); 3164 int64_t ObjectOffset2 = MFI.getObjectOffset(FI2); 3165 assert(ObjectOffset1 <= ObjectOffset2 && "Object offsets are not ordered."); 3166 // Convert to scaled object offsets. 3167 int Scale1 = AArch64InstrInfo::getMemScale(Opcode1); 3168 if (ObjectOffset1 % Scale1 != 0) 3169 return false; 3170 ObjectOffset1 /= Scale1; 3171 int Scale2 = AArch64InstrInfo::getMemScale(Opcode2); 3172 if (ObjectOffset2 % Scale2 != 0) 3173 return false; 3174 ObjectOffset2 /= Scale2; 3175 ObjectOffset1 += Offset1; 3176 ObjectOffset2 += Offset2; 3177 return ObjectOffset1 + 1 == ObjectOffset2; 3178 } 3179 3180 return FI1 == FI2; 3181 } 3182 3183 /// Detect opportunities for ldp/stp formation. 3184 /// 3185 /// Only called for LdSt for which getMemOperandWithOffset returns true. 3186 bool AArch64InstrInfo::shouldClusterMemOps( 3187 ArrayRef<const MachineOperand *> BaseOps1, 3188 ArrayRef<const MachineOperand *> BaseOps2, unsigned NumLoads, 3189 unsigned NumBytes) const { 3190 assert(BaseOps1.size() == 1 && BaseOps2.size() == 1); 3191 const MachineOperand &BaseOp1 = *BaseOps1.front(); 3192 const MachineOperand &BaseOp2 = *BaseOps2.front(); 3193 const MachineInstr &FirstLdSt = *BaseOp1.getParent(); 3194 const MachineInstr &SecondLdSt = *BaseOp2.getParent(); 3195 if (BaseOp1.getType() != BaseOp2.getType()) 3196 return false; 3197 3198 assert((BaseOp1.isReg() || BaseOp1.isFI()) && 3199 "Only base registers and frame indices are supported."); 3200 3201 // Check for both base regs and base FI. 3202 if (BaseOp1.isReg() && BaseOp1.getReg() != BaseOp2.getReg()) 3203 return false; 3204 3205 // Only cluster up to a single pair. 3206 if (NumLoads > 2) 3207 return false; 3208 3209 if (!isPairableLdStInst(FirstLdSt) || !isPairableLdStInst(SecondLdSt)) 3210 return false; 3211 3212 // Can we pair these instructions based on their opcodes? 3213 unsigned FirstOpc = FirstLdSt.getOpcode(); 3214 unsigned SecondOpc = SecondLdSt.getOpcode(); 3215 if (!canPairLdStOpc(FirstOpc, SecondOpc)) 3216 return false; 3217 3218 // Can't merge volatiles or load/stores that have a hint to avoid pair 3219 // formation, for example. 3220 if (!isCandidateToMergeOrPair(FirstLdSt) || 3221 !isCandidateToMergeOrPair(SecondLdSt)) 3222 return false; 3223 3224 // isCandidateToMergeOrPair guarantees that operand 2 is an immediate. 3225 int64_t Offset1 = FirstLdSt.getOperand(2).getImm(); 3226 if (hasUnscaledLdStOffset(FirstOpc) && !scaleOffset(FirstOpc, Offset1)) 3227 return false; 3228 3229 int64_t Offset2 = SecondLdSt.getOperand(2).getImm(); 3230 if (hasUnscaledLdStOffset(SecondOpc) && !scaleOffset(SecondOpc, Offset2)) 3231 return false; 3232 3233 // Pairwise instructions have a 7-bit signed offset field. 3234 if (Offset1 > 63 || Offset1 < -64) 3235 return false; 3236 3237 // The caller should already have ordered First/SecondLdSt by offset. 3238 // Note: except for non-equal frame index bases 3239 if (BaseOp1.isFI()) { 3240 assert((!BaseOp1.isIdenticalTo(BaseOp2) || Offset1 <= Offset2) && 3241 "Caller should have ordered offsets."); 3242 3243 const MachineFrameInfo &MFI = 3244 FirstLdSt.getParent()->getParent()->getFrameInfo(); 3245 return shouldClusterFI(MFI, BaseOp1.getIndex(), Offset1, FirstOpc, 3246 BaseOp2.getIndex(), Offset2, SecondOpc); 3247 } 3248 3249 assert(Offset1 <= Offset2 && "Caller should have ordered offsets."); 3250 3251 return Offset1 + 1 == Offset2; 3252 } 3253 3254 static const MachineInstrBuilder &AddSubReg(const MachineInstrBuilder &MIB, 3255 unsigned Reg, unsigned SubIdx, 3256 unsigned State, 3257 const TargetRegisterInfo *TRI) { 3258 if (!SubIdx) 3259 return MIB.addReg(Reg, State); 3260 3261 if (Register::isPhysicalRegister(Reg)) 3262 return MIB.addReg(TRI->getSubReg(Reg, SubIdx), State); 3263 return MIB.addReg(Reg, State, SubIdx); 3264 } 3265 3266 static bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg, 3267 unsigned NumRegs) { 3268 // We really want the positive remainder mod 32 here, that happens to be 3269 // easily obtainable with a mask. 3270 return ((DestReg - SrcReg) & 0x1f) < NumRegs; 3271 } 3272 3273 void AArch64InstrInfo::copyPhysRegTuple(MachineBasicBlock &MBB, 3274 MachineBasicBlock::iterator I, 3275 const DebugLoc &DL, MCRegister DestReg, 3276 MCRegister SrcReg, bool KillSrc, 3277 unsigned Opcode, 3278 ArrayRef<unsigned> Indices) const { 3279 assert(Subtarget.hasNEON() && "Unexpected register copy without NEON"); 3280 const TargetRegisterInfo *TRI = &getRegisterInfo(); 3281 uint16_t DestEncoding = TRI->getEncodingValue(DestReg); 3282 uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg); 3283 unsigned NumRegs = Indices.size(); 3284 3285 int SubReg = 0, End = NumRegs, Incr = 1; 3286 if (forwardCopyWillClobberTuple(DestEncoding, SrcEncoding, NumRegs)) { 3287 SubReg = NumRegs - 1; 3288 End = -1; 3289 Incr = -1; 3290 } 3291 3292 for (; SubReg != End; SubReg += Incr) { 3293 const MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opcode)); 3294 AddSubReg(MIB, DestReg, Indices[SubReg], RegState::Define, TRI); 3295 AddSubReg(MIB, SrcReg, Indices[SubReg], 0, TRI); 3296 AddSubReg(MIB, SrcReg, Indices[SubReg], getKillRegState(KillSrc), TRI); 3297 } 3298 } 3299 3300 void AArch64InstrInfo::copyGPRRegTuple(MachineBasicBlock &MBB, 3301 MachineBasicBlock::iterator I, 3302 DebugLoc DL, unsigned DestReg, 3303 unsigned SrcReg, bool KillSrc, 3304 unsigned Opcode, unsigned ZeroReg, 3305 llvm::ArrayRef<unsigned> Indices) const { 3306 const TargetRegisterInfo *TRI = &getRegisterInfo(); 3307 unsigned NumRegs = Indices.size(); 3308 3309 #ifndef NDEBUG 3310 uint16_t DestEncoding = TRI->getEncodingValue(DestReg); 3311 uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg); 3312 assert(DestEncoding % NumRegs == 0 && SrcEncoding % NumRegs == 0 && 3313 "GPR reg sequences should not be able to overlap"); 3314 #endif 3315 3316 for (unsigned SubReg = 0; SubReg != NumRegs; ++SubReg) { 3317 const MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opcode)); 3318 AddSubReg(MIB, DestReg, Indices[SubReg], RegState::Define, TRI); 3319 MIB.addReg(ZeroReg); 3320 AddSubReg(MIB, SrcReg, Indices[SubReg], getKillRegState(KillSrc), TRI); 3321 MIB.addImm(0); 3322 } 3323 } 3324 3325 void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 3326 MachineBasicBlock::iterator I, 3327 const DebugLoc &DL, MCRegister DestReg, 3328 MCRegister SrcReg, bool KillSrc) const { 3329 if (AArch64::GPR32spRegClass.contains(DestReg) && 3330 (AArch64::GPR32spRegClass.contains(SrcReg) || SrcReg == AArch64::WZR)) { 3331 const TargetRegisterInfo *TRI = &getRegisterInfo(); 3332 3333 if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) { 3334 // If either operand is WSP, expand to ADD #0. 3335 if (Subtarget.hasZeroCycleRegMove()) { 3336 // Cyclone recognizes "ADD Xd, Xn, #0" as a zero-cycle register move. 3337 MCRegister DestRegX = TRI->getMatchingSuperReg( 3338 DestReg, AArch64::sub_32, &AArch64::GPR64spRegClass); 3339 MCRegister SrcRegX = TRI->getMatchingSuperReg( 3340 SrcReg, AArch64::sub_32, &AArch64::GPR64spRegClass); 3341 // This instruction is reading and writing X registers. This may upset 3342 // the register scavenger and machine verifier, so we need to indicate 3343 // that we are reading an undefined value from SrcRegX, but a proper 3344 // value from SrcReg. 3345 BuildMI(MBB, I, DL, get(AArch64::ADDXri), DestRegX) 3346 .addReg(SrcRegX, RegState::Undef) 3347 .addImm(0) 3348 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)) 3349 .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc)); 3350 } else { 3351 BuildMI(MBB, I, DL, get(AArch64::ADDWri), DestReg) 3352 .addReg(SrcReg, getKillRegState(KillSrc)) 3353 .addImm(0) 3354 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 3355 } 3356 } else if (SrcReg == AArch64::WZR && Subtarget.hasZeroCycleZeroingGP()) { 3357 BuildMI(MBB, I, DL, get(AArch64::MOVZWi), DestReg) 3358 .addImm(0) 3359 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 3360 } else { 3361 if (Subtarget.hasZeroCycleRegMove()) { 3362 // Cyclone recognizes "ORR Xd, XZR, Xm" as a zero-cycle register move. 3363 MCRegister DestRegX = TRI->getMatchingSuperReg( 3364 DestReg, AArch64::sub_32, &AArch64::GPR64spRegClass); 3365 MCRegister SrcRegX = TRI->getMatchingSuperReg( 3366 SrcReg, AArch64::sub_32, &AArch64::GPR64spRegClass); 3367 // This instruction is reading and writing X registers. This may upset 3368 // the register scavenger and machine verifier, so we need to indicate 3369 // that we are reading an undefined value from SrcRegX, but a proper 3370 // value from SrcReg. 3371 BuildMI(MBB, I, DL, get(AArch64::ORRXrr), DestRegX) 3372 .addReg(AArch64::XZR) 3373 .addReg(SrcRegX, RegState::Undef) 3374 .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc)); 3375 } else { 3376 // Otherwise, expand to ORR WZR. 3377 BuildMI(MBB, I, DL, get(AArch64::ORRWrr), DestReg) 3378 .addReg(AArch64::WZR) 3379 .addReg(SrcReg, getKillRegState(KillSrc)); 3380 } 3381 } 3382 return; 3383 } 3384 3385 // Copy a Predicate register by ORRing with itself. 3386 if (AArch64::PPRRegClass.contains(DestReg) && 3387 AArch64::PPRRegClass.contains(SrcReg)) { 3388 assert(Subtarget.hasSVE() && "Unexpected SVE register."); 3389 BuildMI(MBB, I, DL, get(AArch64::ORR_PPzPP), DestReg) 3390 .addReg(SrcReg) // Pg 3391 .addReg(SrcReg) 3392 .addReg(SrcReg, getKillRegState(KillSrc)); 3393 return; 3394 } 3395 3396 // Copy a Z register by ORRing with itself. 3397 if (AArch64::ZPRRegClass.contains(DestReg) && 3398 AArch64::ZPRRegClass.contains(SrcReg)) { 3399 assert(Subtarget.hasSVE() && "Unexpected SVE register."); 3400 BuildMI(MBB, I, DL, get(AArch64::ORR_ZZZ), DestReg) 3401 .addReg(SrcReg) 3402 .addReg(SrcReg, getKillRegState(KillSrc)); 3403 return; 3404 } 3405 3406 // Copy a Z register pair by copying the individual sub-registers. 3407 if (AArch64::ZPR2RegClass.contains(DestReg) && 3408 AArch64::ZPR2RegClass.contains(SrcReg)) { 3409 static const unsigned Indices[] = {AArch64::zsub0, AArch64::zsub1}; 3410 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORR_ZZZ, 3411 Indices); 3412 return; 3413 } 3414 3415 // Copy a Z register triple by copying the individual sub-registers. 3416 if (AArch64::ZPR3RegClass.contains(DestReg) && 3417 AArch64::ZPR3RegClass.contains(SrcReg)) { 3418 static const unsigned Indices[] = {AArch64::zsub0, AArch64::zsub1, 3419 AArch64::zsub2}; 3420 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORR_ZZZ, 3421 Indices); 3422 return; 3423 } 3424 3425 // Copy a Z register quad by copying the individual sub-registers. 3426 if (AArch64::ZPR4RegClass.contains(DestReg) && 3427 AArch64::ZPR4RegClass.contains(SrcReg)) { 3428 static const unsigned Indices[] = {AArch64::zsub0, AArch64::zsub1, 3429 AArch64::zsub2, AArch64::zsub3}; 3430 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORR_ZZZ, 3431 Indices); 3432 return; 3433 } 3434 3435 if (AArch64::GPR64spRegClass.contains(DestReg) && 3436 (AArch64::GPR64spRegClass.contains(SrcReg) || SrcReg == AArch64::XZR)) { 3437 if (DestReg == AArch64::SP || SrcReg == AArch64::SP) { 3438 // If either operand is SP, expand to ADD #0. 3439 BuildMI(MBB, I, DL, get(AArch64::ADDXri), DestReg) 3440 .addReg(SrcReg, getKillRegState(KillSrc)) 3441 .addImm(0) 3442 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 3443 } else if (SrcReg == AArch64::XZR && Subtarget.hasZeroCycleZeroingGP()) { 3444 BuildMI(MBB, I, DL, get(AArch64::MOVZXi), DestReg) 3445 .addImm(0) 3446 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 3447 } else { 3448 // Otherwise, expand to ORR XZR. 3449 BuildMI(MBB, I, DL, get(AArch64::ORRXrr), DestReg) 3450 .addReg(AArch64::XZR) 3451 .addReg(SrcReg, getKillRegState(KillSrc)); 3452 } 3453 return; 3454 } 3455 3456 // Copy a DDDD register quad by copying the individual sub-registers. 3457 if (AArch64::DDDDRegClass.contains(DestReg) && 3458 AArch64::DDDDRegClass.contains(SrcReg)) { 3459 static const unsigned Indices[] = {AArch64::dsub0, AArch64::dsub1, 3460 AArch64::dsub2, AArch64::dsub3}; 3461 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8, 3462 Indices); 3463 return; 3464 } 3465 3466 // Copy a DDD register triple by copying the individual sub-registers. 3467 if (AArch64::DDDRegClass.contains(DestReg) && 3468 AArch64::DDDRegClass.contains(SrcReg)) { 3469 static const unsigned Indices[] = {AArch64::dsub0, AArch64::dsub1, 3470 AArch64::dsub2}; 3471 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8, 3472 Indices); 3473 return; 3474 } 3475 3476 // Copy a DD register pair by copying the individual sub-registers. 3477 if (AArch64::DDRegClass.contains(DestReg) && 3478 AArch64::DDRegClass.contains(SrcReg)) { 3479 static const unsigned Indices[] = {AArch64::dsub0, AArch64::dsub1}; 3480 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8, 3481 Indices); 3482 return; 3483 } 3484 3485 // Copy a QQQQ register quad by copying the individual sub-registers. 3486 if (AArch64::QQQQRegClass.contains(DestReg) && 3487 AArch64::QQQQRegClass.contains(SrcReg)) { 3488 static const unsigned Indices[] = {AArch64::qsub0, AArch64::qsub1, 3489 AArch64::qsub2, AArch64::qsub3}; 3490 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8, 3491 Indices); 3492 return; 3493 } 3494 3495 // Copy a QQQ register triple by copying the individual sub-registers. 3496 if (AArch64::QQQRegClass.contains(DestReg) && 3497 AArch64::QQQRegClass.contains(SrcReg)) { 3498 static const unsigned Indices[] = {AArch64::qsub0, AArch64::qsub1, 3499 AArch64::qsub2}; 3500 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8, 3501 Indices); 3502 return; 3503 } 3504 3505 // Copy a QQ register pair by copying the individual sub-registers. 3506 if (AArch64::QQRegClass.contains(DestReg) && 3507 AArch64::QQRegClass.contains(SrcReg)) { 3508 static const unsigned Indices[] = {AArch64::qsub0, AArch64::qsub1}; 3509 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8, 3510 Indices); 3511 return; 3512 } 3513 3514 if (AArch64::XSeqPairsClassRegClass.contains(DestReg) && 3515 AArch64::XSeqPairsClassRegClass.contains(SrcReg)) { 3516 static const unsigned Indices[] = {AArch64::sube64, AArch64::subo64}; 3517 copyGPRRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRXrs, 3518 AArch64::XZR, Indices); 3519 return; 3520 } 3521 3522 if (AArch64::WSeqPairsClassRegClass.contains(DestReg) && 3523 AArch64::WSeqPairsClassRegClass.contains(SrcReg)) { 3524 static const unsigned Indices[] = {AArch64::sube32, AArch64::subo32}; 3525 copyGPRRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRWrs, 3526 AArch64::WZR, Indices); 3527 return; 3528 } 3529 3530 if (AArch64::FPR128RegClass.contains(DestReg) && 3531 AArch64::FPR128RegClass.contains(SrcReg)) { 3532 if (Subtarget.hasNEON()) { 3533 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 3534 .addReg(SrcReg) 3535 .addReg(SrcReg, getKillRegState(KillSrc)); 3536 } else { 3537 BuildMI(MBB, I, DL, get(AArch64::STRQpre)) 3538 .addReg(AArch64::SP, RegState::Define) 3539 .addReg(SrcReg, getKillRegState(KillSrc)) 3540 .addReg(AArch64::SP) 3541 .addImm(-16); 3542 BuildMI(MBB, I, DL, get(AArch64::LDRQpre)) 3543 .addReg(AArch64::SP, RegState::Define) 3544 .addReg(DestReg, RegState::Define) 3545 .addReg(AArch64::SP) 3546 .addImm(16); 3547 } 3548 return; 3549 } 3550 3551 if (AArch64::FPR64RegClass.contains(DestReg) && 3552 AArch64::FPR64RegClass.contains(SrcReg)) { 3553 BuildMI(MBB, I, DL, get(AArch64::FMOVDr), DestReg) 3554 .addReg(SrcReg, getKillRegState(KillSrc)); 3555 return; 3556 } 3557 3558 if (AArch64::FPR32RegClass.contains(DestReg) && 3559 AArch64::FPR32RegClass.contains(SrcReg)) { 3560 BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg) 3561 .addReg(SrcReg, getKillRegState(KillSrc)); 3562 return; 3563 } 3564 3565 if (AArch64::FPR16RegClass.contains(DestReg) && 3566 AArch64::FPR16RegClass.contains(SrcReg)) { 3567 DestReg = 3568 RI.getMatchingSuperReg(DestReg, AArch64::hsub, &AArch64::FPR32RegClass); 3569 SrcReg = 3570 RI.getMatchingSuperReg(SrcReg, AArch64::hsub, &AArch64::FPR32RegClass); 3571 BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg) 3572 .addReg(SrcReg, getKillRegState(KillSrc)); 3573 return; 3574 } 3575 3576 if (AArch64::FPR8RegClass.contains(DestReg) && 3577 AArch64::FPR8RegClass.contains(SrcReg)) { 3578 DestReg = 3579 RI.getMatchingSuperReg(DestReg, AArch64::bsub, &AArch64::FPR32RegClass); 3580 SrcReg = 3581 RI.getMatchingSuperReg(SrcReg, AArch64::bsub, &AArch64::FPR32RegClass); 3582 BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg) 3583 .addReg(SrcReg, getKillRegState(KillSrc)); 3584 return; 3585 } 3586 3587 // Copies between GPR64 and FPR64. 3588 if (AArch64::FPR64RegClass.contains(DestReg) && 3589 AArch64::GPR64RegClass.contains(SrcReg)) { 3590 BuildMI(MBB, I, DL, get(AArch64::FMOVXDr), DestReg) 3591 .addReg(SrcReg, getKillRegState(KillSrc)); 3592 return; 3593 } 3594 if (AArch64::GPR64RegClass.contains(DestReg) && 3595 AArch64::FPR64RegClass.contains(SrcReg)) { 3596 BuildMI(MBB, I, DL, get(AArch64::FMOVDXr), DestReg) 3597 .addReg(SrcReg, getKillRegState(KillSrc)); 3598 return; 3599 } 3600 // Copies between GPR32 and FPR32. 3601 if (AArch64::FPR32RegClass.contains(DestReg) && 3602 AArch64::GPR32RegClass.contains(SrcReg)) { 3603 BuildMI(MBB, I, DL, get(AArch64::FMOVWSr), DestReg) 3604 .addReg(SrcReg, getKillRegState(KillSrc)); 3605 return; 3606 } 3607 if (AArch64::GPR32RegClass.contains(DestReg) && 3608 AArch64::FPR32RegClass.contains(SrcReg)) { 3609 BuildMI(MBB, I, DL, get(AArch64::FMOVSWr), DestReg) 3610 .addReg(SrcReg, getKillRegState(KillSrc)); 3611 return; 3612 } 3613 3614 if (DestReg == AArch64::NZCV) { 3615 assert(AArch64::GPR64RegClass.contains(SrcReg) && "Invalid NZCV copy"); 3616 BuildMI(MBB, I, DL, get(AArch64::MSR)) 3617 .addImm(AArch64SysReg::NZCV) 3618 .addReg(SrcReg, getKillRegState(KillSrc)) 3619 .addReg(AArch64::NZCV, RegState::Implicit | RegState::Define); 3620 return; 3621 } 3622 3623 if (SrcReg == AArch64::NZCV) { 3624 assert(AArch64::GPR64RegClass.contains(DestReg) && "Invalid NZCV copy"); 3625 BuildMI(MBB, I, DL, get(AArch64::MRS), DestReg) 3626 .addImm(AArch64SysReg::NZCV) 3627 .addReg(AArch64::NZCV, RegState::Implicit | getKillRegState(KillSrc)); 3628 return; 3629 } 3630 3631 #ifndef NDEBUG 3632 const TargetRegisterInfo &TRI = getRegisterInfo(); 3633 errs() << TRI.getRegAsmName(DestReg) << " = COPY " 3634 << TRI.getRegAsmName(SrcReg) << "\n"; 3635 #endif 3636 llvm_unreachable("unimplemented reg-to-reg copy"); 3637 } 3638 3639 static void storeRegPairToStackSlot(const TargetRegisterInfo &TRI, 3640 MachineBasicBlock &MBB, 3641 MachineBasicBlock::iterator InsertBefore, 3642 const MCInstrDesc &MCID, 3643 Register SrcReg, bool IsKill, 3644 unsigned SubIdx0, unsigned SubIdx1, int FI, 3645 MachineMemOperand *MMO) { 3646 Register SrcReg0 = SrcReg; 3647 Register SrcReg1 = SrcReg; 3648 if (Register::isPhysicalRegister(SrcReg)) { 3649 SrcReg0 = TRI.getSubReg(SrcReg, SubIdx0); 3650 SubIdx0 = 0; 3651 SrcReg1 = TRI.getSubReg(SrcReg, SubIdx1); 3652 SubIdx1 = 0; 3653 } 3654 BuildMI(MBB, InsertBefore, DebugLoc(), MCID) 3655 .addReg(SrcReg0, getKillRegState(IsKill), SubIdx0) 3656 .addReg(SrcReg1, getKillRegState(IsKill), SubIdx1) 3657 .addFrameIndex(FI) 3658 .addImm(0) 3659 .addMemOperand(MMO); 3660 } 3661 3662 void AArch64InstrInfo::storeRegToStackSlot( 3663 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, 3664 bool isKill, int FI, const TargetRegisterClass *RC, 3665 const TargetRegisterInfo *TRI) const { 3666 MachineFunction &MF = *MBB.getParent(); 3667 MachineFrameInfo &MFI = MF.getFrameInfo(); 3668 3669 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FI); 3670 MachineMemOperand *MMO = 3671 MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOStore, 3672 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 3673 unsigned Opc = 0; 3674 bool Offset = true; 3675 unsigned StackID = TargetStackID::Default; 3676 switch (TRI->getSpillSize(*RC)) { 3677 case 1: 3678 if (AArch64::FPR8RegClass.hasSubClassEq(RC)) 3679 Opc = AArch64::STRBui; 3680 break; 3681 case 2: 3682 if (AArch64::FPR16RegClass.hasSubClassEq(RC)) 3683 Opc = AArch64::STRHui; 3684 else if (AArch64::PPRRegClass.hasSubClassEq(RC)) { 3685 assert(Subtarget.hasSVE() && "Unexpected register store without SVE"); 3686 Opc = AArch64::STR_PXI; 3687 StackID = TargetStackID::ScalableVector; 3688 } 3689 break; 3690 case 4: 3691 if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) { 3692 Opc = AArch64::STRWui; 3693 if (Register::isVirtualRegister(SrcReg)) 3694 MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR32RegClass); 3695 else 3696 assert(SrcReg != AArch64::WSP); 3697 } else if (AArch64::FPR32RegClass.hasSubClassEq(RC)) 3698 Opc = AArch64::STRSui; 3699 break; 3700 case 8: 3701 if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) { 3702 Opc = AArch64::STRXui; 3703 if (Register::isVirtualRegister(SrcReg)) 3704 MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR64RegClass); 3705 else 3706 assert(SrcReg != AArch64::SP); 3707 } else if (AArch64::FPR64RegClass.hasSubClassEq(RC)) { 3708 Opc = AArch64::STRDui; 3709 } else if (AArch64::WSeqPairsClassRegClass.hasSubClassEq(RC)) { 3710 storeRegPairToStackSlot(getRegisterInfo(), MBB, MBBI, 3711 get(AArch64::STPWi), SrcReg, isKill, 3712 AArch64::sube32, AArch64::subo32, FI, MMO); 3713 return; 3714 } 3715 break; 3716 case 16: 3717 if (AArch64::FPR128RegClass.hasSubClassEq(RC)) 3718 Opc = AArch64::STRQui; 3719 else if (AArch64::DDRegClass.hasSubClassEq(RC)) { 3720 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 3721 Opc = AArch64::ST1Twov1d; 3722 Offset = false; 3723 } else if (AArch64::XSeqPairsClassRegClass.hasSubClassEq(RC)) { 3724 storeRegPairToStackSlot(getRegisterInfo(), MBB, MBBI, 3725 get(AArch64::STPXi), SrcReg, isKill, 3726 AArch64::sube64, AArch64::subo64, FI, MMO); 3727 return; 3728 } else if (AArch64::ZPRRegClass.hasSubClassEq(RC)) { 3729 assert(Subtarget.hasSVE() && "Unexpected register store without SVE"); 3730 Opc = AArch64::STR_ZXI; 3731 StackID = TargetStackID::ScalableVector; 3732 } 3733 break; 3734 case 24: 3735 if (AArch64::DDDRegClass.hasSubClassEq(RC)) { 3736 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 3737 Opc = AArch64::ST1Threev1d; 3738 Offset = false; 3739 } 3740 break; 3741 case 32: 3742 if (AArch64::DDDDRegClass.hasSubClassEq(RC)) { 3743 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 3744 Opc = AArch64::ST1Fourv1d; 3745 Offset = false; 3746 } else if (AArch64::QQRegClass.hasSubClassEq(RC)) { 3747 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 3748 Opc = AArch64::ST1Twov2d; 3749 Offset = false; 3750 } else if (AArch64::ZPR2RegClass.hasSubClassEq(RC)) { 3751 assert(Subtarget.hasSVE() && "Unexpected register store without SVE"); 3752 Opc = AArch64::STR_ZZXI; 3753 StackID = TargetStackID::ScalableVector; 3754 } 3755 break; 3756 case 48: 3757 if (AArch64::QQQRegClass.hasSubClassEq(RC)) { 3758 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 3759 Opc = AArch64::ST1Threev2d; 3760 Offset = false; 3761 } else if (AArch64::ZPR3RegClass.hasSubClassEq(RC)) { 3762 assert(Subtarget.hasSVE() && "Unexpected register store without SVE"); 3763 Opc = AArch64::STR_ZZZXI; 3764 StackID = TargetStackID::ScalableVector; 3765 } 3766 break; 3767 case 64: 3768 if (AArch64::QQQQRegClass.hasSubClassEq(RC)) { 3769 assert(Subtarget.hasNEON() && "Unexpected register store without NEON"); 3770 Opc = AArch64::ST1Fourv2d; 3771 Offset = false; 3772 } else if (AArch64::ZPR4RegClass.hasSubClassEq(RC)) { 3773 assert(Subtarget.hasSVE() && "Unexpected register store without SVE"); 3774 Opc = AArch64::STR_ZZZZXI; 3775 StackID = TargetStackID::ScalableVector; 3776 } 3777 break; 3778 } 3779 assert(Opc && "Unknown register class"); 3780 MFI.setStackID(FI, StackID); 3781 3782 const MachineInstrBuilder MI = BuildMI(MBB, MBBI, DebugLoc(), get(Opc)) 3783 .addReg(SrcReg, getKillRegState(isKill)) 3784 .addFrameIndex(FI); 3785 3786 if (Offset) 3787 MI.addImm(0); 3788 MI.addMemOperand(MMO); 3789 } 3790 3791 static void loadRegPairFromStackSlot(const TargetRegisterInfo &TRI, 3792 MachineBasicBlock &MBB, 3793 MachineBasicBlock::iterator InsertBefore, 3794 const MCInstrDesc &MCID, 3795 Register DestReg, unsigned SubIdx0, 3796 unsigned SubIdx1, int FI, 3797 MachineMemOperand *MMO) { 3798 Register DestReg0 = DestReg; 3799 Register DestReg1 = DestReg; 3800 bool IsUndef = true; 3801 if (Register::isPhysicalRegister(DestReg)) { 3802 DestReg0 = TRI.getSubReg(DestReg, SubIdx0); 3803 SubIdx0 = 0; 3804 DestReg1 = TRI.getSubReg(DestReg, SubIdx1); 3805 SubIdx1 = 0; 3806 IsUndef = false; 3807 } 3808 BuildMI(MBB, InsertBefore, DebugLoc(), MCID) 3809 .addReg(DestReg0, RegState::Define | getUndefRegState(IsUndef), SubIdx0) 3810 .addReg(DestReg1, RegState::Define | getUndefRegState(IsUndef), SubIdx1) 3811 .addFrameIndex(FI) 3812 .addImm(0) 3813 .addMemOperand(MMO); 3814 } 3815 3816 void AArch64InstrInfo::loadRegFromStackSlot( 3817 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, 3818 int FI, const TargetRegisterClass *RC, 3819 const TargetRegisterInfo *TRI) const { 3820 MachineFunction &MF = *MBB.getParent(); 3821 MachineFrameInfo &MFI = MF.getFrameInfo(); 3822 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FI); 3823 MachineMemOperand *MMO = 3824 MF.getMachineMemOperand(PtrInfo, MachineMemOperand::MOLoad, 3825 MFI.getObjectSize(FI), MFI.getObjectAlign(FI)); 3826 3827 unsigned Opc = 0; 3828 bool Offset = true; 3829 unsigned StackID = TargetStackID::Default; 3830 switch (TRI->getSpillSize(*RC)) { 3831 case 1: 3832 if (AArch64::FPR8RegClass.hasSubClassEq(RC)) 3833 Opc = AArch64::LDRBui; 3834 break; 3835 case 2: 3836 if (AArch64::FPR16RegClass.hasSubClassEq(RC)) 3837 Opc = AArch64::LDRHui; 3838 else if (AArch64::PPRRegClass.hasSubClassEq(RC)) { 3839 assert(Subtarget.hasSVE() && "Unexpected register load without SVE"); 3840 Opc = AArch64::LDR_PXI; 3841 StackID = TargetStackID::ScalableVector; 3842 } 3843 break; 3844 case 4: 3845 if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) { 3846 Opc = AArch64::LDRWui; 3847 if (Register::isVirtualRegister(DestReg)) 3848 MF.getRegInfo().constrainRegClass(DestReg, &AArch64::GPR32RegClass); 3849 else 3850 assert(DestReg != AArch64::WSP); 3851 } else if (AArch64::FPR32RegClass.hasSubClassEq(RC)) 3852 Opc = AArch64::LDRSui; 3853 break; 3854 case 8: 3855 if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) { 3856 Opc = AArch64::LDRXui; 3857 if (Register::isVirtualRegister(DestReg)) 3858 MF.getRegInfo().constrainRegClass(DestReg, &AArch64::GPR64RegClass); 3859 else 3860 assert(DestReg != AArch64::SP); 3861 } else if (AArch64::FPR64RegClass.hasSubClassEq(RC)) { 3862 Opc = AArch64::LDRDui; 3863 } else if (AArch64::WSeqPairsClassRegClass.hasSubClassEq(RC)) { 3864 loadRegPairFromStackSlot(getRegisterInfo(), MBB, MBBI, 3865 get(AArch64::LDPWi), DestReg, AArch64::sube32, 3866 AArch64::subo32, FI, MMO); 3867 return; 3868 } 3869 break; 3870 case 16: 3871 if (AArch64::FPR128RegClass.hasSubClassEq(RC)) 3872 Opc = AArch64::LDRQui; 3873 else if (AArch64::DDRegClass.hasSubClassEq(RC)) { 3874 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 3875 Opc = AArch64::LD1Twov1d; 3876 Offset = false; 3877 } else if (AArch64::XSeqPairsClassRegClass.hasSubClassEq(RC)) { 3878 loadRegPairFromStackSlot(getRegisterInfo(), MBB, MBBI, 3879 get(AArch64::LDPXi), DestReg, AArch64::sube64, 3880 AArch64::subo64, FI, MMO); 3881 return; 3882 } else if (AArch64::ZPRRegClass.hasSubClassEq(RC)) { 3883 assert(Subtarget.hasSVE() && "Unexpected register load without SVE"); 3884 Opc = AArch64::LDR_ZXI; 3885 StackID = TargetStackID::ScalableVector; 3886 } 3887 break; 3888 case 24: 3889 if (AArch64::DDDRegClass.hasSubClassEq(RC)) { 3890 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 3891 Opc = AArch64::LD1Threev1d; 3892 Offset = false; 3893 } 3894 break; 3895 case 32: 3896 if (AArch64::DDDDRegClass.hasSubClassEq(RC)) { 3897 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 3898 Opc = AArch64::LD1Fourv1d; 3899 Offset = false; 3900 } else if (AArch64::QQRegClass.hasSubClassEq(RC)) { 3901 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 3902 Opc = AArch64::LD1Twov2d; 3903 Offset = false; 3904 } else if (AArch64::ZPR2RegClass.hasSubClassEq(RC)) { 3905 assert(Subtarget.hasSVE() && "Unexpected register load without SVE"); 3906 Opc = AArch64::LDR_ZZXI; 3907 StackID = TargetStackID::ScalableVector; 3908 } 3909 break; 3910 case 48: 3911 if (AArch64::QQQRegClass.hasSubClassEq(RC)) { 3912 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 3913 Opc = AArch64::LD1Threev2d; 3914 Offset = false; 3915 } else if (AArch64::ZPR3RegClass.hasSubClassEq(RC)) { 3916 assert(Subtarget.hasSVE() && "Unexpected register load without SVE"); 3917 Opc = AArch64::LDR_ZZZXI; 3918 StackID = TargetStackID::ScalableVector; 3919 } 3920 break; 3921 case 64: 3922 if (AArch64::QQQQRegClass.hasSubClassEq(RC)) { 3923 assert(Subtarget.hasNEON() && "Unexpected register load without NEON"); 3924 Opc = AArch64::LD1Fourv2d; 3925 Offset = false; 3926 } else if (AArch64::ZPR4RegClass.hasSubClassEq(RC)) { 3927 assert(Subtarget.hasSVE() && "Unexpected register load without SVE"); 3928 Opc = AArch64::LDR_ZZZZXI; 3929 StackID = TargetStackID::ScalableVector; 3930 } 3931 break; 3932 } 3933 3934 assert(Opc && "Unknown register class"); 3935 MFI.setStackID(FI, StackID); 3936 3937 const MachineInstrBuilder MI = BuildMI(MBB, MBBI, DebugLoc(), get(Opc)) 3938 .addReg(DestReg, getDefRegState(true)) 3939 .addFrameIndex(FI); 3940 if (Offset) 3941 MI.addImm(0); 3942 MI.addMemOperand(MMO); 3943 } 3944 3945 bool llvm::isNZCVTouchedInInstructionRange(const MachineInstr &DefMI, 3946 const MachineInstr &UseMI, 3947 const TargetRegisterInfo *TRI) { 3948 return any_of(instructionsWithoutDebug(std::next(DefMI.getIterator()), 3949 UseMI.getIterator()), 3950 [TRI](const MachineInstr &I) { 3951 return I.modifiesRegister(AArch64::NZCV, TRI) || 3952 I.readsRegister(AArch64::NZCV, TRI); 3953 }); 3954 } 3955 3956 void AArch64InstrInfo::decomposeStackOffsetForDwarfOffsets( 3957 const StackOffset &Offset, int64_t &ByteSized, int64_t &VGSized) { 3958 // The smallest scalable element supported by scaled SVE addressing 3959 // modes are predicates, which are 2 scalable bytes in size. So the scalable 3960 // byte offset must always be a multiple of 2. 3961 assert(Offset.getScalable() % 2 == 0 && "Invalid frame offset"); 3962 3963 // VGSized offsets are divided by '2', because the VG register is the 3964 // the number of 64bit granules as opposed to 128bit vector chunks, 3965 // which is how the 'n' in e.g. MVT::nxv1i8 is modelled. 3966 // So, for a stack offset of 16 MVT::nxv1i8's, the size is n x 16 bytes. 3967 // VG = n * 2 and the dwarf offset must be VG * 8 bytes. 3968 ByteSized = Offset.getFixed(); 3969 VGSized = Offset.getScalable() / 2; 3970 } 3971 3972 /// Returns the offset in parts to which this frame offset can be 3973 /// decomposed for the purpose of describing a frame offset. 3974 /// For non-scalable offsets this is simply its byte size. 3975 void AArch64InstrInfo::decomposeStackOffsetForFrameOffsets( 3976 const StackOffset &Offset, int64_t &NumBytes, int64_t &NumPredicateVectors, 3977 int64_t &NumDataVectors) { 3978 // The smallest scalable element supported by scaled SVE addressing 3979 // modes are predicates, which are 2 scalable bytes in size. So the scalable 3980 // byte offset must always be a multiple of 2. 3981 assert(Offset.getScalable() % 2 == 0 && "Invalid frame offset"); 3982 3983 NumBytes = Offset.getFixed(); 3984 NumDataVectors = 0; 3985 NumPredicateVectors = Offset.getScalable() / 2; 3986 // This method is used to get the offsets to adjust the frame offset. 3987 // If the function requires ADDPL to be used and needs more than two ADDPL 3988 // instructions, part of the offset is folded into NumDataVectors so that it 3989 // uses ADDVL for part of it, reducing the number of ADDPL instructions. 3990 if (NumPredicateVectors % 8 == 0 || NumPredicateVectors < -64 || 3991 NumPredicateVectors > 62) { 3992 NumDataVectors = NumPredicateVectors / 8; 3993 NumPredicateVectors -= NumDataVectors * 8; 3994 } 3995 } 3996 3997 // Helper function to emit a frame offset adjustment from a given 3998 // pointer (SrcReg), stored into DestReg. This function is explicit 3999 // in that it requires the opcode. 4000 static void emitFrameOffsetAdj(MachineBasicBlock &MBB, 4001 MachineBasicBlock::iterator MBBI, 4002 const DebugLoc &DL, unsigned DestReg, 4003 unsigned SrcReg, int64_t Offset, unsigned Opc, 4004 const TargetInstrInfo *TII, 4005 MachineInstr::MIFlag Flag, bool NeedsWinCFI, 4006 bool *HasWinCFI) { 4007 int Sign = 1; 4008 unsigned MaxEncoding, ShiftSize; 4009 switch (Opc) { 4010 case AArch64::ADDXri: 4011 case AArch64::ADDSXri: 4012 case AArch64::SUBXri: 4013 case AArch64::SUBSXri: 4014 MaxEncoding = 0xfff; 4015 ShiftSize = 12; 4016 break; 4017 case AArch64::ADDVL_XXI: 4018 case AArch64::ADDPL_XXI: 4019 MaxEncoding = 31; 4020 ShiftSize = 0; 4021 if (Offset < 0) { 4022 MaxEncoding = 32; 4023 Sign = -1; 4024 Offset = -Offset; 4025 } 4026 break; 4027 default: 4028 llvm_unreachable("Unsupported opcode"); 4029 } 4030 4031 // FIXME: If the offset won't fit in 24-bits, compute the offset into a 4032 // scratch register. If DestReg is a virtual register, use it as the 4033 // scratch register; otherwise, create a new virtual register (to be 4034 // replaced by the scavenger at the end of PEI). That case can be optimized 4035 // slightly if DestReg is SP which is always 16-byte aligned, so the scratch 4036 // register can be loaded with offset%8 and the add/sub can use an extending 4037 // instruction with LSL#3. 4038 // Currently the function handles any offsets but generates a poor sequence 4039 // of code. 4040 // assert(Offset < (1 << 24) && "unimplemented reg plus immediate"); 4041 4042 const unsigned MaxEncodableValue = MaxEncoding << ShiftSize; 4043 Register TmpReg = DestReg; 4044 if (TmpReg == AArch64::XZR) 4045 TmpReg = MBB.getParent()->getRegInfo().createVirtualRegister( 4046 &AArch64::GPR64RegClass); 4047 do { 4048 uint64_t ThisVal = std::min<uint64_t>(Offset, MaxEncodableValue); 4049 unsigned LocalShiftSize = 0; 4050 if (ThisVal > MaxEncoding) { 4051 ThisVal = ThisVal >> ShiftSize; 4052 LocalShiftSize = ShiftSize; 4053 } 4054 assert((ThisVal >> ShiftSize) <= MaxEncoding && 4055 "Encoding cannot handle value that big"); 4056 4057 Offset -= ThisVal << LocalShiftSize; 4058 if (Offset == 0) 4059 TmpReg = DestReg; 4060 auto MBI = BuildMI(MBB, MBBI, DL, TII->get(Opc), TmpReg) 4061 .addReg(SrcReg) 4062 .addImm(Sign * (int)ThisVal); 4063 if (ShiftSize) 4064 MBI = MBI.addImm( 4065 AArch64_AM::getShifterImm(AArch64_AM::LSL, LocalShiftSize)); 4066 MBI = MBI.setMIFlag(Flag); 4067 4068 if (NeedsWinCFI) { 4069 assert(Sign == 1 && "SEH directives should always have a positive sign"); 4070 int Imm = (int)(ThisVal << LocalShiftSize); 4071 if ((DestReg == AArch64::FP && SrcReg == AArch64::SP) || 4072 (SrcReg == AArch64::FP && DestReg == AArch64::SP)) { 4073 if (HasWinCFI) 4074 *HasWinCFI = true; 4075 if (Imm == 0) 4076 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_SetFP)).setMIFlag(Flag); 4077 else 4078 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_AddFP)) 4079 .addImm(Imm) 4080 .setMIFlag(Flag); 4081 assert(Offset == 0 && "Expected remaining offset to be zero to " 4082 "emit a single SEH directive"); 4083 } else if (DestReg == AArch64::SP) { 4084 if (HasWinCFI) 4085 *HasWinCFI = true; 4086 assert(SrcReg == AArch64::SP && "Unexpected SrcReg for SEH_StackAlloc"); 4087 BuildMI(MBB, MBBI, DL, TII->get(AArch64::SEH_StackAlloc)) 4088 .addImm(Imm) 4089 .setMIFlag(Flag); 4090 } 4091 if (HasWinCFI) 4092 *HasWinCFI = true; 4093 } 4094 4095 SrcReg = TmpReg; 4096 } while (Offset); 4097 } 4098 4099 void llvm::emitFrameOffset(MachineBasicBlock &MBB, 4100 MachineBasicBlock::iterator MBBI, const DebugLoc &DL, 4101 unsigned DestReg, unsigned SrcReg, 4102 StackOffset Offset, const TargetInstrInfo *TII, 4103 MachineInstr::MIFlag Flag, bool SetNZCV, 4104 bool NeedsWinCFI, bool *HasWinCFI) { 4105 int64_t Bytes, NumPredicateVectors, NumDataVectors; 4106 AArch64InstrInfo::decomposeStackOffsetForFrameOffsets( 4107 Offset, Bytes, NumPredicateVectors, NumDataVectors); 4108 4109 // First emit non-scalable frame offsets, or a simple 'mov'. 4110 if (Bytes || (!Offset && SrcReg != DestReg)) { 4111 assert((DestReg != AArch64::SP || Bytes % 8 == 0) && 4112 "SP increment/decrement not 8-byte aligned"); 4113 unsigned Opc = SetNZCV ? AArch64::ADDSXri : AArch64::ADDXri; 4114 if (Bytes < 0) { 4115 Bytes = -Bytes; 4116 Opc = SetNZCV ? AArch64::SUBSXri : AArch64::SUBXri; 4117 } 4118 emitFrameOffsetAdj(MBB, MBBI, DL, DestReg, SrcReg, Bytes, Opc, TII, Flag, 4119 NeedsWinCFI, HasWinCFI); 4120 SrcReg = DestReg; 4121 } 4122 4123 assert(!(SetNZCV && (NumPredicateVectors || NumDataVectors)) && 4124 "SetNZCV not supported with SVE vectors"); 4125 assert(!(NeedsWinCFI && (NumPredicateVectors || NumDataVectors)) && 4126 "WinCFI not supported with SVE vectors"); 4127 4128 if (NumDataVectors) { 4129 emitFrameOffsetAdj(MBB, MBBI, DL, DestReg, SrcReg, NumDataVectors, 4130 AArch64::ADDVL_XXI, TII, Flag, NeedsWinCFI, nullptr); 4131 SrcReg = DestReg; 4132 } 4133 4134 if (NumPredicateVectors) { 4135 assert(DestReg != AArch64::SP && "Unaligned access to SP"); 4136 emitFrameOffsetAdj(MBB, MBBI, DL, DestReg, SrcReg, NumPredicateVectors, 4137 AArch64::ADDPL_XXI, TII, Flag, NeedsWinCFI, nullptr); 4138 } 4139 } 4140 4141 MachineInstr *AArch64InstrInfo::foldMemoryOperandImpl( 4142 MachineFunction &MF, MachineInstr &MI, ArrayRef<unsigned> Ops, 4143 MachineBasicBlock::iterator InsertPt, int FrameIndex, 4144 LiveIntervals *LIS, VirtRegMap *VRM) const { 4145 // This is a bit of a hack. Consider this instruction: 4146 // 4147 // %0 = COPY %sp; GPR64all:%0 4148 // 4149 // We explicitly chose GPR64all for the virtual register so such a copy might 4150 // be eliminated by RegisterCoalescer. However, that may not be possible, and 4151 // %0 may even spill. We can't spill %sp, and since it is in the GPR64all 4152 // register class, TargetInstrInfo::foldMemoryOperand() is going to try. 4153 // 4154 // To prevent that, we are going to constrain the %0 register class here. 4155 // 4156 // <rdar://problem/11522048> 4157 // 4158 if (MI.isFullCopy()) { 4159 Register DstReg = MI.getOperand(0).getReg(); 4160 Register SrcReg = MI.getOperand(1).getReg(); 4161 if (SrcReg == AArch64::SP && Register::isVirtualRegister(DstReg)) { 4162 MF.getRegInfo().constrainRegClass(DstReg, &AArch64::GPR64RegClass); 4163 return nullptr; 4164 } 4165 if (DstReg == AArch64::SP && Register::isVirtualRegister(SrcReg)) { 4166 MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR64RegClass); 4167 return nullptr; 4168 } 4169 } 4170 4171 // Handle the case where a copy is being spilled or filled but the source 4172 // and destination register class don't match. For example: 4173 // 4174 // %0 = COPY %xzr; GPR64common:%0 4175 // 4176 // In this case we can still safely fold away the COPY and generate the 4177 // following spill code: 4178 // 4179 // STRXui %xzr, %stack.0 4180 // 4181 // This also eliminates spilled cross register class COPYs (e.g. between x and 4182 // d regs) of the same size. For example: 4183 // 4184 // %0 = COPY %1; GPR64:%0, FPR64:%1 4185 // 4186 // will be filled as 4187 // 4188 // LDRDui %0, fi<#0> 4189 // 4190 // instead of 4191 // 4192 // LDRXui %Temp, fi<#0> 4193 // %0 = FMOV %Temp 4194 // 4195 if (MI.isCopy() && Ops.size() == 1 && 4196 // Make sure we're only folding the explicit COPY defs/uses. 4197 (Ops[0] == 0 || Ops[0] == 1)) { 4198 bool IsSpill = Ops[0] == 0; 4199 bool IsFill = !IsSpill; 4200 const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); 4201 const MachineRegisterInfo &MRI = MF.getRegInfo(); 4202 MachineBasicBlock &MBB = *MI.getParent(); 4203 const MachineOperand &DstMO = MI.getOperand(0); 4204 const MachineOperand &SrcMO = MI.getOperand(1); 4205 Register DstReg = DstMO.getReg(); 4206 Register SrcReg = SrcMO.getReg(); 4207 // This is slightly expensive to compute for physical regs since 4208 // getMinimalPhysRegClass is slow. 4209 auto getRegClass = [&](unsigned Reg) { 4210 return Register::isVirtualRegister(Reg) ? MRI.getRegClass(Reg) 4211 : TRI.getMinimalPhysRegClass(Reg); 4212 }; 4213 4214 if (DstMO.getSubReg() == 0 && SrcMO.getSubReg() == 0) { 4215 assert(TRI.getRegSizeInBits(*getRegClass(DstReg)) == 4216 TRI.getRegSizeInBits(*getRegClass(SrcReg)) && 4217 "Mismatched register size in non subreg COPY"); 4218 if (IsSpill) 4219 storeRegToStackSlot(MBB, InsertPt, SrcReg, SrcMO.isKill(), FrameIndex, 4220 getRegClass(SrcReg), &TRI); 4221 else 4222 loadRegFromStackSlot(MBB, InsertPt, DstReg, FrameIndex, 4223 getRegClass(DstReg), &TRI); 4224 return &*--InsertPt; 4225 } 4226 4227 // Handle cases like spilling def of: 4228 // 4229 // %0:sub_32<def,read-undef> = COPY %wzr; GPR64common:%0 4230 // 4231 // where the physical register source can be widened and stored to the full 4232 // virtual reg destination stack slot, in this case producing: 4233 // 4234 // STRXui %xzr, %stack.0 4235 // 4236 if (IsSpill && DstMO.isUndef() && Register::isPhysicalRegister(SrcReg)) { 4237 assert(SrcMO.getSubReg() == 0 && 4238 "Unexpected subreg on physical register"); 4239 const TargetRegisterClass *SpillRC; 4240 unsigned SpillSubreg; 4241 switch (DstMO.getSubReg()) { 4242 default: 4243 SpillRC = nullptr; 4244 break; 4245 case AArch64::sub_32: 4246 case AArch64::ssub: 4247 if (AArch64::GPR32RegClass.contains(SrcReg)) { 4248 SpillRC = &AArch64::GPR64RegClass; 4249 SpillSubreg = AArch64::sub_32; 4250 } else if (AArch64::FPR32RegClass.contains(SrcReg)) { 4251 SpillRC = &AArch64::FPR64RegClass; 4252 SpillSubreg = AArch64::ssub; 4253 } else 4254 SpillRC = nullptr; 4255 break; 4256 case AArch64::dsub: 4257 if (AArch64::FPR64RegClass.contains(SrcReg)) { 4258 SpillRC = &AArch64::FPR128RegClass; 4259 SpillSubreg = AArch64::dsub; 4260 } else 4261 SpillRC = nullptr; 4262 break; 4263 } 4264 4265 if (SpillRC) 4266 if (unsigned WidenedSrcReg = 4267 TRI.getMatchingSuperReg(SrcReg, SpillSubreg, SpillRC)) { 4268 storeRegToStackSlot(MBB, InsertPt, WidenedSrcReg, SrcMO.isKill(), 4269 FrameIndex, SpillRC, &TRI); 4270 return &*--InsertPt; 4271 } 4272 } 4273 4274 // Handle cases like filling use of: 4275 // 4276 // %0:sub_32<def,read-undef> = COPY %1; GPR64:%0, GPR32:%1 4277 // 4278 // where we can load the full virtual reg source stack slot, into the subreg 4279 // destination, in this case producing: 4280 // 4281 // LDRWui %0:sub_32<def,read-undef>, %stack.0 4282 // 4283 if (IsFill && SrcMO.getSubReg() == 0 && DstMO.isUndef()) { 4284 const TargetRegisterClass *FillRC; 4285 switch (DstMO.getSubReg()) { 4286 default: 4287 FillRC = nullptr; 4288 break; 4289 case AArch64::sub_32: 4290 FillRC = &AArch64::GPR32RegClass; 4291 break; 4292 case AArch64::ssub: 4293 FillRC = &AArch64::FPR32RegClass; 4294 break; 4295 case AArch64::dsub: 4296 FillRC = &AArch64::FPR64RegClass; 4297 break; 4298 } 4299 4300 if (FillRC) { 4301 assert(TRI.getRegSizeInBits(*getRegClass(SrcReg)) == 4302 TRI.getRegSizeInBits(*FillRC) && 4303 "Mismatched regclass size on folded subreg COPY"); 4304 loadRegFromStackSlot(MBB, InsertPt, DstReg, FrameIndex, FillRC, &TRI); 4305 MachineInstr &LoadMI = *--InsertPt; 4306 MachineOperand &LoadDst = LoadMI.getOperand(0); 4307 assert(LoadDst.getSubReg() == 0 && "unexpected subreg on fill load"); 4308 LoadDst.setSubReg(DstMO.getSubReg()); 4309 LoadDst.setIsUndef(); 4310 return &LoadMI; 4311 } 4312 } 4313 } 4314 4315 // Cannot fold. 4316 return nullptr; 4317 } 4318 4319 int llvm::isAArch64FrameOffsetLegal(const MachineInstr &MI, 4320 StackOffset &SOffset, 4321 bool *OutUseUnscaledOp, 4322 unsigned *OutUnscaledOp, 4323 int64_t *EmittableOffset) { 4324 // Set output values in case of early exit. 4325 if (EmittableOffset) 4326 *EmittableOffset = 0; 4327 if (OutUseUnscaledOp) 4328 *OutUseUnscaledOp = false; 4329 if (OutUnscaledOp) 4330 *OutUnscaledOp = 0; 4331 4332 // Exit early for structured vector spills/fills as they can't take an 4333 // immediate offset. 4334 switch (MI.getOpcode()) { 4335 default: 4336 break; 4337 case AArch64::LD1Twov2d: 4338 case AArch64::LD1Threev2d: 4339 case AArch64::LD1Fourv2d: 4340 case AArch64::LD1Twov1d: 4341 case AArch64::LD1Threev1d: 4342 case AArch64::LD1Fourv1d: 4343 case AArch64::ST1Twov2d: 4344 case AArch64::ST1Threev2d: 4345 case AArch64::ST1Fourv2d: 4346 case AArch64::ST1Twov1d: 4347 case AArch64::ST1Threev1d: 4348 case AArch64::ST1Fourv1d: 4349 case AArch64::ST1i8: 4350 case AArch64::ST1i16: 4351 case AArch64::ST1i32: 4352 case AArch64::ST1i64: 4353 case AArch64::IRG: 4354 case AArch64::IRGstack: 4355 case AArch64::STGloop: 4356 case AArch64::STZGloop: 4357 return AArch64FrameOffsetCannotUpdate; 4358 } 4359 4360 // Get the min/max offset and the scale. 4361 TypeSize ScaleValue(0U, false); 4362 unsigned Width; 4363 int64_t MinOff, MaxOff; 4364 if (!AArch64InstrInfo::getMemOpInfo(MI.getOpcode(), ScaleValue, Width, MinOff, 4365 MaxOff)) 4366 llvm_unreachable("unhandled opcode in isAArch64FrameOffsetLegal"); 4367 4368 // Construct the complete offset. 4369 bool IsMulVL = ScaleValue.isScalable(); 4370 unsigned Scale = ScaleValue.getKnownMinSize(); 4371 int64_t Offset = IsMulVL ? SOffset.getScalable() : SOffset.getFixed(); 4372 4373 const MachineOperand &ImmOpnd = 4374 MI.getOperand(AArch64InstrInfo::getLoadStoreImmIdx(MI.getOpcode())); 4375 Offset += ImmOpnd.getImm() * Scale; 4376 4377 // If the offset doesn't match the scale, we rewrite the instruction to 4378 // use the unscaled instruction instead. Likewise, if we have a negative 4379 // offset and there is an unscaled op to use. 4380 Optional<unsigned> UnscaledOp = 4381 AArch64InstrInfo::getUnscaledLdSt(MI.getOpcode()); 4382 bool useUnscaledOp = UnscaledOp && (Offset % Scale || Offset < 0); 4383 if (useUnscaledOp && 4384 !AArch64InstrInfo::getMemOpInfo(*UnscaledOp, ScaleValue, Width, MinOff, 4385 MaxOff)) 4386 llvm_unreachable("unhandled opcode in isAArch64FrameOffsetLegal"); 4387 4388 Scale = ScaleValue.getKnownMinSize(); 4389 assert(IsMulVL == ScaleValue.isScalable() && 4390 "Unscaled opcode has different value for scalable"); 4391 4392 int64_t Remainder = Offset % Scale; 4393 assert(!(Remainder && useUnscaledOp) && 4394 "Cannot have remainder when using unscaled op"); 4395 4396 assert(MinOff < MaxOff && "Unexpected Min/Max offsets"); 4397 int64_t NewOffset = Offset / Scale; 4398 if (MinOff <= NewOffset && NewOffset <= MaxOff) 4399 Offset = Remainder; 4400 else { 4401 NewOffset = NewOffset < 0 ? MinOff : MaxOff; 4402 Offset = Offset - NewOffset * Scale + Remainder; 4403 } 4404 4405 if (EmittableOffset) 4406 *EmittableOffset = NewOffset; 4407 if (OutUseUnscaledOp) 4408 *OutUseUnscaledOp = useUnscaledOp; 4409 if (OutUnscaledOp && UnscaledOp) 4410 *OutUnscaledOp = *UnscaledOp; 4411 4412 if (IsMulVL) 4413 SOffset = StackOffset::get(SOffset.getFixed(), Offset); 4414 else 4415 SOffset = StackOffset::get(Offset, SOffset.getScalable()); 4416 return AArch64FrameOffsetCanUpdate | 4417 (SOffset ? 0 : AArch64FrameOffsetIsLegal); 4418 } 4419 4420 bool llvm::rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 4421 unsigned FrameReg, StackOffset &Offset, 4422 const AArch64InstrInfo *TII) { 4423 unsigned Opcode = MI.getOpcode(); 4424 unsigned ImmIdx = FrameRegIdx + 1; 4425 4426 if (Opcode == AArch64::ADDSXri || Opcode == AArch64::ADDXri) { 4427 Offset += StackOffset::getFixed(MI.getOperand(ImmIdx).getImm()); 4428 emitFrameOffset(*MI.getParent(), MI, MI.getDebugLoc(), 4429 MI.getOperand(0).getReg(), FrameReg, Offset, TII, 4430 MachineInstr::NoFlags, (Opcode == AArch64::ADDSXri)); 4431 MI.eraseFromParent(); 4432 Offset = StackOffset(); 4433 return true; 4434 } 4435 4436 int64_t NewOffset; 4437 unsigned UnscaledOp; 4438 bool UseUnscaledOp; 4439 int Status = isAArch64FrameOffsetLegal(MI, Offset, &UseUnscaledOp, 4440 &UnscaledOp, &NewOffset); 4441 if (Status & AArch64FrameOffsetCanUpdate) { 4442 if (Status & AArch64FrameOffsetIsLegal) 4443 // Replace the FrameIndex with FrameReg. 4444 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 4445 if (UseUnscaledOp) 4446 MI.setDesc(TII->get(UnscaledOp)); 4447 4448 MI.getOperand(ImmIdx).ChangeToImmediate(NewOffset); 4449 return !Offset; 4450 } 4451 4452 return false; 4453 } 4454 4455 MCInst AArch64InstrInfo::getNop() const { 4456 return MCInstBuilder(AArch64::HINT).addImm(0); 4457 } 4458 4459 // AArch64 supports MachineCombiner. 4460 bool AArch64InstrInfo::useMachineCombiner() const { return true; } 4461 4462 // True when Opc sets flag 4463 static bool isCombineInstrSettingFlag(unsigned Opc) { 4464 switch (Opc) { 4465 case AArch64::ADDSWrr: 4466 case AArch64::ADDSWri: 4467 case AArch64::ADDSXrr: 4468 case AArch64::ADDSXri: 4469 case AArch64::SUBSWrr: 4470 case AArch64::SUBSXrr: 4471 // Note: MSUB Wd,Wn,Wm,Wi -> Wd = Wi - WnxWm, not Wd=WnxWm - Wi. 4472 case AArch64::SUBSWri: 4473 case AArch64::SUBSXri: 4474 return true; 4475 default: 4476 break; 4477 } 4478 return false; 4479 } 4480 4481 // 32b Opcodes that can be combined with a MUL 4482 static bool isCombineInstrCandidate32(unsigned Opc) { 4483 switch (Opc) { 4484 case AArch64::ADDWrr: 4485 case AArch64::ADDWri: 4486 case AArch64::SUBWrr: 4487 case AArch64::ADDSWrr: 4488 case AArch64::ADDSWri: 4489 case AArch64::SUBSWrr: 4490 // Note: MSUB Wd,Wn,Wm,Wi -> Wd = Wi - WnxWm, not Wd=WnxWm - Wi. 4491 case AArch64::SUBWri: 4492 case AArch64::SUBSWri: 4493 return true; 4494 default: 4495 break; 4496 } 4497 return false; 4498 } 4499 4500 // 64b Opcodes that can be combined with a MUL 4501 static bool isCombineInstrCandidate64(unsigned Opc) { 4502 switch (Opc) { 4503 case AArch64::ADDXrr: 4504 case AArch64::ADDXri: 4505 case AArch64::SUBXrr: 4506 case AArch64::ADDSXrr: 4507 case AArch64::ADDSXri: 4508 case AArch64::SUBSXrr: 4509 // Note: MSUB Wd,Wn,Wm,Wi -> Wd = Wi - WnxWm, not Wd=WnxWm - Wi. 4510 case AArch64::SUBXri: 4511 case AArch64::SUBSXri: 4512 case AArch64::ADDv8i8: 4513 case AArch64::ADDv16i8: 4514 case AArch64::ADDv4i16: 4515 case AArch64::ADDv8i16: 4516 case AArch64::ADDv2i32: 4517 case AArch64::ADDv4i32: 4518 case AArch64::SUBv8i8: 4519 case AArch64::SUBv16i8: 4520 case AArch64::SUBv4i16: 4521 case AArch64::SUBv8i16: 4522 case AArch64::SUBv2i32: 4523 case AArch64::SUBv4i32: 4524 return true; 4525 default: 4526 break; 4527 } 4528 return false; 4529 } 4530 4531 // FP Opcodes that can be combined with a FMUL. 4532 static bool isCombineInstrCandidateFP(const MachineInstr &Inst) { 4533 switch (Inst.getOpcode()) { 4534 default: 4535 break; 4536 case AArch64::FADDHrr: 4537 case AArch64::FADDSrr: 4538 case AArch64::FADDDrr: 4539 case AArch64::FADDv4f16: 4540 case AArch64::FADDv8f16: 4541 case AArch64::FADDv2f32: 4542 case AArch64::FADDv2f64: 4543 case AArch64::FADDv4f32: 4544 case AArch64::FSUBHrr: 4545 case AArch64::FSUBSrr: 4546 case AArch64::FSUBDrr: 4547 case AArch64::FSUBv4f16: 4548 case AArch64::FSUBv8f16: 4549 case AArch64::FSUBv2f32: 4550 case AArch64::FSUBv2f64: 4551 case AArch64::FSUBv4f32: 4552 TargetOptions Options = Inst.getParent()->getParent()->getTarget().Options; 4553 // We can fuse FADD/FSUB with FMUL, if fusion is either allowed globally by 4554 // the target options or if FADD/FSUB has the contract fast-math flag. 4555 return Options.UnsafeFPMath || 4556 Options.AllowFPOpFusion == FPOpFusion::Fast || 4557 Inst.getFlag(MachineInstr::FmContract); 4558 return true; 4559 } 4560 return false; 4561 } 4562 4563 // Opcodes that can be combined with a MUL 4564 static bool isCombineInstrCandidate(unsigned Opc) { 4565 return (isCombineInstrCandidate32(Opc) || isCombineInstrCandidate64(Opc)); 4566 } 4567 4568 // 4569 // Utility routine that checks if \param MO is defined by an 4570 // \param CombineOpc instruction in the basic block \param MBB 4571 static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, 4572 unsigned CombineOpc, unsigned ZeroReg = 0, 4573 bool CheckZeroReg = false) { 4574 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 4575 MachineInstr *MI = nullptr; 4576 4577 if (MO.isReg() && Register::isVirtualRegister(MO.getReg())) 4578 MI = MRI.getUniqueVRegDef(MO.getReg()); 4579 // And it needs to be in the trace (otherwise, it won't have a depth). 4580 if (!MI || MI->getParent() != &MBB || (unsigned)MI->getOpcode() != CombineOpc) 4581 return false; 4582 // Must only used by the user we combine with. 4583 if (!MRI.hasOneNonDBGUse(MI->getOperand(0).getReg())) 4584 return false; 4585 4586 if (CheckZeroReg) { 4587 assert(MI->getNumOperands() >= 4 && MI->getOperand(0).isReg() && 4588 MI->getOperand(1).isReg() && MI->getOperand(2).isReg() && 4589 MI->getOperand(3).isReg() && "MAdd/MSub must have a least 4 regs"); 4590 // The third input reg must be zero. 4591 if (MI->getOperand(3).getReg() != ZeroReg) 4592 return false; 4593 } 4594 4595 return true; 4596 } 4597 4598 // 4599 // Is \param MO defined by an integer multiply and can be combined? 4600 static bool canCombineWithMUL(MachineBasicBlock &MBB, MachineOperand &MO, 4601 unsigned MulOpc, unsigned ZeroReg) { 4602 return canCombine(MBB, MO, MulOpc, ZeroReg, true); 4603 } 4604 4605 // 4606 // Is \param MO defined by a floating-point multiply and can be combined? 4607 static bool canCombineWithFMUL(MachineBasicBlock &MBB, MachineOperand &MO, 4608 unsigned MulOpc) { 4609 return canCombine(MBB, MO, MulOpc); 4610 } 4611 4612 // TODO: There are many more machine instruction opcodes to match: 4613 // 1. Other data types (integer, vectors) 4614 // 2. Other math / logic operations (xor, or) 4615 // 3. Other forms of the same operation (intrinsics and other variants) 4616 bool AArch64InstrInfo::isAssociativeAndCommutative( 4617 const MachineInstr &Inst) const { 4618 switch (Inst.getOpcode()) { 4619 case AArch64::FADDDrr: 4620 case AArch64::FADDSrr: 4621 case AArch64::FADDv2f32: 4622 case AArch64::FADDv2f64: 4623 case AArch64::FADDv4f32: 4624 case AArch64::FMULDrr: 4625 case AArch64::FMULSrr: 4626 case AArch64::FMULX32: 4627 case AArch64::FMULX64: 4628 case AArch64::FMULXv2f32: 4629 case AArch64::FMULXv2f64: 4630 case AArch64::FMULXv4f32: 4631 case AArch64::FMULv2f32: 4632 case AArch64::FMULv2f64: 4633 case AArch64::FMULv4f32: 4634 return Inst.getParent()->getParent()->getTarget().Options.UnsafeFPMath; 4635 default: 4636 return false; 4637 } 4638 } 4639 4640 /// Find instructions that can be turned into madd. 4641 static bool getMaddPatterns(MachineInstr &Root, 4642 SmallVectorImpl<MachineCombinerPattern> &Patterns) { 4643 unsigned Opc = Root.getOpcode(); 4644 MachineBasicBlock &MBB = *Root.getParent(); 4645 bool Found = false; 4646 4647 if (!isCombineInstrCandidate(Opc)) 4648 return false; 4649 if (isCombineInstrSettingFlag(Opc)) { 4650 int Cmp_NZCV = Root.findRegisterDefOperandIdx(AArch64::NZCV, true); 4651 // When NZCV is live bail out. 4652 if (Cmp_NZCV == -1) 4653 return false; 4654 unsigned NewOpc = convertToNonFlagSettingOpc(Root); 4655 // When opcode can't change bail out. 4656 // CHECKME: do we miss any cases for opcode conversion? 4657 if (NewOpc == Opc) 4658 return false; 4659 Opc = NewOpc; 4660 } 4661 4662 auto setFound = [&](int Opcode, int Operand, unsigned ZeroReg, 4663 MachineCombinerPattern Pattern) { 4664 if (canCombineWithMUL(MBB, Root.getOperand(Operand), Opcode, ZeroReg)) { 4665 Patterns.push_back(Pattern); 4666 Found = true; 4667 } 4668 }; 4669 4670 auto setVFound = [&](int Opcode, int Operand, MachineCombinerPattern Pattern) { 4671 if (canCombine(MBB, Root.getOperand(Operand), Opcode)) { 4672 Patterns.push_back(Pattern); 4673 Found = true; 4674 } 4675 }; 4676 4677 typedef MachineCombinerPattern MCP; 4678 4679 switch (Opc) { 4680 default: 4681 break; 4682 case AArch64::ADDWrr: 4683 assert(Root.getOperand(1).isReg() && Root.getOperand(2).isReg() && 4684 "ADDWrr does not have register operands"); 4685 setFound(AArch64::MADDWrrr, 1, AArch64::WZR, MCP::MULADDW_OP1); 4686 setFound(AArch64::MADDWrrr, 2, AArch64::WZR, MCP::MULADDW_OP2); 4687 break; 4688 case AArch64::ADDXrr: 4689 setFound(AArch64::MADDXrrr, 1, AArch64::XZR, MCP::MULADDX_OP1); 4690 setFound(AArch64::MADDXrrr, 2, AArch64::XZR, MCP::MULADDX_OP2); 4691 break; 4692 case AArch64::SUBWrr: 4693 setFound(AArch64::MADDWrrr, 1, AArch64::WZR, MCP::MULSUBW_OP1); 4694 setFound(AArch64::MADDWrrr, 2, AArch64::WZR, MCP::MULSUBW_OP2); 4695 break; 4696 case AArch64::SUBXrr: 4697 setFound(AArch64::MADDXrrr, 1, AArch64::XZR, MCP::MULSUBX_OP1); 4698 setFound(AArch64::MADDXrrr, 2, AArch64::XZR, MCP::MULSUBX_OP2); 4699 break; 4700 case AArch64::ADDWri: 4701 setFound(AArch64::MADDWrrr, 1, AArch64::WZR, MCP::MULADDWI_OP1); 4702 break; 4703 case AArch64::ADDXri: 4704 setFound(AArch64::MADDXrrr, 1, AArch64::XZR, MCP::MULADDXI_OP1); 4705 break; 4706 case AArch64::SUBWri: 4707 setFound(AArch64::MADDWrrr, 1, AArch64::WZR, MCP::MULSUBWI_OP1); 4708 break; 4709 case AArch64::SUBXri: 4710 setFound(AArch64::MADDXrrr, 1, AArch64::XZR, MCP::MULSUBXI_OP1); 4711 break; 4712 case AArch64::ADDv8i8: 4713 setVFound(AArch64::MULv8i8, 1, MCP::MULADDv8i8_OP1); 4714 setVFound(AArch64::MULv8i8, 2, MCP::MULADDv8i8_OP2); 4715 break; 4716 case AArch64::ADDv16i8: 4717 setVFound(AArch64::MULv16i8, 1, MCP::MULADDv16i8_OP1); 4718 setVFound(AArch64::MULv16i8, 2, MCP::MULADDv16i8_OP2); 4719 break; 4720 case AArch64::ADDv4i16: 4721 setVFound(AArch64::MULv4i16, 1, MCP::MULADDv4i16_OP1); 4722 setVFound(AArch64::MULv4i16, 2, MCP::MULADDv4i16_OP2); 4723 setVFound(AArch64::MULv4i16_indexed, 1, MCP::MULADDv4i16_indexed_OP1); 4724 setVFound(AArch64::MULv4i16_indexed, 2, MCP::MULADDv4i16_indexed_OP2); 4725 break; 4726 case AArch64::ADDv8i16: 4727 setVFound(AArch64::MULv8i16, 1, MCP::MULADDv8i16_OP1); 4728 setVFound(AArch64::MULv8i16, 2, MCP::MULADDv8i16_OP2); 4729 setVFound(AArch64::MULv8i16_indexed, 1, MCP::MULADDv8i16_indexed_OP1); 4730 setVFound(AArch64::MULv8i16_indexed, 2, MCP::MULADDv8i16_indexed_OP2); 4731 break; 4732 case AArch64::ADDv2i32: 4733 setVFound(AArch64::MULv2i32, 1, MCP::MULADDv2i32_OP1); 4734 setVFound(AArch64::MULv2i32, 2, MCP::MULADDv2i32_OP2); 4735 setVFound(AArch64::MULv2i32_indexed, 1, MCP::MULADDv2i32_indexed_OP1); 4736 setVFound(AArch64::MULv2i32_indexed, 2, MCP::MULADDv2i32_indexed_OP2); 4737 break; 4738 case AArch64::ADDv4i32: 4739 setVFound(AArch64::MULv4i32, 1, MCP::MULADDv4i32_OP1); 4740 setVFound(AArch64::MULv4i32, 2, MCP::MULADDv4i32_OP2); 4741 setVFound(AArch64::MULv4i32_indexed, 1, MCP::MULADDv4i32_indexed_OP1); 4742 setVFound(AArch64::MULv4i32_indexed, 2, MCP::MULADDv4i32_indexed_OP2); 4743 break; 4744 case AArch64::SUBv8i8: 4745 setVFound(AArch64::MULv8i8, 1, MCP::MULSUBv8i8_OP1); 4746 setVFound(AArch64::MULv8i8, 2, MCP::MULSUBv8i8_OP2); 4747 break; 4748 case AArch64::SUBv16i8: 4749 setVFound(AArch64::MULv16i8, 1, MCP::MULSUBv16i8_OP1); 4750 setVFound(AArch64::MULv16i8, 2, MCP::MULSUBv16i8_OP2); 4751 break; 4752 case AArch64::SUBv4i16: 4753 setVFound(AArch64::MULv4i16, 1, MCP::MULSUBv4i16_OP1); 4754 setVFound(AArch64::MULv4i16, 2, MCP::MULSUBv4i16_OP2); 4755 setVFound(AArch64::MULv4i16_indexed, 1, MCP::MULSUBv4i16_indexed_OP1); 4756 setVFound(AArch64::MULv4i16_indexed, 2, MCP::MULSUBv4i16_indexed_OP2); 4757 break; 4758 case AArch64::SUBv8i16: 4759 setVFound(AArch64::MULv8i16, 1, MCP::MULSUBv8i16_OP1); 4760 setVFound(AArch64::MULv8i16, 2, MCP::MULSUBv8i16_OP2); 4761 setVFound(AArch64::MULv8i16_indexed, 1, MCP::MULSUBv8i16_indexed_OP1); 4762 setVFound(AArch64::MULv8i16_indexed, 2, MCP::MULSUBv8i16_indexed_OP2); 4763 break; 4764 case AArch64::SUBv2i32: 4765 setVFound(AArch64::MULv2i32, 1, MCP::MULSUBv2i32_OP1); 4766 setVFound(AArch64::MULv2i32, 2, MCP::MULSUBv2i32_OP2); 4767 setVFound(AArch64::MULv2i32_indexed, 1, MCP::MULSUBv2i32_indexed_OP1); 4768 setVFound(AArch64::MULv2i32_indexed, 2, MCP::MULSUBv2i32_indexed_OP2); 4769 break; 4770 case AArch64::SUBv4i32: 4771 setVFound(AArch64::MULv4i32, 1, MCP::MULSUBv4i32_OP1); 4772 setVFound(AArch64::MULv4i32, 2, MCP::MULSUBv4i32_OP2); 4773 setVFound(AArch64::MULv4i32_indexed, 1, MCP::MULSUBv4i32_indexed_OP1); 4774 setVFound(AArch64::MULv4i32_indexed, 2, MCP::MULSUBv4i32_indexed_OP2); 4775 break; 4776 } 4777 return Found; 4778 } 4779 /// Floating-Point Support 4780 4781 /// Find instructions that can be turned into madd. 4782 static bool getFMAPatterns(MachineInstr &Root, 4783 SmallVectorImpl<MachineCombinerPattern> &Patterns) { 4784 4785 if (!isCombineInstrCandidateFP(Root)) 4786 return false; 4787 4788 MachineBasicBlock &MBB = *Root.getParent(); 4789 bool Found = false; 4790 4791 auto Match = [&](int Opcode, int Operand, 4792 MachineCombinerPattern Pattern) -> bool { 4793 if (canCombineWithFMUL(MBB, Root.getOperand(Operand), Opcode)) { 4794 Patterns.push_back(Pattern); 4795 return true; 4796 } 4797 return false; 4798 }; 4799 4800 typedef MachineCombinerPattern MCP; 4801 4802 switch (Root.getOpcode()) { 4803 default: 4804 assert(false && "Unsupported FP instruction in combiner\n"); 4805 break; 4806 case AArch64::FADDHrr: 4807 assert(Root.getOperand(1).isReg() && Root.getOperand(2).isReg() && 4808 "FADDHrr does not have register operands"); 4809 4810 Found = Match(AArch64::FMULHrr, 1, MCP::FMULADDH_OP1); 4811 Found |= Match(AArch64::FMULHrr, 2, MCP::FMULADDH_OP2); 4812 break; 4813 case AArch64::FADDSrr: 4814 assert(Root.getOperand(1).isReg() && Root.getOperand(2).isReg() && 4815 "FADDSrr does not have register operands"); 4816 4817 Found |= Match(AArch64::FMULSrr, 1, MCP::FMULADDS_OP1) || 4818 Match(AArch64::FMULv1i32_indexed, 1, MCP::FMLAv1i32_indexed_OP1); 4819 4820 Found |= Match(AArch64::FMULSrr, 2, MCP::FMULADDS_OP2) || 4821 Match(AArch64::FMULv1i32_indexed, 2, MCP::FMLAv1i32_indexed_OP2); 4822 break; 4823 case AArch64::FADDDrr: 4824 Found |= Match(AArch64::FMULDrr, 1, MCP::FMULADDD_OP1) || 4825 Match(AArch64::FMULv1i64_indexed, 1, MCP::FMLAv1i64_indexed_OP1); 4826 4827 Found |= Match(AArch64::FMULDrr, 2, MCP::FMULADDD_OP2) || 4828 Match(AArch64::FMULv1i64_indexed, 2, MCP::FMLAv1i64_indexed_OP2); 4829 break; 4830 case AArch64::FADDv4f16: 4831 Found |= Match(AArch64::FMULv4i16_indexed, 1, MCP::FMLAv4i16_indexed_OP1) || 4832 Match(AArch64::FMULv4f16, 1, MCP::FMLAv4f16_OP1); 4833 4834 Found |= Match(AArch64::FMULv4i16_indexed, 2, MCP::FMLAv4i16_indexed_OP2) || 4835 Match(AArch64::FMULv4f16, 2, MCP::FMLAv4f16_OP2); 4836 break; 4837 case AArch64::FADDv8f16: 4838 Found |= Match(AArch64::FMULv8i16_indexed, 1, MCP::FMLAv8i16_indexed_OP1) || 4839 Match(AArch64::FMULv8f16, 1, MCP::FMLAv8f16_OP1); 4840 4841 Found |= Match(AArch64::FMULv8i16_indexed, 2, MCP::FMLAv8i16_indexed_OP2) || 4842 Match(AArch64::FMULv8f16, 2, MCP::FMLAv8f16_OP2); 4843 break; 4844 case AArch64::FADDv2f32: 4845 Found |= Match(AArch64::FMULv2i32_indexed, 1, MCP::FMLAv2i32_indexed_OP1) || 4846 Match(AArch64::FMULv2f32, 1, MCP::FMLAv2f32_OP1); 4847 4848 Found |= Match(AArch64::FMULv2i32_indexed, 2, MCP::FMLAv2i32_indexed_OP2) || 4849 Match(AArch64::FMULv2f32, 2, MCP::FMLAv2f32_OP2); 4850 break; 4851 case AArch64::FADDv2f64: 4852 Found |= Match(AArch64::FMULv2i64_indexed, 1, MCP::FMLAv2i64_indexed_OP1) || 4853 Match(AArch64::FMULv2f64, 1, MCP::FMLAv2f64_OP1); 4854 4855 Found |= Match(AArch64::FMULv2i64_indexed, 2, MCP::FMLAv2i64_indexed_OP2) || 4856 Match(AArch64::FMULv2f64, 2, MCP::FMLAv2f64_OP2); 4857 break; 4858 case AArch64::FADDv4f32: 4859 Found |= Match(AArch64::FMULv4i32_indexed, 1, MCP::FMLAv4i32_indexed_OP1) || 4860 Match(AArch64::FMULv4f32, 1, MCP::FMLAv4f32_OP1); 4861 4862 Found |= Match(AArch64::FMULv4i32_indexed, 2, MCP::FMLAv4i32_indexed_OP2) || 4863 Match(AArch64::FMULv4f32, 2, MCP::FMLAv4f32_OP2); 4864 break; 4865 case AArch64::FSUBHrr: 4866 Found = Match(AArch64::FMULHrr, 1, MCP::FMULSUBH_OP1); 4867 Found |= Match(AArch64::FMULHrr, 2, MCP::FMULSUBH_OP2); 4868 Found |= Match(AArch64::FNMULHrr, 1, MCP::FNMULSUBH_OP1); 4869 break; 4870 case AArch64::FSUBSrr: 4871 Found = Match(AArch64::FMULSrr, 1, MCP::FMULSUBS_OP1); 4872 4873 Found |= Match(AArch64::FMULSrr, 2, MCP::FMULSUBS_OP2) || 4874 Match(AArch64::FMULv1i32_indexed, 2, MCP::FMLSv1i32_indexed_OP2); 4875 4876 Found |= Match(AArch64::FNMULSrr, 1, MCP::FNMULSUBS_OP1); 4877 break; 4878 case AArch64::FSUBDrr: 4879 Found = Match(AArch64::FMULDrr, 1, MCP::FMULSUBD_OP1); 4880 4881 Found |= Match(AArch64::FMULDrr, 2, MCP::FMULSUBD_OP2) || 4882 Match(AArch64::FMULv1i64_indexed, 2, MCP::FMLSv1i64_indexed_OP2); 4883 4884 Found |= Match(AArch64::FNMULDrr, 1, MCP::FNMULSUBD_OP1); 4885 break; 4886 case AArch64::FSUBv4f16: 4887 Found |= Match(AArch64::FMULv4i16_indexed, 2, MCP::FMLSv4i16_indexed_OP2) || 4888 Match(AArch64::FMULv4f16, 2, MCP::FMLSv4f16_OP2); 4889 4890 Found |= Match(AArch64::FMULv4i16_indexed, 1, MCP::FMLSv4i16_indexed_OP1) || 4891 Match(AArch64::FMULv4f16, 1, MCP::FMLSv4f16_OP1); 4892 break; 4893 case AArch64::FSUBv8f16: 4894 Found |= Match(AArch64::FMULv8i16_indexed, 2, MCP::FMLSv8i16_indexed_OP2) || 4895 Match(AArch64::FMULv8f16, 2, MCP::FMLSv8f16_OP2); 4896 4897 Found |= Match(AArch64::FMULv8i16_indexed, 1, MCP::FMLSv8i16_indexed_OP1) || 4898 Match(AArch64::FMULv8f16, 1, MCP::FMLSv8f16_OP1); 4899 break; 4900 case AArch64::FSUBv2f32: 4901 Found |= Match(AArch64::FMULv2i32_indexed, 2, MCP::FMLSv2i32_indexed_OP2) || 4902 Match(AArch64::FMULv2f32, 2, MCP::FMLSv2f32_OP2); 4903 4904 Found |= Match(AArch64::FMULv2i32_indexed, 1, MCP::FMLSv2i32_indexed_OP1) || 4905 Match(AArch64::FMULv2f32, 1, MCP::FMLSv2f32_OP1); 4906 break; 4907 case AArch64::FSUBv2f64: 4908 Found |= Match(AArch64::FMULv2i64_indexed, 2, MCP::FMLSv2i64_indexed_OP2) || 4909 Match(AArch64::FMULv2f64, 2, MCP::FMLSv2f64_OP2); 4910 4911 Found |= Match(AArch64::FMULv2i64_indexed, 1, MCP::FMLSv2i64_indexed_OP1) || 4912 Match(AArch64::FMULv2f64, 1, MCP::FMLSv2f64_OP1); 4913 break; 4914 case AArch64::FSUBv4f32: 4915 Found |= Match(AArch64::FMULv4i32_indexed, 2, MCP::FMLSv4i32_indexed_OP2) || 4916 Match(AArch64::FMULv4f32, 2, MCP::FMLSv4f32_OP2); 4917 4918 Found |= Match(AArch64::FMULv4i32_indexed, 1, MCP::FMLSv4i32_indexed_OP1) || 4919 Match(AArch64::FMULv4f32, 1, MCP::FMLSv4f32_OP1); 4920 break; 4921 } 4922 return Found; 4923 } 4924 4925 static bool getFMULPatterns(MachineInstr &Root, 4926 SmallVectorImpl<MachineCombinerPattern> &Patterns) { 4927 MachineBasicBlock &MBB = *Root.getParent(); 4928 bool Found = false; 4929 4930 auto Match = [&](unsigned Opcode, int Operand, 4931 MachineCombinerPattern Pattern) -> bool { 4932 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 4933 MachineOperand &MO = Root.getOperand(Operand); 4934 MachineInstr *MI = nullptr; 4935 if (MO.isReg() && Register::isVirtualRegister(MO.getReg())) 4936 MI = MRI.getUniqueVRegDef(MO.getReg()); 4937 if (MI && MI->getOpcode() == Opcode) { 4938 Patterns.push_back(Pattern); 4939 return true; 4940 } 4941 return false; 4942 }; 4943 4944 typedef MachineCombinerPattern MCP; 4945 4946 switch (Root.getOpcode()) { 4947 default: 4948 return false; 4949 case AArch64::FMULv2f32: 4950 Found = Match(AArch64::DUPv2i32lane, 1, MCP::FMULv2i32_indexed_OP1); 4951 Found |= Match(AArch64::DUPv2i32lane, 2, MCP::FMULv2i32_indexed_OP2); 4952 break; 4953 case AArch64::FMULv2f64: 4954 Found = Match(AArch64::DUPv2i64lane, 1, MCP::FMULv2i64_indexed_OP1); 4955 Found |= Match(AArch64::DUPv2i64lane, 2, MCP::FMULv2i64_indexed_OP2); 4956 break; 4957 case AArch64::FMULv4f16: 4958 Found = Match(AArch64::DUPv4i16lane, 1, MCP::FMULv4i16_indexed_OP1); 4959 Found |= Match(AArch64::DUPv4i16lane, 2, MCP::FMULv4i16_indexed_OP2); 4960 break; 4961 case AArch64::FMULv4f32: 4962 Found = Match(AArch64::DUPv4i32lane, 1, MCP::FMULv4i32_indexed_OP1); 4963 Found |= Match(AArch64::DUPv4i32lane, 2, MCP::FMULv4i32_indexed_OP2); 4964 break; 4965 case AArch64::FMULv8f16: 4966 Found = Match(AArch64::DUPv8i16lane, 1, MCP::FMULv8i16_indexed_OP1); 4967 Found |= Match(AArch64::DUPv8i16lane, 2, MCP::FMULv8i16_indexed_OP2); 4968 break; 4969 } 4970 4971 return Found; 4972 } 4973 4974 /// Return true when a code sequence can improve throughput. It 4975 /// should be called only for instructions in loops. 4976 /// \param Pattern - combiner pattern 4977 bool AArch64InstrInfo::isThroughputPattern( 4978 MachineCombinerPattern Pattern) const { 4979 switch (Pattern) { 4980 default: 4981 break; 4982 case MachineCombinerPattern::FMULADDH_OP1: 4983 case MachineCombinerPattern::FMULADDH_OP2: 4984 case MachineCombinerPattern::FMULSUBH_OP1: 4985 case MachineCombinerPattern::FMULSUBH_OP2: 4986 case MachineCombinerPattern::FMULADDS_OP1: 4987 case MachineCombinerPattern::FMULADDS_OP2: 4988 case MachineCombinerPattern::FMULSUBS_OP1: 4989 case MachineCombinerPattern::FMULSUBS_OP2: 4990 case MachineCombinerPattern::FMULADDD_OP1: 4991 case MachineCombinerPattern::FMULADDD_OP2: 4992 case MachineCombinerPattern::FMULSUBD_OP1: 4993 case MachineCombinerPattern::FMULSUBD_OP2: 4994 case MachineCombinerPattern::FNMULSUBH_OP1: 4995 case MachineCombinerPattern::FNMULSUBS_OP1: 4996 case MachineCombinerPattern::FNMULSUBD_OP1: 4997 case MachineCombinerPattern::FMLAv4i16_indexed_OP1: 4998 case MachineCombinerPattern::FMLAv4i16_indexed_OP2: 4999 case MachineCombinerPattern::FMLAv8i16_indexed_OP1: 5000 case MachineCombinerPattern::FMLAv8i16_indexed_OP2: 5001 case MachineCombinerPattern::FMLAv1i32_indexed_OP1: 5002 case MachineCombinerPattern::FMLAv1i32_indexed_OP2: 5003 case MachineCombinerPattern::FMLAv1i64_indexed_OP1: 5004 case MachineCombinerPattern::FMLAv1i64_indexed_OP2: 5005 case MachineCombinerPattern::FMLAv4f16_OP2: 5006 case MachineCombinerPattern::FMLAv4f16_OP1: 5007 case MachineCombinerPattern::FMLAv8f16_OP1: 5008 case MachineCombinerPattern::FMLAv8f16_OP2: 5009 case MachineCombinerPattern::FMLAv2f32_OP2: 5010 case MachineCombinerPattern::FMLAv2f32_OP1: 5011 case MachineCombinerPattern::FMLAv2f64_OP1: 5012 case MachineCombinerPattern::FMLAv2f64_OP2: 5013 case MachineCombinerPattern::FMLAv2i32_indexed_OP1: 5014 case MachineCombinerPattern::FMLAv2i32_indexed_OP2: 5015 case MachineCombinerPattern::FMLAv2i64_indexed_OP1: 5016 case MachineCombinerPattern::FMLAv2i64_indexed_OP2: 5017 case MachineCombinerPattern::FMLAv4f32_OP1: 5018 case MachineCombinerPattern::FMLAv4f32_OP2: 5019 case MachineCombinerPattern::FMLAv4i32_indexed_OP1: 5020 case MachineCombinerPattern::FMLAv4i32_indexed_OP2: 5021 case MachineCombinerPattern::FMLSv4i16_indexed_OP1: 5022 case MachineCombinerPattern::FMLSv4i16_indexed_OP2: 5023 case MachineCombinerPattern::FMLSv8i16_indexed_OP1: 5024 case MachineCombinerPattern::FMLSv8i16_indexed_OP2: 5025 case MachineCombinerPattern::FMLSv1i32_indexed_OP2: 5026 case MachineCombinerPattern::FMLSv1i64_indexed_OP2: 5027 case MachineCombinerPattern::FMLSv2i32_indexed_OP2: 5028 case MachineCombinerPattern::FMLSv2i64_indexed_OP2: 5029 case MachineCombinerPattern::FMLSv4f16_OP1: 5030 case MachineCombinerPattern::FMLSv4f16_OP2: 5031 case MachineCombinerPattern::FMLSv8f16_OP1: 5032 case MachineCombinerPattern::FMLSv8f16_OP2: 5033 case MachineCombinerPattern::FMLSv2f32_OP2: 5034 case MachineCombinerPattern::FMLSv2f64_OP2: 5035 case MachineCombinerPattern::FMLSv4i32_indexed_OP2: 5036 case MachineCombinerPattern::FMLSv4f32_OP2: 5037 case MachineCombinerPattern::FMULv2i32_indexed_OP1: 5038 case MachineCombinerPattern::FMULv2i32_indexed_OP2: 5039 case MachineCombinerPattern::FMULv2i64_indexed_OP1: 5040 case MachineCombinerPattern::FMULv2i64_indexed_OP2: 5041 case MachineCombinerPattern::FMULv4i16_indexed_OP1: 5042 case MachineCombinerPattern::FMULv4i16_indexed_OP2: 5043 case MachineCombinerPattern::FMULv4i32_indexed_OP1: 5044 case MachineCombinerPattern::FMULv4i32_indexed_OP2: 5045 case MachineCombinerPattern::FMULv8i16_indexed_OP1: 5046 case MachineCombinerPattern::FMULv8i16_indexed_OP2: 5047 case MachineCombinerPattern::MULADDv8i8_OP1: 5048 case MachineCombinerPattern::MULADDv8i8_OP2: 5049 case MachineCombinerPattern::MULADDv16i8_OP1: 5050 case MachineCombinerPattern::MULADDv16i8_OP2: 5051 case MachineCombinerPattern::MULADDv4i16_OP1: 5052 case MachineCombinerPattern::MULADDv4i16_OP2: 5053 case MachineCombinerPattern::MULADDv8i16_OP1: 5054 case MachineCombinerPattern::MULADDv8i16_OP2: 5055 case MachineCombinerPattern::MULADDv2i32_OP1: 5056 case MachineCombinerPattern::MULADDv2i32_OP2: 5057 case MachineCombinerPattern::MULADDv4i32_OP1: 5058 case MachineCombinerPattern::MULADDv4i32_OP2: 5059 case MachineCombinerPattern::MULSUBv8i8_OP1: 5060 case MachineCombinerPattern::MULSUBv8i8_OP2: 5061 case MachineCombinerPattern::MULSUBv16i8_OP1: 5062 case MachineCombinerPattern::MULSUBv16i8_OP2: 5063 case MachineCombinerPattern::MULSUBv4i16_OP1: 5064 case MachineCombinerPattern::MULSUBv4i16_OP2: 5065 case MachineCombinerPattern::MULSUBv8i16_OP1: 5066 case MachineCombinerPattern::MULSUBv8i16_OP2: 5067 case MachineCombinerPattern::MULSUBv2i32_OP1: 5068 case MachineCombinerPattern::MULSUBv2i32_OP2: 5069 case MachineCombinerPattern::MULSUBv4i32_OP1: 5070 case MachineCombinerPattern::MULSUBv4i32_OP2: 5071 case MachineCombinerPattern::MULADDv4i16_indexed_OP1: 5072 case MachineCombinerPattern::MULADDv4i16_indexed_OP2: 5073 case MachineCombinerPattern::MULADDv8i16_indexed_OP1: 5074 case MachineCombinerPattern::MULADDv8i16_indexed_OP2: 5075 case MachineCombinerPattern::MULADDv2i32_indexed_OP1: 5076 case MachineCombinerPattern::MULADDv2i32_indexed_OP2: 5077 case MachineCombinerPattern::MULADDv4i32_indexed_OP1: 5078 case MachineCombinerPattern::MULADDv4i32_indexed_OP2: 5079 case MachineCombinerPattern::MULSUBv4i16_indexed_OP1: 5080 case MachineCombinerPattern::MULSUBv4i16_indexed_OP2: 5081 case MachineCombinerPattern::MULSUBv8i16_indexed_OP1: 5082 case MachineCombinerPattern::MULSUBv8i16_indexed_OP2: 5083 case MachineCombinerPattern::MULSUBv2i32_indexed_OP1: 5084 case MachineCombinerPattern::MULSUBv2i32_indexed_OP2: 5085 case MachineCombinerPattern::MULSUBv4i32_indexed_OP1: 5086 case MachineCombinerPattern::MULSUBv4i32_indexed_OP2: 5087 return true; 5088 } // end switch (Pattern) 5089 return false; 5090 } 5091 /// Return true when there is potentially a faster code sequence for an 5092 /// instruction chain ending in \p Root. All potential patterns are listed in 5093 /// the \p Pattern vector. Pattern should be sorted in priority order since the 5094 /// pattern evaluator stops checking as soon as it finds a faster sequence. 5095 5096 bool AArch64InstrInfo::getMachineCombinerPatterns( 5097 MachineInstr &Root, SmallVectorImpl<MachineCombinerPattern> &Patterns, 5098 bool DoRegPressureReduce) const { 5099 // Integer patterns 5100 if (getMaddPatterns(Root, Patterns)) 5101 return true; 5102 // Floating point patterns 5103 if (getFMULPatterns(Root, Patterns)) 5104 return true; 5105 if (getFMAPatterns(Root, Patterns)) 5106 return true; 5107 5108 return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns, 5109 DoRegPressureReduce); 5110 } 5111 5112 enum class FMAInstKind { Default, Indexed, Accumulator }; 5113 /// genFusedMultiply - Generate fused multiply instructions. 5114 /// This function supports both integer and floating point instructions. 5115 /// A typical example: 5116 /// F|MUL I=A,B,0 5117 /// F|ADD R,I,C 5118 /// ==> F|MADD R,A,B,C 5119 /// \param MF Containing MachineFunction 5120 /// \param MRI Register information 5121 /// \param TII Target information 5122 /// \param Root is the F|ADD instruction 5123 /// \param [out] InsInstrs is a vector of machine instructions and will 5124 /// contain the generated madd instruction 5125 /// \param IdxMulOpd is index of operand in Root that is the result of 5126 /// the F|MUL. In the example above IdxMulOpd is 1. 5127 /// \param MaddOpc the opcode fo the f|madd instruction 5128 /// \param RC Register class of operands 5129 /// \param kind of fma instruction (addressing mode) to be generated 5130 /// \param ReplacedAddend is the result register from the instruction 5131 /// replacing the non-combined operand, if any. 5132 static MachineInstr * 5133 genFusedMultiply(MachineFunction &MF, MachineRegisterInfo &MRI, 5134 const TargetInstrInfo *TII, MachineInstr &Root, 5135 SmallVectorImpl<MachineInstr *> &InsInstrs, unsigned IdxMulOpd, 5136 unsigned MaddOpc, const TargetRegisterClass *RC, 5137 FMAInstKind kind = FMAInstKind::Default, 5138 const Register *ReplacedAddend = nullptr) { 5139 assert(IdxMulOpd == 1 || IdxMulOpd == 2); 5140 5141 unsigned IdxOtherOpd = IdxMulOpd == 1 ? 2 : 1; 5142 MachineInstr *MUL = MRI.getUniqueVRegDef(Root.getOperand(IdxMulOpd).getReg()); 5143 Register ResultReg = Root.getOperand(0).getReg(); 5144 Register SrcReg0 = MUL->getOperand(1).getReg(); 5145 bool Src0IsKill = MUL->getOperand(1).isKill(); 5146 Register SrcReg1 = MUL->getOperand(2).getReg(); 5147 bool Src1IsKill = MUL->getOperand(2).isKill(); 5148 5149 unsigned SrcReg2; 5150 bool Src2IsKill; 5151 if (ReplacedAddend) { 5152 // If we just generated a new addend, we must be it's only use. 5153 SrcReg2 = *ReplacedAddend; 5154 Src2IsKill = true; 5155 } else { 5156 SrcReg2 = Root.getOperand(IdxOtherOpd).getReg(); 5157 Src2IsKill = Root.getOperand(IdxOtherOpd).isKill(); 5158 } 5159 5160 if (Register::isVirtualRegister(ResultReg)) 5161 MRI.constrainRegClass(ResultReg, RC); 5162 if (Register::isVirtualRegister(SrcReg0)) 5163 MRI.constrainRegClass(SrcReg0, RC); 5164 if (Register::isVirtualRegister(SrcReg1)) 5165 MRI.constrainRegClass(SrcReg1, RC); 5166 if (Register::isVirtualRegister(SrcReg2)) 5167 MRI.constrainRegClass(SrcReg2, RC); 5168 5169 MachineInstrBuilder MIB; 5170 if (kind == FMAInstKind::Default) 5171 MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 5172 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 5173 .addReg(SrcReg1, getKillRegState(Src1IsKill)) 5174 .addReg(SrcReg2, getKillRegState(Src2IsKill)); 5175 else if (kind == FMAInstKind::Indexed) 5176 MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 5177 .addReg(SrcReg2, getKillRegState(Src2IsKill)) 5178 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 5179 .addReg(SrcReg1, getKillRegState(Src1IsKill)) 5180 .addImm(MUL->getOperand(3).getImm()); 5181 else if (kind == FMAInstKind::Accumulator) 5182 MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 5183 .addReg(SrcReg2, getKillRegState(Src2IsKill)) 5184 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 5185 .addReg(SrcReg1, getKillRegState(Src1IsKill)); 5186 else 5187 assert(false && "Invalid FMA instruction kind \n"); 5188 // Insert the MADD (MADD, FMA, FMS, FMLA, FMSL) 5189 InsInstrs.push_back(MIB); 5190 return MUL; 5191 } 5192 5193 /// Fold (FMUL x (DUP y lane)) into (FMUL_indexed x y lane) 5194 static MachineInstr * 5195 genIndexedMultiply(MachineInstr &Root, 5196 SmallVectorImpl<MachineInstr *> &InsInstrs, 5197 unsigned IdxDupOp, unsigned MulOpc, 5198 const TargetRegisterClass *RC, MachineRegisterInfo &MRI) { 5199 assert(((IdxDupOp == 1) || (IdxDupOp == 2)) && 5200 "Invalid index of FMUL operand"); 5201 5202 MachineFunction &MF = *Root.getMF(); 5203 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 5204 5205 MachineInstr *Dup = 5206 MF.getRegInfo().getUniqueVRegDef(Root.getOperand(IdxDupOp).getReg()); 5207 5208 Register DupSrcReg = Dup->getOperand(1).getReg(); 5209 MRI.clearKillFlags(DupSrcReg); 5210 MRI.constrainRegClass(DupSrcReg, RC); 5211 5212 unsigned DupSrcLane = Dup->getOperand(2).getImm(); 5213 5214 unsigned IdxMulOp = IdxDupOp == 1 ? 2 : 1; 5215 MachineOperand &MulOp = Root.getOperand(IdxMulOp); 5216 5217 Register ResultReg = Root.getOperand(0).getReg(); 5218 5219 MachineInstrBuilder MIB; 5220 MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MulOpc), ResultReg) 5221 .add(MulOp) 5222 .addReg(DupSrcReg) 5223 .addImm(DupSrcLane); 5224 5225 InsInstrs.push_back(MIB); 5226 return &Root; 5227 } 5228 5229 /// genFusedMultiplyAcc - Helper to generate fused multiply accumulate 5230 /// instructions. 5231 /// 5232 /// \see genFusedMultiply 5233 static MachineInstr *genFusedMultiplyAcc( 5234 MachineFunction &MF, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, 5235 MachineInstr &Root, SmallVectorImpl<MachineInstr *> &InsInstrs, 5236 unsigned IdxMulOpd, unsigned MaddOpc, const TargetRegisterClass *RC) { 5237 return genFusedMultiply(MF, MRI, TII, Root, InsInstrs, IdxMulOpd, MaddOpc, RC, 5238 FMAInstKind::Accumulator); 5239 } 5240 5241 /// genNeg - Helper to generate an intermediate negation of the second operand 5242 /// of Root 5243 static Register genNeg(MachineFunction &MF, MachineRegisterInfo &MRI, 5244 const TargetInstrInfo *TII, MachineInstr &Root, 5245 SmallVectorImpl<MachineInstr *> &InsInstrs, 5246 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg, 5247 unsigned MnegOpc, const TargetRegisterClass *RC) { 5248 Register NewVR = MRI.createVirtualRegister(RC); 5249 MachineInstrBuilder MIB = 5250 BuildMI(MF, Root.getDebugLoc(), TII->get(MnegOpc), NewVR) 5251 .add(Root.getOperand(2)); 5252 InsInstrs.push_back(MIB); 5253 5254 assert(InstrIdxForVirtReg.empty()); 5255 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 5256 5257 return NewVR; 5258 } 5259 5260 /// genFusedMultiplyAccNeg - Helper to generate fused multiply accumulate 5261 /// instructions with an additional negation of the accumulator 5262 static MachineInstr *genFusedMultiplyAccNeg( 5263 MachineFunction &MF, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, 5264 MachineInstr &Root, SmallVectorImpl<MachineInstr *> &InsInstrs, 5265 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg, unsigned IdxMulOpd, 5266 unsigned MaddOpc, unsigned MnegOpc, const TargetRegisterClass *RC) { 5267 assert(IdxMulOpd == 1); 5268 5269 Register NewVR = 5270 genNeg(MF, MRI, TII, Root, InsInstrs, InstrIdxForVirtReg, MnegOpc, RC); 5271 return genFusedMultiply(MF, MRI, TII, Root, InsInstrs, IdxMulOpd, MaddOpc, RC, 5272 FMAInstKind::Accumulator, &NewVR); 5273 } 5274 5275 /// genFusedMultiplyIdx - Helper to generate fused multiply accumulate 5276 /// instructions. 5277 /// 5278 /// \see genFusedMultiply 5279 static MachineInstr *genFusedMultiplyIdx( 5280 MachineFunction &MF, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, 5281 MachineInstr &Root, SmallVectorImpl<MachineInstr *> &InsInstrs, 5282 unsigned IdxMulOpd, unsigned MaddOpc, const TargetRegisterClass *RC) { 5283 return genFusedMultiply(MF, MRI, TII, Root, InsInstrs, IdxMulOpd, MaddOpc, RC, 5284 FMAInstKind::Indexed); 5285 } 5286 5287 /// genFusedMultiplyAccNeg - Helper to generate fused multiply accumulate 5288 /// instructions with an additional negation of the accumulator 5289 static MachineInstr *genFusedMultiplyIdxNeg( 5290 MachineFunction &MF, MachineRegisterInfo &MRI, const TargetInstrInfo *TII, 5291 MachineInstr &Root, SmallVectorImpl<MachineInstr *> &InsInstrs, 5292 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg, unsigned IdxMulOpd, 5293 unsigned MaddOpc, unsigned MnegOpc, const TargetRegisterClass *RC) { 5294 assert(IdxMulOpd == 1); 5295 5296 Register NewVR = 5297 genNeg(MF, MRI, TII, Root, InsInstrs, InstrIdxForVirtReg, MnegOpc, RC); 5298 5299 return genFusedMultiply(MF, MRI, TII, Root, InsInstrs, IdxMulOpd, MaddOpc, RC, 5300 FMAInstKind::Indexed, &NewVR); 5301 } 5302 5303 /// genMaddR - Generate madd instruction and combine mul and add using 5304 /// an extra virtual register 5305 /// Example - an ADD intermediate needs to be stored in a register: 5306 /// MUL I=A,B,0 5307 /// ADD R,I,Imm 5308 /// ==> ORR V, ZR, Imm 5309 /// ==> MADD R,A,B,V 5310 /// \param MF Containing MachineFunction 5311 /// \param MRI Register information 5312 /// \param TII Target information 5313 /// \param Root is the ADD instruction 5314 /// \param [out] InsInstrs is a vector of machine instructions and will 5315 /// contain the generated madd instruction 5316 /// \param IdxMulOpd is index of operand in Root that is the result of 5317 /// the MUL. In the example above IdxMulOpd is 1. 5318 /// \param MaddOpc the opcode fo the madd instruction 5319 /// \param VR is a virtual register that holds the value of an ADD operand 5320 /// (V in the example above). 5321 /// \param RC Register class of operands 5322 static MachineInstr *genMaddR(MachineFunction &MF, MachineRegisterInfo &MRI, 5323 const TargetInstrInfo *TII, MachineInstr &Root, 5324 SmallVectorImpl<MachineInstr *> &InsInstrs, 5325 unsigned IdxMulOpd, unsigned MaddOpc, unsigned VR, 5326 const TargetRegisterClass *RC) { 5327 assert(IdxMulOpd == 1 || IdxMulOpd == 2); 5328 5329 MachineInstr *MUL = MRI.getUniqueVRegDef(Root.getOperand(IdxMulOpd).getReg()); 5330 Register ResultReg = Root.getOperand(0).getReg(); 5331 Register SrcReg0 = MUL->getOperand(1).getReg(); 5332 bool Src0IsKill = MUL->getOperand(1).isKill(); 5333 Register SrcReg1 = MUL->getOperand(2).getReg(); 5334 bool Src1IsKill = MUL->getOperand(2).isKill(); 5335 5336 if (Register::isVirtualRegister(ResultReg)) 5337 MRI.constrainRegClass(ResultReg, RC); 5338 if (Register::isVirtualRegister(SrcReg0)) 5339 MRI.constrainRegClass(SrcReg0, RC); 5340 if (Register::isVirtualRegister(SrcReg1)) 5341 MRI.constrainRegClass(SrcReg1, RC); 5342 if (Register::isVirtualRegister(VR)) 5343 MRI.constrainRegClass(VR, RC); 5344 5345 MachineInstrBuilder MIB = 5346 BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 5347 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 5348 .addReg(SrcReg1, getKillRegState(Src1IsKill)) 5349 .addReg(VR); 5350 // Insert the MADD 5351 InsInstrs.push_back(MIB); 5352 return MUL; 5353 } 5354 5355 /// When getMachineCombinerPatterns() finds potential patterns, 5356 /// this function generates the instructions that could replace the 5357 /// original code sequence 5358 void AArch64InstrInfo::genAlternativeCodeSequence( 5359 MachineInstr &Root, MachineCombinerPattern Pattern, 5360 SmallVectorImpl<MachineInstr *> &InsInstrs, 5361 SmallVectorImpl<MachineInstr *> &DelInstrs, 5362 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const { 5363 MachineBasicBlock &MBB = *Root.getParent(); 5364 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 5365 MachineFunction &MF = *MBB.getParent(); 5366 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 5367 5368 MachineInstr *MUL = nullptr; 5369 const TargetRegisterClass *RC; 5370 unsigned Opc; 5371 switch (Pattern) { 5372 default: 5373 // Reassociate instructions. 5374 TargetInstrInfo::genAlternativeCodeSequence(Root, Pattern, InsInstrs, 5375 DelInstrs, InstrIdxForVirtReg); 5376 return; 5377 case MachineCombinerPattern::MULADDW_OP1: 5378 case MachineCombinerPattern::MULADDX_OP1: 5379 // MUL I=A,B,0 5380 // ADD R,I,C 5381 // ==> MADD R,A,B,C 5382 // --- Create(MADD); 5383 if (Pattern == MachineCombinerPattern::MULADDW_OP1) { 5384 Opc = AArch64::MADDWrrr; 5385 RC = &AArch64::GPR32RegClass; 5386 } else { 5387 Opc = AArch64::MADDXrrr; 5388 RC = &AArch64::GPR64RegClass; 5389 } 5390 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5391 break; 5392 case MachineCombinerPattern::MULADDW_OP2: 5393 case MachineCombinerPattern::MULADDX_OP2: 5394 // MUL I=A,B,0 5395 // ADD R,C,I 5396 // ==> MADD R,A,B,C 5397 // --- Create(MADD); 5398 if (Pattern == MachineCombinerPattern::MULADDW_OP2) { 5399 Opc = AArch64::MADDWrrr; 5400 RC = &AArch64::GPR32RegClass; 5401 } else { 5402 Opc = AArch64::MADDXrrr; 5403 RC = &AArch64::GPR64RegClass; 5404 } 5405 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5406 break; 5407 case MachineCombinerPattern::MULADDWI_OP1: 5408 case MachineCombinerPattern::MULADDXI_OP1: { 5409 // MUL I=A,B,0 5410 // ADD R,I,Imm 5411 // ==> ORR V, ZR, Imm 5412 // ==> MADD R,A,B,V 5413 // --- Create(MADD); 5414 const TargetRegisterClass *OrrRC; 5415 unsigned BitSize, OrrOpc, ZeroReg; 5416 if (Pattern == MachineCombinerPattern::MULADDWI_OP1) { 5417 OrrOpc = AArch64::ORRWri; 5418 OrrRC = &AArch64::GPR32spRegClass; 5419 BitSize = 32; 5420 ZeroReg = AArch64::WZR; 5421 Opc = AArch64::MADDWrrr; 5422 RC = &AArch64::GPR32RegClass; 5423 } else { 5424 OrrOpc = AArch64::ORRXri; 5425 OrrRC = &AArch64::GPR64spRegClass; 5426 BitSize = 64; 5427 ZeroReg = AArch64::XZR; 5428 Opc = AArch64::MADDXrrr; 5429 RC = &AArch64::GPR64RegClass; 5430 } 5431 Register NewVR = MRI.createVirtualRegister(OrrRC); 5432 uint64_t Imm = Root.getOperand(2).getImm(); 5433 5434 if (Root.getOperand(3).isImm()) { 5435 unsigned Val = Root.getOperand(3).getImm(); 5436 Imm = Imm << Val; 5437 } 5438 uint64_t UImm = SignExtend64(Imm, BitSize); 5439 uint64_t Encoding; 5440 if (!AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding)) 5441 return; 5442 MachineInstrBuilder MIB1 = 5443 BuildMI(MF, Root.getDebugLoc(), TII->get(OrrOpc), NewVR) 5444 .addReg(ZeroReg) 5445 .addImm(Encoding); 5446 InsInstrs.push_back(MIB1); 5447 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 5448 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC); 5449 break; 5450 } 5451 case MachineCombinerPattern::MULSUBW_OP1: 5452 case MachineCombinerPattern::MULSUBX_OP1: { 5453 // MUL I=A,B,0 5454 // SUB R,I, C 5455 // ==> SUB V, 0, C 5456 // ==> MADD R,A,B,V // = -C + A*B 5457 // --- Create(MADD); 5458 const TargetRegisterClass *SubRC; 5459 unsigned SubOpc, ZeroReg; 5460 if (Pattern == MachineCombinerPattern::MULSUBW_OP1) { 5461 SubOpc = AArch64::SUBWrr; 5462 SubRC = &AArch64::GPR32spRegClass; 5463 ZeroReg = AArch64::WZR; 5464 Opc = AArch64::MADDWrrr; 5465 RC = &AArch64::GPR32RegClass; 5466 } else { 5467 SubOpc = AArch64::SUBXrr; 5468 SubRC = &AArch64::GPR64spRegClass; 5469 ZeroReg = AArch64::XZR; 5470 Opc = AArch64::MADDXrrr; 5471 RC = &AArch64::GPR64RegClass; 5472 } 5473 Register NewVR = MRI.createVirtualRegister(SubRC); 5474 // SUB NewVR, 0, C 5475 MachineInstrBuilder MIB1 = 5476 BuildMI(MF, Root.getDebugLoc(), TII->get(SubOpc), NewVR) 5477 .addReg(ZeroReg) 5478 .add(Root.getOperand(2)); 5479 InsInstrs.push_back(MIB1); 5480 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 5481 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC); 5482 break; 5483 } 5484 case MachineCombinerPattern::MULSUBW_OP2: 5485 case MachineCombinerPattern::MULSUBX_OP2: 5486 // MUL I=A,B,0 5487 // SUB R,C,I 5488 // ==> MSUB R,A,B,C (computes C - A*B) 5489 // --- Create(MSUB); 5490 if (Pattern == MachineCombinerPattern::MULSUBW_OP2) { 5491 Opc = AArch64::MSUBWrrr; 5492 RC = &AArch64::GPR32RegClass; 5493 } else { 5494 Opc = AArch64::MSUBXrrr; 5495 RC = &AArch64::GPR64RegClass; 5496 } 5497 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5498 break; 5499 case MachineCombinerPattern::MULSUBWI_OP1: 5500 case MachineCombinerPattern::MULSUBXI_OP1: { 5501 // MUL I=A,B,0 5502 // SUB R,I, Imm 5503 // ==> ORR V, ZR, -Imm 5504 // ==> MADD R,A,B,V // = -Imm + A*B 5505 // --- Create(MADD); 5506 const TargetRegisterClass *OrrRC; 5507 unsigned BitSize, OrrOpc, ZeroReg; 5508 if (Pattern == MachineCombinerPattern::MULSUBWI_OP1) { 5509 OrrOpc = AArch64::ORRWri; 5510 OrrRC = &AArch64::GPR32spRegClass; 5511 BitSize = 32; 5512 ZeroReg = AArch64::WZR; 5513 Opc = AArch64::MADDWrrr; 5514 RC = &AArch64::GPR32RegClass; 5515 } else { 5516 OrrOpc = AArch64::ORRXri; 5517 OrrRC = &AArch64::GPR64spRegClass; 5518 BitSize = 64; 5519 ZeroReg = AArch64::XZR; 5520 Opc = AArch64::MADDXrrr; 5521 RC = &AArch64::GPR64RegClass; 5522 } 5523 Register NewVR = MRI.createVirtualRegister(OrrRC); 5524 uint64_t Imm = Root.getOperand(2).getImm(); 5525 if (Root.getOperand(3).isImm()) { 5526 unsigned Val = Root.getOperand(3).getImm(); 5527 Imm = Imm << Val; 5528 } 5529 uint64_t UImm = SignExtend64(-Imm, BitSize); 5530 uint64_t Encoding; 5531 if (!AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding)) 5532 return; 5533 MachineInstrBuilder MIB1 = 5534 BuildMI(MF, Root.getDebugLoc(), TII->get(OrrOpc), NewVR) 5535 .addReg(ZeroReg) 5536 .addImm(Encoding); 5537 InsInstrs.push_back(MIB1); 5538 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 5539 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC); 5540 break; 5541 } 5542 5543 case MachineCombinerPattern::MULADDv8i8_OP1: 5544 Opc = AArch64::MLAv8i8; 5545 RC = &AArch64::FPR64RegClass; 5546 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5547 break; 5548 case MachineCombinerPattern::MULADDv8i8_OP2: 5549 Opc = AArch64::MLAv8i8; 5550 RC = &AArch64::FPR64RegClass; 5551 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5552 break; 5553 case MachineCombinerPattern::MULADDv16i8_OP1: 5554 Opc = AArch64::MLAv16i8; 5555 RC = &AArch64::FPR128RegClass; 5556 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5557 break; 5558 case MachineCombinerPattern::MULADDv16i8_OP2: 5559 Opc = AArch64::MLAv16i8; 5560 RC = &AArch64::FPR128RegClass; 5561 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5562 break; 5563 case MachineCombinerPattern::MULADDv4i16_OP1: 5564 Opc = AArch64::MLAv4i16; 5565 RC = &AArch64::FPR64RegClass; 5566 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5567 break; 5568 case MachineCombinerPattern::MULADDv4i16_OP2: 5569 Opc = AArch64::MLAv4i16; 5570 RC = &AArch64::FPR64RegClass; 5571 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5572 break; 5573 case MachineCombinerPattern::MULADDv8i16_OP1: 5574 Opc = AArch64::MLAv8i16; 5575 RC = &AArch64::FPR128RegClass; 5576 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5577 break; 5578 case MachineCombinerPattern::MULADDv8i16_OP2: 5579 Opc = AArch64::MLAv8i16; 5580 RC = &AArch64::FPR128RegClass; 5581 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5582 break; 5583 case MachineCombinerPattern::MULADDv2i32_OP1: 5584 Opc = AArch64::MLAv2i32; 5585 RC = &AArch64::FPR64RegClass; 5586 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5587 break; 5588 case MachineCombinerPattern::MULADDv2i32_OP2: 5589 Opc = AArch64::MLAv2i32; 5590 RC = &AArch64::FPR64RegClass; 5591 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5592 break; 5593 case MachineCombinerPattern::MULADDv4i32_OP1: 5594 Opc = AArch64::MLAv4i32; 5595 RC = &AArch64::FPR128RegClass; 5596 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5597 break; 5598 case MachineCombinerPattern::MULADDv4i32_OP2: 5599 Opc = AArch64::MLAv4i32; 5600 RC = &AArch64::FPR128RegClass; 5601 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5602 break; 5603 5604 case MachineCombinerPattern::MULSUBv8i8_OP1: 5605 Opc = AArch64::MLAv8i8; 5606 RC = &AArch64::FPR64RegClass; 5607 MUL = genFusedMultiplyAccNeg(MF, MRI, TII, Root, InsInstrs, 5608 InstrIdxForVirtReg, 1, Opc, AArch64::NEGv8i8, 5609 RC); 5610 break; 5611 case MachineCombinerPattern::MULSUBv8i8_OP2: 5612 Opc = AArch64::MLSv8i8; 5613 RC = &AArch64::FPR64RegClass; 5614 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5615 break; 5616 case MachineCombinerPattern::MULSUBv16i8_OP1: 5617 Opc = AArch64::MLAv16i8; 5618 RC = &AArch64::FPR128RegClass; 5619 MUL = genFusedMultiplyAccNeg(MF, MRI, TII, Root, InsInstrs, 5620 InstrIdxForVirtReg, 1, Opc, AArch64::NEGv16i8, 5621 RC); 5622 break; 5623 case MachineCombinerPattern::MULSUBv16i8_OP2: 5624 Opc = AArch64::MLSv16i8; 5625 RC = &AArch64::FPR128RegClass; 5626 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5627 break; 5628 case MachineCombinerPattern::MULSUBv4i16_OP1: 5629 Opc = AArch64::MLAv4i16; 5630 RC = &AArch64::FPR64RegClass; 5631 MUL = genFusedMultiplyAccNeg(MF, MRI, TII, Root, InsInstrs, 5632 InstrIdxForVirtReg, 1, Opc, AArch64::NEGv4i16, 5633 RC); 5634 break; 5635 case MachineCombinerPattern::MULSUBv4i16_OP2: 5636 Opc = AArch64::MLSv4i16; 5637 RC = &AArch64::FPR64RegClass; 5638 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5639 break; 5640 case MachineCombinerPattern::MULSUBv8i16_OP1: 5641 Opc = AArch64::MLAv8i16; 5642 RC = &AArch64::FPR128RegClass; 5643 MUL = genFusedMultiplyAccNeg(MF, MRI, TII, Root, InsInstrs, 5644 InstrIdxForVirtReg, 1, Opc, AArch64::NEGv8i16, 5645 RC); 5646 break; 5647 case MachineCombinerPattern::MULSUBv8i16_OP2: 5648 Opc = AArch64::MLSv8i16; 5649 RC = &AArch64::FPR128RegClass; 5650 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5651 break; 5652 case MachineCombinerPattern::MULSUBv2i32_OP1: 5653 Opc = AArch64::MLAv2i32; 5654 RC = &AArch64::FPR64RegClass; 5655 MUL = genFusedMultiplyAccNeg(MF, MRI, TII, Root, InsInstrs, 5656 InstrIdxForVirtReg, 1, Opc, AArch64::NEGv2i32, 5657 RC); 5658 break; 5659 case MachineCombinerPattern::MULSUBv2i32_OP2: 5660 Opc = AArch64::MLSv2i32; 5661 RC = &AArch64::FPR64RegClass; 5662 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5663 break; 5664 case MachineCombinerPattern::MULSUBv4i32_OP1: 5665 Opc = AArch64::MLAv4i32; 5666 RC = &AArch64::FPR128RegClass; 5667 MUL = genFusedMultiplyAccNeg(MF, MRI, TII, Root, InsInstrs, 5668 InstrIdxForVirtReg, 1, Opc, AArch64::NEGv4i32, 5669 RC); 5670 break; 5671 case MachineCombinerPattern::MULSUBv4i32_OP2: 5672 Opc = AArch64::MLSv4i32; 5673 RC = &AArch64::FPR128RegClass; 5674 MUL = genFusedMultiplyAcc(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5675 break; 5676 5677 case MachineCombinerPattern::MULADDv4i16_indexed_OP1: 5678 Opc = AArch64::MLAv4i16_indexed; 5679 RC = &AArch64::FPR64RegClass; 5680 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5681 break; 5682 case MachineCombinerPattern::MULADDv4i16_indexed_OP2: 5683 Opc = AArch64::MLAv4i16_indexed; 5684 RC = &AArch64::FPR64RegClass; 5685 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5686 break; 5687 case MachineCombinerPattern::MULADDv8i16_indexed_OP1: 5688 Opc = AArch64::MLAv8i16_indexed; 5689 RC = &AArch64::FPR128RegClass; 5690 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5691 break; 5692 case MachineCombinerPattern::MULADDv8i16_indexed_OP2: 5693 Opc = AArch64::MLAv8i16_indexed; 5694 RC = &AArch64::FPR128RegClass; 5695 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5696 break; 5697 case MachineCombinerPattern::MULADDv2i32_indexed_OP1: 5698 Opc = AArch64::MLAv2i32_indexed; 5699 RC = &AArch64::FPR64RegClass; 5700 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5701 break; 5702 case MachineCombinerPattern::MULADDv2i32_indexed_OP2: 5703 Opc = AArch64::MLAv2i32_indexed; 5704 RC = &AArch64::FPR64RegClass; 5705 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5706 break; 5707 case MachineCombinerPattern::MULADDv4i32_indexed_OP1: 5708 Opc = AArch64::MLAv4i32_indexed; 5709 RC = &AArch64::FPR128RegClass; 5710 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5711 break; 5712 case MachineCombinerPattern::MULADDv4i32_indexed_OP2: 5713 Opc = AArch64::MLAv4i32_indexed; 5714 RC = &AArch64::FPR128RegClass; 5715 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5716 break; 5717 5718 case MachineCombinerPattern::MULSUBv4i16_indexed_OP1: 5719 Opc = AArch64::MLAv4i16_indexed; 5720 RC = &AArch64::FPR64RegClass; 5721 MUL = genFusedMultiplyIdxNeg(MF, MRI, TII, Root, InsInstrs, 5722 InstrIdxForVirtReg, 1, Opc, AArch64::NEGv4i16, 5723 RC); 5724 break; 5725 case MachineCombinerPattern::MULSUBv4i16_indexed_OP2: 5726 Opc = AArch64::MLSv4i16_indexed; 5727 RC = &AArch64::FPR64RegClass; 5728 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5729 break; 5730 case MachineCombinerPattern::MULSUBv8i16_indexed_OP1: 5731 Opc = AArch64::MLAv8i16_indexed; 5732 RC = &AArch64::FPR128RegClass; 5733 MUL = genFusedMultiplyIdxNeg(MF, MRI, TII, Root, InsInstrs, 5734 InstrIdxForVirtReg, 1, Opc, AArch64::NEGv8i16, 5735 RC); 5736 break; 5737 case MachineCombinerPattern::MULSUBv8i16_indexed_OP2: 5738 Opc = AArch64::MLSv8i16_indexed; 5739 RC = &AArch64::FPR128RegClass; 5740 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5741 break; 5742 case MachineCombinerPattern::MULSUBv2i32_indexed_OP1: 5743 Opc = AArch64::MLAv2i32_indexed; 5744 RC = &AArch64::FPR64RegClass; 5745 MUL = genFusedMultiplyIdxNeg(MF, MRI, TII, Root, InsInstrs, 5746 InstrIdxForVirtReg, 1, Opc, AArch64::NEGv2i32, 5747 RC); 5748 break; 5749 case MachineCombinerPattern::MULSUBv2i32_indexed_OP2: 5750 Opc = AArch64::MLSv2i32_indexed; 5751 RC = &AArch64::FPR64RegClass; 5752 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5753 break; 5754 case MachineCombinerPattern::MULSUBv4i32_indexed_OP1: 5755 Opc = AArch64::MLAv4i32_indexed; 5756 RC = &AArch64::FPR128RegClass; 5757 MUL = genFusedMultiplyIdxNeg(MF, MRI, TII, Root, InsInstrs, 5758 InstrIdxForVirtReg, 1, Opc, AArch64::NEGv4i32, 5759 RC); 5760 break; 5761 case MachineCombinerPattern::MULSUBv4i32_indexed_OP2: 5762 Opc = AArch64::MLSv4i32_indexed; 5763 RC = &AArch64::FPR128RegClass; 5764 MUL = genFusedMultiplyIdx(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5765 break; 5766 5767 // Floating Point Support 5768 case MachineCombinerPattern::FMULADDH_OP1: 5769 Opc = AArch64::FMADDHrrr; 5770 RC = &AArch64::FPR16RegClass; 5771 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5772 break; 5773 case MachineCombinerPattern::FMULADDS_OP1: 5774 Opc = AArch64::FMADDSrrr; 5775 RC = &AArch64::FPR32RegClass; 5776 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5777 break; 5778 case MachineCombinerPattern::FMULADDD_OP1: 5779 Opc = AArch64::FMADDDrrr; 5780 RC = &AArch64::FPR64RegClass; 5781 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5782 break; 5783 5784 case MachineCombinerPattern::FMULADDH_OP2: 5785 Opc = AArch64::FMADDHrrr; 5786 RC = &AArch64::FPR16RegClass; 5787 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5788 break; 5789 case MachineCombinerPattern::FMULADDS_OP2: 5790 Opc = AArch64::FMADDSrrr; 5791 RC = &AArch64::FPR32RegClass; 5792 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5793 break; 5794 case MachineCombinerPattern::FMULADDD_OP2: 5795 Opc = AArch64::FMADDDrrr; 5796 RC = &AArch64::FPR64RegClass; 5797 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5798 break; 5799 5800 case MachineCombinerPattern::FMLAv1i32_indexed_OP1: 5801 Opc = AArch64::FMLAv1i32_indexed; 5802 RC = &AArch64::FPR32RegClass; 5803 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5804 FMAInstKind::Indexed); 5805 break; 5806 case MachineCombinerPattern::FMLAv1i32_indexed_OP2: 5807 Opc = AArch64::FMLAv1i32_indexed; 5808 RC = &AArch64::FPR32RegClass; 5809 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5810 FMAInstKind::Indexed); 5811 break; 5812 5813 case MachineCombinerPattern::FMLAv1i64_indexed_OP1: 5814 Opc = AArch64::FMLAv1i64_indexed; 5815 RC = &AArch64::FPR64RegClass; 5816 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5817 FMAInstKind::Indexed); 5818 break; 5819 case MachineCombinerPattern::FMLAv1i64_indexed_OP2: 5820 Opc = AArch64::FMLAv1i64_indexed; 5821 RC = &AArch64::FPR64RegClass; 5822 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5823 FMAInstKind::Indexed); 5824 break; 5825 5826 case MachineCombinerPattern::FMLAv4i16_indexed_OP1: 5827 RC = &AArch64::FPR64RegClass; 5828 Opc = AArch64::FMLAv4i16_indexed; 5829 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5830 FMAInstKind::Indexed); 5831 break; 5832 case MachineCombinerPattern::FMLAv4f16_OP1: 5833 RC = &AArch64::FPR64RegClass; 5834 Opc = AArch64::FMLAv4f16; 5835 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5836 FMAInstKind::Accumulator); 5837 break; 5838 case MachineCombinerPattern::FMLAv4i16_indexed_OP2: 5839 RC = &AArch64::FPR64RegClass; 5840 Opc = AArch64::FMLAv4i16_indexed; 5841 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5842 FMAInstKind::Indexed); 5843 break; 5844 case MachineCombinerPattern::FMLAv4f16_OP2: 5845 RC = &AArch64::FPR64RegClass; 5846 Opc = AArch64::FMLAv4f16; 5847 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5848 FMAInstKind::Accumulator); 5849 break; 5850 5851 case MachineCombinerPattern::FMLAv2i32_indexed_OP1: 5852 case MachineCombinerPattern::FMLAv2f32_OP1: 5853 RC = &AArch64::FPR64RegClass; 5854 if (Pattern == MachineCombinerPattern::FMLAv2i32_indexed_OP1) { 5855 Opc = AArch64::FMLAv2i32_indexed; 5856 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5857 FMAInstKind::Indexed); 5858 } else { 5859 Opc = AArch64::FMLAv2f32; 5860 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5861 FMAInstKind::Accumulator); 5862 } 5863 break; 5864 case MachineCombinerPattern::FMLAv2i32_indexed_OP2: 5865 case MachineCombinerPattern::FMLAv2f32_OP2: 5866 RC = &AArch64::FPR64RegClass; 5867 if (Pattern == MachineCombinerPattern::FMLAv2i32_indexed_OP2) { 5868 Opc = AArch64::FMLAv2i32_indexed; 5869 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5870 FMAInstKind::Indexed); 5871 } else { 5872 Opc = AArch64::FMLAv2f32; 5873 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5874 FMAInstKind::Accumulator); 5875 } 5876 break; 5877 5878 case MachineCombinerPattern::FMLAv8i16_indexed_OP1: 5879 RC = &AArch64::FPR128RegClass; 5880 Opc = AArch64::FMLAv8i16_indexed; 5881 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5882 FMAInstKind::Indexed); 5883 break; 5884 case MachineCombinerPattern::FMLAv8f16_OP1: 5885 RC = &AArch64::FPR128RegClass; 5886 Opc = AArch64::FMLAv8f16; 5887 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5888 FMAInstKind::Accumulator); 5889 break; 5890 case MachineCombinerPattern::FMLAv8i16_indexed_OP2: 5891 RC = &AArch64::FPR128RegClass; 5892 Opc = AArch64::FMLAv8i16_indexed; 5893 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5894 FMAInstKind::Indexed); 5895 break; 5896 case MachineCombinerPattern::FMLAv8f16_OP2: 5897 RC = &AArch64::FPR128RegClass; 5898 Opc = AArch64::FMLAv8f16; 5899 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5900 FMAInstKind::Accumulator); 5901 break; 5902 5903 case MachineCombinerPattern::FMLAv2i64_indexed_OP1: 5904 case MachineCombinerPattern::FMLAv2f64_OP1: 5905 RC = &AArch64::FPR128RegClass; 5906 if (Pattern == MachineCombinerPattern::FMLAv2i64_indexed_OP1) { 5907 Opc = AArch64::FMLAv2i64_indexed; 5908 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5909 FMAInstKind::Indexed); 5910 } else { 5911 Opc = AArch64::FMLAv2f64; 5912 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5913 FMAInstKind::Accumulator); 5914 } 5915 break; 5916 case MachineCombinerPattern::FMLAv2i64_indexed_OP2: 5917 case MachineCombinerPattern::FMLAv2f64_OP2: 5918 RC = &AArch64::FPR128RegClass; 5919 if (Pattern == MachineCombinerPattern::FMLAv2i64_indexed_OP2) { 5920 Opc = AArch64::FMLAv2i64_indexed; 5921 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5922 FMAInstKind::Indexed); 5923 } else { 5924 Opc = AArch64::FMLAv2f64; 5925 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5926 FMAInstKind::Accumulator); 5927 } 5928 break; 5929 5930 case MachineCombinerPattern::FMLAv4i32_indexed_OP1: 5931 case MachineCombinerPattern::FMLAv4f32_OP1: 5932 RC = &AArch64::FPR128RegClass; 5933 if (Pattern == MachineCombinerPattern::FMLAv4i32_indexed_OP1) { 5934 Opc = AArch64::FMLAv4i32_indexed; 5935 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5936 FMAInstKind::Indexed); 5937 } else { 5938 Opc = AArch64::FMLAv4f32; 5939 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 5940 FMAInstKind::Accumulator); 5941 } 5942 break; 5943 5944 case MachineCombinerPattern::FMLAv4i32_indexed_OP2: 5945 case MachineCombinerPattern::FMLAv4f32_OP2: 5946 RC = &AArch64::FPR128RegClass; 5947 if (Pattern == MachineCombinerPattern::FMLAv4i32_indexed_OP2) { 5948 Opc = AArch64::FMLAv4i32_indexed; 5949 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5950 FMAInstKind::Indexed); 5951 } else { 5952 Opc = AArch64::FMLAv4f32; 5953 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 5954 FMAInstKind::Accumulator); 5955 } 5956 break; 5957 5958 case MachineCombinerPattern::FMULSUBH_OP1: 5959 Opc = AArch64::FNMSUBHrrr; 5960 RC = &AArch64::FPR16RegClass; 5961 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5962 break; 5963 case MachineCombinerPattern::FMULSUBS_OP1: 5964 Opc = AArch64::FNMSUBSrrr; 5965 RC = &AArch64::FPR32RegClass; 5966 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5967 break; 5968 case MachineCombinerPattern::FMULSUBD_OP1: 5969 Opc = AArch64::FNMSUBDrrr; 5970 RC = &AArch64::FPR64RegClass; 5971 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5972 break; 5973 5974 case MachineCombinerPattern::FNMULSUBH_OP1: 5975 Opc = AArch64::FNMADDHrrr; 5976 RC = &AArch64::FPR16RegClass; 5977 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5978 break; 5979 case MachineCombinerPattern::FNMULSUBS_OP1: 5980 Opc = AArch64::FNMADDSrrr; 5981 RC = &AArch64::FPR32RegClass; 5982 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5983 break; 5984 case MachineCombinerPattern::FNMULSUBD_OP1: 5985 Opc = AArch64::FNMADDDrrr; 5986 RC = &AArch64::FPR64RegClass; 5987 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 5988 break; 5989 5990 case MachineCombinerPattern::FMULSUBH_OP2: 5991 Opc = AArch64::FMSUBHrrr; 5992 RC = &AArch64::FPR16RegClass; 5993 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5994 break; 5995 case MachineCombinerPattern::FMULSUBS_OP2: 5996 Opc = AArch64::FMSUBSrrr; 5997 RC = &AArch64::FPR32RegClass; 5998 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 5999 break; 6000 case MachineCombinerPattern::FMULSUBD_OP2: 6001 Opc = AArch64::FMSUBDrrr; 6002 RC = &AArch64::FPR64RegClass; 6003 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 6004 break; 6005 6006 case MachineCombinerPattern::FMLSv1i32_indexed_OP2: 6007 Opc = AArch64::FMLSv1i32_indexed; 6008 RC = &AArch64::FPR32RegClass; 6009 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6010 FMAInstKind::Indexed); 6011 break; 6012 6013 case MachineCombinerPattern::FMLSv1i64_indexed_OP2: 6014 Opc = AArch64::FMLSv1i64_indexed; 6015 RC = &AArch64::FPR64RegClass; 6016 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6017 FMAInstKind::Indexed); 6018 break; 6019 6020 case MachineCombinerPattern::FMLSv4f16_OP1: 6021 case MachineCombinerPattern::FMLSv4i16_indexed_OP1: { 6022 RC = &AArch64::FPR64RegClass; 6023 Register NewVR = MRI.createVirtualRegister(RC); 6024 MachineInstrBuilder MIB1 = 6025 BuildMI(MF, Root.getDebugLoc(), TII->get(AArch64::FNEGv4f16), NewVR) 6026 .add(Root.getOperand(2)); 6027 InsInstrs.push_back(MIB1); 6028 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 6029 if (Pattern == MachineCombinerPattern::FMLSv4f16_OP1) { 6030 Opc = AArch64::FMLAv4f16; 6031 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 6032 FMAInstKind::Accumulator, &NewVR); 6033 } else { 6034 Opc = AArch64::FMLAv4i16_indexed; 6035 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 6036 FMAInstKind::Indexed, &NewVR); 6037 } 6038 break; 6039 } 6040 case MachineCombinerPattern::FMLSv4f16_OP2: 6041 RC = &AArch64::FPR64RegClass; 6042 Opc = AArch64::FMLSv4f16; 6043 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6044 FMAInstKind::Accumulator); 6045 break; 6046 case MachineCombinerPattern::FMLSv4i16_indexed_OP2: 6047 RC = &AArch64::FPR64RegClass; 6048 Opc = AArch64::FMLSv4i16_indexed; 6049 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6050 FMAInstKind::Indexed); 6051 break; 6052 6053 case MachineCombinerPattern::FMLSv2f32_OP2: 6054 case MachineCombinerPattern::FMLSv2i32_indexed_OP2: 6055 RC = &AArch64::FPR64RegClass; 6056 if (Pattern == MachineCombinerPattern::FMLSv2i32_indexed_OP2) { 6057 Opc = AArch64::FMLSv2i32_indexed; 6058 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6059 FMAInstKind::Indexed); 6060 } else { 6061 Opc = AArch64::FMLSv2f32; 6062 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6063 FMAInstKind::Accumulator); 6064 } 6065 break; 6066 6067 case MachineCombinerPattern::FMLSv8f16_OP1: 6068 case MachineCombinerPattern::FMLSv8i16_indexed_OP1: { 6069 RC = &AArch64::FPR128RegClass; 6070 Register NewVR = MRI.createVirtualRegister(RC); 6071 MachineInstrBuilder MIB1 = 6072 BuildMI(MF, Root.getDebugLoc(), TII->get(AArch64::FNEGv8f16), NewVR) 6073 .add(Root.getOperand(2)); 6074 InsInstrs.push_back(MIB1); 6075 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 6076 if (Pattern == MachineCombinerPattern::FMLSv8f16_OP1) { 6077 Opc = AArch64::FMLAv8f16; 6078 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 6079 FMAInstKind::Accumulator, &NewVR); 6080 } else { 6081 Opc = AArch64::FMLAv8i16_indexed; 6082 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 6083 FMAInstKind::Indexed, &NewVR); 6084 } 6085 break; 6086 } 6087 case MachineCombinerPattern::FMLSv8f16_OP2: 6088 RC = &AArch64::FPR128RegClass; 6089 Opc = AArch64::FMLSv8f16; 6090 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6091 FMAInstKind::Accumulator); 6092 break; 6093 case MachineCombinerPattern::FMLSv8i16_indexed_OP2: 6094 RC = &AArch64::FPR128RegClass; 6095 Opc = AArch64::FMLSv8i16_indexed; 6096 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6097 FMAInstKind::Indexed); 6098 break; 6099 6100 case MachineCombinerPattern::FMLSv2f64_OP2: 6101 case MachineCombinerPattern::FMLSv2i64_indexed_OP2: 6102 RC = &AArch64::FPR128RegClass; 6103 if (Pattern == MachineCombinerPattern::FMLSv2i64_indexed_OP2) { 6104 Opc = AArch64::FMLSv2i64_indexed; 6105 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6106 FMAInstKind::Indexed); 6107 } else { 6108 Opc = AArch64::FMLSv2f64; 6109 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6110 FMAInstKind::Accumulator); 6111 } 6112 break; 6113 6114 case MachineCombinerPattern::FMLSv4f32_OP2: 6115 case MachineCombinerPattern::FMLSv4i32_indexed_OP2: 6116 RC = &AArch64::FPR128RegClass; 6117 if (Pattern == MachineCombinerPattern::FMLSv4i32_indexed_OP2) { 6118 Opc = AArch64::FMLSv4i32_indexed; 6119 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6120 FMAInstKind::Indexed); 6121 } else { 6122 Opc = AArch64::FMLSv4f32; 6123 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 6124 FMAInstKind::Accumulator); 6125 } 6126 break; 6127 case MachineCombinerPattern::FMLSv2f32_OP1: 6128 case MachineCombinerPattern::FMLSv2i32_indexed_OP1: { 6129 RC = &AArch64::FPR64RegClass; 6130 Register NewVR = MRI.createVirtualRegister(RC); 6131 MachineInstrBuilder MIB1 = 6132 BuildMI(MF, Root.getDebugLoc(), TII->get(AArch64::FNEGv2f32), NewVR) 6133 .add(Root.getOperand(2)); 6134 InsInstrs.push_back(MIB1); 6135 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 6136 if (Pattern == MachineCombinerPattern::FMLSv2i32_indexed_OP1) { 6137 Opc = AArch64::FMLAv2i32_indexed; 6138 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 6139 FMAInstKind::Indexed, &NewVR); 6140 } else { 6141 Opc = AArch64::FMLAv2f32; 6142 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 6143 FMAInstKind::Accumulator, &NewVR); 6144 } 6145 break; 6146 } 6147 case MachineCombinerPattern::FMLSv4f32_OP1: 6148 case MachineCombinerPattern::FMLSv4i32_indexed_OP1: { 6149 RC = &AArch64::FPR128RegClass; 6150 Register NewVR = MRI.createVirtualRegister(RC); 6151 MachineInstrBuilder MIB1 = 6152 BuildMI(MF, Root.getDebugLoc(), TII->get(AArch64::FNEGv4f32), NewVR) 6153 .add(Root.getOperand(2)); 6154 InsInstrs.push_back(MIB1); 6155 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 6156 if (Pattern == MachineCombinerPattern::FMLSv4i32_indexed_OP1) { 6157 Opc = AArch64::FMLAv4i32_indexed; 6158 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 6159 FMAInstKind::Indexed, &NewVR); 6160 } else { 6161 Opc = AArch64::FMLAv4f32; 6162 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 6163 FMAInstKind::Accumulator, &NewVR); 6164 } 6165 break; 6166 } 6167 case MachineCombinerPattern::FMLSv2f64_OP1: 6168 case MachineCombinerPattern::FMLSv2i64_indexed_OP1: { 6169 RC = &AArch64::FPR128RegClass; 6170 Register NewVR = MRI.createVirtualRegister(RC); 6171 MachineInstrBuilder MIB1 = 6172 BuildMI(MF, Root.getDebugLoc(), TII->get(AArch64::FNEGv2f64), NewVR) 6173 .add(Root.getOperand(2)); 6174 InsInstrs.push_back(MIB1); 6175 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 6176 if (Pattern == MachineCombinerPattern::FMLSv2i64_indexed_OP1) { 6177 Opc = AArch64::FMLAv2i64_indexed; 6178 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 6179 FMAInstKind::Indexed, &NewVR); 6180 } else { 6181 Opc = AArch64::FMLAv2f64; 6182 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 6183 FMAInstKind::Accumulator, &NewVR); 6184 } 6185 break; 6186 } 6187 case MachineCombinerPattern::FMULv2i32_indexed_OP1: 6188 case MachineCombinerPattern::FMULv2i32_indexed_OP2: { 6189 unsigned IdxDupOp = 6190 (Pattern == MachineCombinerPattern::FMULv2i32_indexed_OP1) ? 1 : 2; 6191 genIndexedMultiply(Root, InsInstrs, IdxDupOp, AArch64::FMULv2i32_indexed, 6192 &AArch64::FPR128RegClass, MRI); 6193 break; 6194 } 6195 case MachineCombinerPattern::FMULv2i64_indexed_OP1: 6196 case MachineCombinerPattern::FMULv2i64_indexed_OP2: { 6197 unsigned IdxDupOp = 6198 (Pattern == MachineCombinerPattern::FMULv2i64_indexed_OP1) ? 1 : 2; 6199 genIndexedMultiply(Root, InsInstrs, IdxDupOp, AArch64::FMULv2i64_indexed, 6200 &AArch64::FPR128RegClass, MRI); 6201 break; 6202 } 6203 case MachineCombinerPattern::FMULv4i16_indexed_OP1: 6204 case MachineCombinerPattern::FMULv4i16_indexed_OP2: { 6205 unsigned IdxDupOp = 6206 (Pattern == MachineCombinerPattern::FMULv4i16_indexed_OP1) ? 1 : 2; 6207 genIndexedMultiply(Root, InsInstrs, IdxDupOp, AArch64::FMULv4i16_indexed, 6208 &AArch64::FPR128_loRegClass, MRI); 6209 break; 6210 } 6211 case MachineCombinerPattern::FMULv4i32_indexed_OP1: 6212 case MachineCombinerPattern::FMULv4i32_indexed_OP2: { 6213 unsigned IdxDupOp = 6214 (Pattern == MachineCombinerPattern::FMULv4i32_indexed_OP1) ? 1 : 2; 6215 genIndexedMultiply(Root, InsInstrs, IdxDupOp, AArch64::FMULv4i32_indexed, 6216 &AArch64::FPR128RegClass, MRI); 6217 break; 6218 } 6219 case MachineCombinerPattern::FMULv8i16_indexed_OP1: 6220 case MachineCombinerPattern::FMULv8i16_indexed_OP2: { 6221 unsigned IdxDupOp = 6222 (Pattern == MachineCombinerPattern::FMULv8i16_indexed_OP1) ? 1 : 2; 6223 genIndexedMultiply(Root, InsInstrs, IdxDupOp, AArch64::FMULv8i16_indexed, 6224 &AArch64::FPR128_loRegClass, MRI); 6225 break; 6226 } 6227 } // end switch (Pattern) 6228 // Record MUL and ADD/SUB for deletion 6229 if (MUL) 6230 DelInstrs.push_back(MUL); 6231 DelInstrs.push_back(&Root); 6232 } 6233 6234 /// Replace csincr-branch sequence by simple conditional branch 6235 /// 6236 /// Examples: 6237 /// 1. \code 6238 /// csinc w9, wzr, wzr, <condition code> 6239 /// tbnz w9, #0, 0x44 6240 /// \endcode 6241 /// to 6242 /// \code 6243 /// b.<inverted condition code> 6244 /// \endcode 6245 /// 6246 /// 2. \code 6247 /// csinc w9, wzr, wzr, <condition code> 6248 /// tbz w9, #0, 0x44 6249 /// \endcode 6250 /// to 6251 /// \code 6252 /// b.<condition code> 6253 /// \endcode 6254 /// 6255 /// Replace compare and branch sequence by TBZ/TBNZ instruction when the 6256 /// compare's constant operand is power of 2. 6257 /// 6258 /// Examples: 6259 /// \code 6260 /// and w8, w8, #0x400 6261 /// cbnz w8, L1 6262 /// \endcode 6263 /// to 6264 /// \code 6265 /// tbnz w8, #10, L1 6266 /// \endcode 6267 /// 6268 /// \param MI Conditional Branch 6269 /// \return True when the simple conditional branch is generated 6270 /// 6271 bool AArch64InstrInfo::optimizeCondBranch(MachineInstr &MI) const { 6272 bool IsNegativeBranch = false; 6273 bool IsTestAndBranch = false; 6274 unsigned TargetBBInMI = 0; 6275 switch (MI.getOpcode()) { 6276 default: 6277 llvm_unreachable("Unknown branch instruction?"); 6278 case AArch64::Bcc: 6279 return false; 6280 case AArch64::CBZW: 6281 case AArch64::CBZX: 6282 TargetBBInMI = 1; 6283 break; 6284 case AArch64::CBNZW: 6285 case AArch64::CBNZX: 6286 TargetBBInMI = 1; 6287 IsNegativeBranch = true; 6288 break; 6289 case AArch64::TBZW: 6290 case AArch64::TBZX: 6291 TargetBBInMI = 2; 6292 IsTestAndBranch = true; 6293 break; 6294 case AArch64::TBNZW: 6295 case AArch64::TBNZX: 6296 TargetBBInMI = 2; 6297 IsNegativeBranch = true; 6298 IsTestAndBranch = true; 6299 break; 6300 } 6301 // So we increment a zero register and test for bits other 6302 // than bit 0? Conservatively bail out in case the verifier 6303 // missed this case. 6304 if (IsTestAndBranch && MI.getOperand(1).getImm()) 6305 return false; 6306 6307 // Find Definition. 6308 assert(MI.getParent() && "Incomplete machine instruciton\n"); 6309 MachineBasicBlock *MBB = MI.getParent(); 6310 MachineFunction *MF = MBB->getParent(); 6311 MachineRegisterInfo *MRI = &MF->getRegInfo(); 6312 Register VReg = MI.getOperand(0).getReg(); 6313 if (!Register::isVirtualRegister(VReg)) 6314 return false; 6315 6316 MachineInstr *DefMI = MRI->getVRegDef(VReg); 6317 6318 // Look through COPY instructions to find definition. 6319 while (DefMI->isCopy()) { 6320 Register CopyVReg = DefMI->getOperand(1).getReg(); 6321 if (!MRI->hasOneNonDBGUse(CopyVReg)) 6322 return false; 6323 if (!MRI->hasOneDef(CopyVReg)) 6324 return false; 6325 DefMI = MRI->getVRegDef(CopyVReg); 6326 } 6327 6328 switch (DefMI->getOpcode()) { 6329 default: 6330 return false; 6331 // Fold AND into a TBZ/TBNZ if constant operand is power of 2. 6332 case AArch64::ANDWri: 6333 case AArch64::ANDXri: { 6334 if (IsTestAndBranch) 6335 return false; 6336 if (DefMI->getParent() != MBB) 6337 return false; 6338 if (!MRI->hasOneNonDBGUse(VReg)) 6339 return false; 6340 6341 bool Is32Bit = (DefMI->getOpcode() == AArch64::ANDWri); 6342 uint64_t Mask = AArch64_AM::decodeLogicalImmediate( 6343 DefMI->getOperand(2).getImm(), Is32Bit ? 32 : 64); 6344 if (!isPowerOf2_64(Mask)) 6345 return false; 6346 6347 MachineOperand &MO = DefMI->getOperand(1); 6348 Register NewReg = MO.getReg(); 6349 if (!Register::isVirtualRegister(NewReg)) 6350 return false; 6351 6352 assert(!MRI->def_empty(NewReg) && "Register must be defined."); 6353 6354 MachineBasicBlock &RefToMBB = *MBB; 6355 MachineBasicBlock *TBB = MI.getOperand(1).getMBB(); 6356 DebugLoc DL = MI.getDebugLoc(); 6357 unsigned Imm = Log2_64(Mask); 6358 unsigned Opc = (Imm < 32) 6359 ? (IsNegativeBranch ? AArch64::TBNZW : AArch64::TBZW) 6360 : (IsNegativeBranch ? AArch64::TBNZX : AArch64::TBZX); 6361 MachineInstr *NewMI = BuildMI(RefToMBB, MI, DL, get(Opc)) 6362 .addReg(NewReg) 6363 .addImm(Imm) 6364 .addMBB(TBB); 6365 // Register lives on to the CBZ now. 6366 MO.setIsKill(false); 6367 6368 // For immediate smaller than 32, we need to use the 32-bit 6369 // variant (W) in all cases. Indeed the 64-bit variant does not 6370 // allow to encode them. 6371 // Therefore, if the input register is 64-bit, we need to take the 6372 // 32-bit sub-part. 6373 if (!Is32Bit && Imm < 32) 6374 NewMI->getOperand(0).setSubReg(AArch64::sub_32); 6375 MI.eraseFromParent(); 6376 return true; 6377 } 6378 // Look for CSINC 6379 case AArch64::CSINCWr: 6380 case AArch64::CSINCXr: { 6381 if (!(DefMI->getOperand(1).getReg() == AArch64::WZR && 6382 DefMI->getOperand(2).getReg() == AArch64::WZR) && 6383 !(DefMI->getOperand(1).getReg() == AArch64::XZR && 6384 DefMI->getOperand(2).getReg() == AArch64::XZR)) 6385 return false; 6386 6387 if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) != -1) 6388 return false; 6389 6390 AArch64CC::CondCode CC = (AArch64CC::CondCode)DefMI->getOperand(3).getImm(); 6391 // Convert only when the condition code is not modified between 6392 // the CSINC and the branch. The CC may be used by other 6393 // instructions in between. 6394 if (areCFlagsAccessedBetweenInstrs(DefMI, MI, &getRegisterInfo(), AK_Write)) 6395 return false; 6396 MachineBasicBlock &RefToMBB = *MBB; 6397 MachineBasicBlock *TBB = MI.getOperand(TargetBBInMI).getMBB(); 6398 DebugLoc DL = MI.getDebugLoc(); 6399 if (IsNegativeBranch) 6400 CC = AArch64CC::getInvertedCondCode(CC); 6401 BuildMI(RefToMBB, MI, DL, get(AArch64::Bcc)).addImm(CC).addMBB(TBB); 6402 MI.eraseFromParent(); 6403 return true; 6404 } 6405 } 6406 } 6407 6408 std::pair<unsigned, unsigned> 6409 AArch64InstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const { 6410 const unsigned Mask = AArch64II::MO_FRAGMENT; 6411 return std::make_pair(TF & Mask, TF & ~Mask); 6412 } 6413 6414 ArrayRef<std::pair<unsigned, const char *>> 6415 AArch64InstrInfo::getSerializableDirectMachineOperandTargetFlags() const { 6416 using namespace AArch64II; 6417 6418 static const std::pair<unsigned, const char *> TargetFlags[] = { 6419 {MO_PAGE, "aarch64-page"}, {MO_PAGEOFF, "aarch64-pageoff"}, 6420 {MO_G3, "aarch64-g3"}, {MO_G2, "aarch64-g2"}, 6421 {MO_G1, "aarch64-g1"}, {MO_G0, "aarch64-g0"}, 6422 {MO_HI12, "aarch64-hi12"}}; 6423 return makeArrayRef(TargetFlags); 6424 } 6425 6426 ArrayRef<std::pair<unsigned, const char *>> 6427 AArch64InstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const { 6428 using namespace AArch64II; 6429 6430 static const std::pair<unsigned, const char *> TargetFlags[] = { 6431 {MO_COFFSTUB, "aarch64-coffstub"}, 6432 {MO_GOT, "aarch64-got"}, 6433 {MO_NC, "aarch64-nc"}, 6434 {MO_S, "aarch64-s"}, 6435 {MO_TLS, "aarch64-tls"}, 6436 {MO_DLLIMPORT, "aarch64-dllimport"}, 6437 {MO_PREL, "aarch64-prel"}, 6438 {MO_TAGGED, "aarch64-tagged"}}; 6439 return makeArrayRef(TargetFlags); 6440 } 6441 6442 ArrayRef<std::pair<MachineMemOperand::Flags, const char *>> 6443 AArch64InstrInfo::getSerializableMachineMemOperandTargetFlags() const { 6444 static const std::pair<MachineMemOperand::Flags, const char *> TargetFlags[] = 6445 {{MOSuppressPair, "aarch64-suppress-pair"}, 6446 {MOStridedAccess, "aarch64-strided-access"}}; 6447 return makeArrayRef(TargetFlags); 6448 } 6449 6450 /// Constants defining how certain sequences should be outlined. 6451 /// This encompasses how an outlined function should be called, and what kind of 6452 /// frame should be emitted for that outlined function. 6453 /// 6454 /// \p MachineOutlinerDefault implies that the function should be called with 6455 /// a save and restore of LR to the stack. 6456 /// 6457 /// That is, 6458 /// 6459 /// I1 Save LR OUTLINED_FUNCTION: 6460 /// I2 --> BL OUTLINED_FUNCTION I1 6461 /// I3 Restore LR I2 6462 /// I3 6463 /// RET 6464 /// 6465 /// * Call construction overhead: 3 (save + BL + restore) 6466 /// * Frame construction overhead: 1 (ret) 6467 /// * Requires stack fixups? Yes 6468 /// 6469 /// \p MachineOutlinerTailCall implies that the function is being created from 6470 /// a sequence of instructions ending in a return. 6471 /// 6472 /// That is, 6473 /// 6474 /// I1 OUTLINED_FUNCTION: 6475 /// I2 --> B OUTLINED_FUNCTION I1 6476 /// RET I2 6477 /// RET 6478 /// 6479 /// * Call construction overhead: 1 (B) 6480 /// * Frame construction overhead: 0 (Return included in sequence) 6481 /// * Requires stack fixups? No 6482 /// 6483 /// \p MachineOutlinerNoLRSave implies that the function should be called using 6484 /// a BL instruction, but doesn't require LR to be saved and restored. This 6485 /// happens when LR is known to be dead. 6486 /// 6487 /// That is, 6488 /// 6489 /// I1 OUTLINED_FUNCTION: 6490 /// I2 --> BL OUTLINED_FUNCTION I1 6491 /// I3 I2 6492 /// I3 6493 /// RET 6494 /// 6495 /// * Call construction overhead: 1 (BL) 6496 /// * Frame construction overhead: 1 (RET) 6497 /// * Requires stack fixups? No 6498 /// 6499 /// \p MachineOutlinerThunk implies that the function is being created from 6500 /// a sequence of instructions ending in a call. The outlined function is 6501 /// called with a BL instruction, and the outlined function tail-calls the 6502 /// original call destination. 6503 /// 6504 /// That is, 6505 /// 6506 /// I1 OUTLINED_FUNCTION: 6507 /// I2 --> BL OUTLINED_FUNCTION I1 6508 /// BL f I2 6509 /// B f 6510 /// * Call construction overhead: 1 (BL) 6511 /// * Frame construction overhead: 0 6512 /// * Requires stack fixups? No 6513 /// 6514 /// \p MachineOutlinerRegSave implies that the function should be called with a 6515 /// save and restore of LR to an available register. This allows us to avoid 6516 /// stack fixups. Note that this outlining variant is compatible with the 6517 /// NoLRSave case. 6518 /// 6519 /// That is, 6520 /// 6521 /// I1 Save LR OUTLINED_FUNCTION: 6522 /// I2 --> BL OUTLINED_FUNCTION I1 6523 /// I3 Restore LR I2 6524 /// I3 6525 /// RET 6526 /// 6527 /// * Call construction overhead: 3 (save + BL + restore) 6528 /// * Frame construction overhead: 1 (ret) 6529 /// * Requires stack fixups? No 6530 enum MachineOutlinerClass { 6531 MachineOutlinerDefault, /// Emit a save, restore, call, and return. 6532 MachineOutlinerTailCall, /// Only emit a branch. 6533 MachineOutlinerNoLRSave, /// Emit a call and return. 6534 MachineOutlinerThunk, /// Emit a call and tail-call. 6535 MachineOutlinerRegSave /// Same as default, but save to a register. 6536 }; 6537 6538 enum MachineOutlinerMBBFlags { 6539 LRUnavailableSomewhere = 0x2, 6540 HasCalls = 0x4, 6541 UnsafeRegsDead = 0x8 6542 }; 6543 6544 unsigned 6545 AArch64InstrInfo::findRegisterToSaveLRTo(const outliner::Candidate &C) const { 6546 assert(C.LRUWasSet && "LRU wasn't set?"); 6547 MachineFunction *MF = C.getMF(); 6548 const AArch64RegisterInfo *ARI = static_cast<const AArch64RegisterInfo *>( 6549 MF->getSubtarget().getRegisterInfo()); 6550 6551 // Check if there is an available register across the sequence that we can 6552 // use. 6553 for (unsigned Reg : AArch64::GPR64RegClass) { 6554 if (!ARI->isReservedReg(*MF, Reg) && 6555 Reg != AArch64::LR && // LR is not reserved, but don't use it. 6556 Reg != AArch64::X16 && // X16 is not guaranteed to be preserved. 6557 Reg != AArch64::X17 && // Ditto for X17. 6558 C.LRU.available(Reg) && C.UsedInSequence.available(Reg)) 6559 return Reg; 6560 } 6561 6562 // No suitable register. Return 0. 6563 return 0u; 6564 } 6565 6566 static bool 6567 outliningCandidatesSigningScopeConsensus(const outliner::Candidate &a, 6568 const outliner::Candidate &b) { 6569 const auto &MFIa = a.getMF()->getInfo<AArch64FunctionInfo>(); 6570 const auto &MFIb = b.getMF()->getInfo<AArch64FunctionInfo>(); 6571 6572 return MFIa->shouldSignReturnAddress(false) == MFIb->shouldSignReturnAddress(false) && 6573 MFIa->shouldSignReturnAddress(true) == MFIb->shouldSignReturnAddress(true); 6574 } 6575 6576 static bool 6577 outliningCandidatesSigningKeyConsensus(const outliner::Candidate &a, 6578 const outliner::Candidate &b) { 6579 const auto &MFIa = a.getMF()->getInfo<AArch64FunctionInfo>(); 6580 const auto &MFIb = b.getMF()->getInfo<AArch64FunctionInfo>(); 6581 6582 return MFIa->shouldSignWithBKey() == MFIb->shouldSignWithBKey(); 6583 } 6584 6585 static bool outliningCandidatesV8_3OpsConsensus(const outliner::Candidate &a, 6586 const outliner::Candidate &b) { 6587 const AArch64Subtarget &SubtargetA = 6588 a.getMF()->getSubtarget<AArch64Subtarget>(); 6589 const AArch64Subtarget &SubtargetB = 6590 b.getMF()->getSubtarget<AArch64Subtarget>(); 6591 return SubtargetA.hasV8_3aOps() == SubtargetB.hasV8_3aOps(); 6592 } 6593 6594 outliner::OutlinedFunction AArch64InstrInfo::getOutliningCandidateInfo( 6595 std::vector<outliner::Candidate> &RepeatedSequenceLocs) const { 6596 outliner::Candidate &FirstCand = RepeatedSequenceLocs[0]; 6597 unsigned SequenceSize = 6598 std::accumulate(FirstCand.front(), std::next(FirstCand.back()), 0, 6599 [this](unsigned Sum, const MachineInstr &MI) { 6600 return Sum + getInstSizeInBytes(MI); 6601 }); 6602 unsigned NumBytesToCreateFrame = 0; 6603 6604 // We only allow outlining for functions having exactly matching return 6605 // address signing attributes, i.e., all share the same value for the 6606 // attribute "sign-return-address" and all share the same type of key they 6607 // are signed with. 6608 // Additionally we require all functions to simultaniously either support 6609 // v8.3a features or not. Otherwise an outlined function could get signed 6610 // using dedicated v8.3 instructions and a call from a function that doesn't 6611 // support v8.3 instructions would therefore be invalid. 6612 if (std::adjacent_find( 6613 RepeatedSequenceLocs.begin(), RepeatedSequenceLocs.end(), 6614 [](const outliner::Candidate &a, const outliner::Candidate &b) { 6615 // Return true if a and b are non-equal w.r.t. return address 6616 // signing or support of v8.3a features 6617 if (outliningCandidatesSigningScopeConsensus(a, b) && 6618 outliningCandidatesSigningKeyConsensus(a, b) && 6619 outliningCandidatesV8_3OpsConsensus(a, b)) { 6620 return false; 6621 } 6622 return true; 6623 }) != RepeatedSequenceLocs.end()) { 6624 return outliner::OutlinedFunction(); 6625 } 6626 6627 // Since at this point all candidates agree on their return address signing 6628 // picking just one is fine. If the candidate functions potentially sign their 6629 // return addresses, the outlined function should do the same. Note that in 6630 // the case of "sign-return-address"="non-leaf" this is an assumption: It is 6631 // not certainly true that the outlined function will have to sign its return 6632 // address but this decision is made later, when the decision to outline 6633 // has already been made. 6634 // The same holds for the number of additional instructions we need: On 6635 // v8.3a RET can be replaced by RETAA/RETAB and no AUT instruction is 6636 // necessary. However, at this point we don't know if the outlined function 6637 // will have a RET instruction so we assume the worst. 6638 const TargetRegisterInfo &TRI = getRegisterInfo(); 6639 if (FirstCand.getMF() 6640 ->getInfo<AArch64FunctionInfo>() 6641 ->shouldSignReturnAddress(true)) { 6642 // One PAC and one AUT instructions 6643 NumBytesToCreateFrame += 8; 6644 6645 // We have to check if sp modifying instructions would get outlined. 6646 // If so we only allow outlining if sp is unchanged overall, so matching 6647 // sub and add instructions are okay to outline, all other sp modifications 6648 // are not 6649 auto hasIllegalSPModification = [&TRI](outliner::Candidate &C) { 6650 int SPValue = 0; 6651 MachineBasicBlock::iterator MBBI = C.front(); 6652 for (;;) { 6653 if (MBBI->modifiesRegister(AArch64::SP, &TRI)) { 6654 switch (MBBI->getOpcode()) { 6655 case AArch64::ADDXri: 6656 case AArch64::ADDWri: 6657 assert(MBBI->getNumOperands() == 4 && "Wrong number of operands"); 6658 assert(MBBI->getOperand(2).isImm() && 6659 "Expected operand to be immediate"); 6660 assert(MBBI->getOperand(1).isReg() && 6661 "Expected operand to be a register"); 6662 // Check if the add just increments sp. If so, we search for 6663 // matching sub instructions that decrement sp. If not, the 6664 // modification is illegal 6665 if (MBBI->getOperand(1).getReg() == AArch64::SP) 6666 SPValue += MBBI->getOperand(2).getImm(); 6667 else 6668 return true; 6669 break; 6670 case AArch64::SUBXri: 6671 case AArch64::SUBWri: 6672 assert(MBBI->getNumOperands() == 4 && "Wrong number of operands"); 6673 assert(MBBI->getOperand(2).isImm() && 6674 "Expected operand to be immediate"); 6675 assert(MBBI->getOperand(1).isReg() && 6676 "Expected operand to be a register"); 6677 // Check if the sub just decrements sp. If so, we search for 6678 // matching add instructions that increment sp. If not, the 6679 // modification is illegal 6680 if (MBBI->getOperand(1).getReg() == AArch64::SP) 6681 SPValue -= MBBI->getOperand(2).getImm(); 6682 else 6683 return true; 6684 break; 6685 default: 6686 return true; 6687 } 6688 } 6689 if (MBBI == C.back()) 6690 break; 6691 ++MBBI; 6692 } 6693 if (SPValue) 6694 return true; 6695 return false; 6696 }; 6697 // Remove candidates with illegal stack modifying instructions 6698 llvm::erase_if(RepeatedSequenceLocs, hasIllegalSPModification); 6699 6700 // If the sequence doesn't have enough candidates left, then we're done. 6701 if (RepeatedSequenceLocs.size() < 2) 6702 return outliner::OutlinedFunction(); 6703 } 6704 6705 // Properties about candidate MBBs that hold for all of them. 6706 unsigned FlagsSetInAll = 0xF; 6707 6708 // Compute liveness information for each candidate, and set FlagsSetInAll. 6709 std::for_each(RepeatedSequenceLocs.begin(), RepeatedSequenceLocs.end(), 6710 [&FlagsSetInAll](outliner::Candidate &C) { 6711 FlagsSetInAll &= C.Flags; 6712 }); 6713 6714 // According to the AArch64 Procedure Call Standard, the following are 6715 // undefined on entry/exit from a function call: 6716 // 6717 // * Registers x16, x17, (and thus w16, w17) 6718 // * Condition codes (and thus the NZCV register) 6719 // 6720 // Because if this, we can't outline any sequence of instructions where 6721 // one 6722 // of these registers is live into/across it. Thus, we need to delete 6723 // those 6724 // candidates. 6725 auto CantGuaranteeValueAcrossCall = [&TRI](outliner::Candidate &C) { 6726 // If the unsafe registers in this block are all dead, then we don't need 6727 // to compute liveness here. 6728 if (C.Flags & UnsafeRegsDead) 6729 return false; 6730 C.initLRU(TRI); 6731 LiveRegUnits LRU = C.LRU; 6732 return (!LRU.available(AArch64::W16) || !LRU.available(AArch64::W17) || 6733 !LRU.available(AArch64::NZCV)); 6734 }; 6735 6736 // Are there any candidates where those registers are live? 6737 if (!(FlagsSetInAll & UnsafeRegsDead)) { 6738 // Erase every candidate that violates the restrictions above. (It could be 6739 // true that we have viable candidates, so it's not worth bailing out in 6740 // the case that, say, 1 out of 20 candidates violate the restructions.) 6741 llvm::erase_if(RepeatedSequenceLocs, CantGuaranteeValueAcrossCall); 6742 6743 // If the sequence doesn't have enough candidates left, then we're done. 6744 if (RepeatedSequenceLocs.size() < 2) 6745 return outliner::OutlinedFunction(); 6746 } 6747 6748 // At this point, we have only "safe" candidates to outline. Figure out 6749 // frame + call instruction information. 6750 6751 unsigned LastInstrOpcode = RepeatedSequenceLocs[0].back()->getOpcode(); 6752 6753 // Helper lambda which sets call information for every candidate. 6754 auto SetCandidateCallInfo = 6755 [&RepeatedSequenceLocs](unsigned CallID, unsigned NumBytesForCall) { 6756 for (outliner::Candidate &C : RepeatedSequenceLocs) 6757 C.setCallInfo(CallID, NumBytesForCall); 6758 }; 6759 6760 unsigned FrameID = MachineOutlinerDefault; 6761 NumBytesToCreateFrame += 4; 6762 6763 bool HasBTI = any_of(RepeatedSequenceLocs, [](outliner::Candidate &C) { 6764 return C.getMF()->getInfo<AArch64FunctionInfo>()->branchTargetEnforcement(); 6765 }); 6766 6767 // We check to see if CFI Instructions are present, and if they are 6768 // we find the number of CFI Instructions in the candidates. 6769 unsigned CFICount = 0; 6770 MachineBasicBlock::iterator MBBI = RepeatedSequenceLocs[0].front(); 6771 for (unsigned Loc = RepeatedSequenceLocs[0].getStartIdx(); 6772 Loc < RepeatedSequenceLocs[0].getEndIdx() + 1; Loc++) { 6773 if (MBBI->isCFIInstruction()) 6774 CFICount++; 6775 MBBI++; 6776 } 6777 6778 // We compare the number of found CFI Instructions to the number of CFI 6779 // instructions in the parent function for each candidate. We must check this 6780 // since if we outline one of the CFI instructions in a function, we have to 6781 // outline them all for correctness. If we do not, the address offsets will be 6782 // incorrect between the two sections of the program. 6783 for (outliner::Candidate &C : RepeatedSequenceLocs) { 6784 std::vector<MCCFIInstruction> CFIInstructions = 6785 C.getMF()->getFrameInstructions(); 6786 6787 if (CFICount > 0 && CFICount != CFIInstructions.size()) 6788 return outliner::OutlinedFunction(); 6789 } 6790 6791 // Returns true if an instructions is safe to fix up, false otherwise. 6792 auto IsSafeToFixup = [this, &TRI](MachineInstr &MI) { 6793 if (MI.isCall()) 6794 return true; 6795 6796 if (!MI.modifiesRegister(AArch64::SP, &TRI) && 6797 !MI.readsRegister(AArch64::SP, &TRI)) 6798 return true; 6799 6800 // Any modification of SP will break our code to save/restore LR. 6801 // FIXME: We could handle some instructions which add a constant 6802 // offset to SP, with a bit more work. 6803 if (MI.modifiesRegister(AArch64::SP, &TRI)) 6804 return false; 6805 6806 // At this point, we have a stack instruction that we might need to 6807 // fix up. We'll handle it if it's a load or store. 6808 if (MI.mayLoadOrStore()) { 6809 const MachineOperand *Base; // Filled with the base operand of MI. 6810 int64_t Offset; // Filled with the offset of MI. 6811 bool OffsetIsScalable; 6812 6813 // Does it allow us to offset the base operand and is the base the 6814 // register SP? 6815 if (!getMemOperandWithOffset(MI, Base, Offset, OffsetIsScalable, &TRI) || 6816 !Base->isReg() || Base->getReg() != AArch64::SP) 6817 return false; 6818 6819 // Fixe-up code below assumes bytes. 6820 if (OffsetIsScalable) 6821 return false; 6822 6823 // Find the minimum/maximum offset for this instruction and check 6824 // if fixing it up would be in range. 6825 int64_t MinOffset, 6826 MaxOffset; // Unscaled offsets for the instruction. 6827 TypeSize Scale(0U, false); // The scale to multiply the offsets by. 6828 unsigned DummyWidth; 6829 getMemOpInfo(MI.getOpcode(), Scale, DummyWidth, MinOffset, MaxOffset); 6830 6831 Offset += 16; // Update the offset to what it would be if we outlined. 6832 if (Offset < MinOffset * (int64_t)Scale.getFixedSize() || 6833 Offset > MaxOffset * (int64_t)Scale.getFixedSize()) 6834 return false; 6835 6836 // It's in range, so we can outline it. 6837 return true; 6838 } 6839 6840 // FIXME: Add handling for instructions like "add x0, sp, #8". 6841 6842 // We can't fix it up, so don't outline it. 6843 return false; 6844 }; 6845 6846 // True if it's possible to fix up each stack instruction in this sequence. 6847 // Important for frames/call variants that modify the stack. 6848 bool AllStackInstrsSafe = std::all_of( 6849 FirstCand.front(), std::next(FirstCand.back()), IsSafeToFixup); 6850 6851 // If the last instruction in any candidate is a terminator, then we should 6852 // tail call all of the candidates. 6853 if (RepeatedSequenceLocs[0].back()->isTerminator()) { 6854 FrameID = MachineOutlinerTailCall; 6855 NumBytesToCreateFrame = 0; 6856 SetCandidateCallInfo(MachineOutlinerTailCall, 4); 6857 } 6858 6859 else if (LastInstrOpcode == AArch64::BL || 6860 ((LastInstrOpcode == AArch64::BLR || 6861 LastInstrOpcode == AArch64::BLRNoIP) && 6862 !HasBTI)) { 6863 // FIXME: Do we need to check if the code after this uses the value of LR? 6864 FrameID = MachineOutlinerThunk; 6865 NumBytesToCreateFrame = 0; 6866 SetCandidateCallInfo(MachineOutlinerThunk, 4); 6867 } 6868 6869 else { 6870 // We need to decide how to emit calls + frames. We can always emit the same 6871 // frame if we don't need to save to the stack. If we have to save to the 6872 // stack, then we need a different frame. 6873 unsigned NumBytesNoStackCalls = 0; 6874 std::vector<outliner::Candidate> CandidatesWithoutStackFixups; 6875 6876 // Check if we have to save LR. 6877 for (outliner::Candidate &C : RepeatedSequenceLocs) { 6878 C.initLRU(TRI); 6879 6880 // If we have a noreturn caller, then we're going to be conservative and 6881 // say that we have to save LR. If we don't have a ret at the end of the 6882 // block, then we can't reason about liveness accurately. 6883 // 6884 // FIXME: We can probably do better than always disabling this in 6885 // noreturn functions by fixing up the liveness info. 6886 bool IsNoReturn = 6887 C.getMF()->getFunction().hasFnAttribute(Attribute::NoReturn); 6888 6889 // Is LR available? If so, we don't need a save. 6890 if (C.LRU.available(AArch64::LR) && !IsNoReturn) { 6891 NumBytesNoStackCalls += 4; 6892 C.setCallInfo(MachineOutlinerNoLRSave, 4); 6893 CandidatesWithoutStackFixups.push_back(C); 6894 } 6895 6896 // Is an unused register available? If so, we won't modify the stack, so 6897 // we can outline with the same frame type as those that don't save LR. 6898 else if (findRegisterToSaveLRTo(C)) { 6899 NumBytesNoStackCalls += 12; 6900 C.setCallInfo(MachineOutlinerRegSave, 12); 6901 CandidatesWithoutStackFixups.push_back(C); 6902 } 6903 6904 // Is SP used in the sequence at all? If not, we don't have to modify 6905 // the stack, so we are guaranteed to get the same frame. 6906 else if (C.UsedInSequence.available(AArch64::SP)) { 6907 NumBytesNoStackCalls += 12; 6908 C.setCallInfo(MachineOutlinerDefault, 12); 6909 CandidatesWithoutStackFixups.push_back(C); 6910 } 6911 6912 // If we outline this, we need to modify the stack. Pretend we don't 6913 // outline this by saving all of its bytes. 6914 else { 6915 NumBytesNoStackCalls += SequenceSize; 6916 } 6917 } 6918 6919 // If there are no places where we have to save LR, then note that we 6920 // don't have to update the stack. Otherwise, give every candidate the 6921 // default call type, as long as it's safe to do so. 6922 if (!AllStackInstrsSafe || 6923 NumBytesNoStackCalls <= RepeatedSequenceLocs.size() * 12) { 6924 RepeatedSequenceLocs = CandidatesWithoutStackFixups; 6925 FrameID = MachineOutlinerNoLRSave; 6926 } else { 6927 SetCandidateCallInfo(MachineOutlinerDefault, 12); 6928 6929 // Bugzilla ID: 46767 6930 // TODO: Check if fixing up the stack more than once is safe so we can 6931 // outline these. 6932 // 6933 // An outline resulting in a caller that requires stack fixups at the 6934 // callsite to a callee that also requires stack fixups can happen when 6935 // there are no available registers at the candidate callsite for a 6936 // candidate that itself also has calls. 6937 // 6938 // In other words if function_containing_sequence in the following pseudo 6939 // assembly requires that we save LR at the point of the call, but there 6940 // are no available registers: in this case we save using SP and as a 6941 // result the SP offsets requires stack fixups by multiples of 16. 6942 // 6943 // function_containing_sequence: 6944 // ... 6945 // save LR to SP <- Requires stack instr fixups in OUTLINED_FUNCTION_N 6946 // call OUTLINED_FUNCTION_N 6947 // restore LR from SP 6948 // ... 6949 // 6950 // OUTLINED_FUNCTION_N: 6951 // save LR to SP <- Requires stack instr fixups in OUTLINED_FUNCTION_N 6952 // ... 6953 // bl foo 6954 // restore LR from SP 6955 // ret 6956 // 6957 // Because the code to handle more than one stack fixup does not 6958 // currently have the proper checks for legality, these cases will assert 6959 // in the AArch64 MachineOutliner. This is because the code to do this 6960 // needs more hardening, testing, better checks that generated code is 6961 // legal, etc and because it is only verified to handle a single pass of 6962 // stack fixup. 6963 // 6964 // The assert happens in AArch64InstrInfo::buildOutlinedFrame to catch 6965 // these cases until they are known to be handled. Bugzilla 46767 is 6966 // referenced in comments at the assert site. 6967 // 6968 // To avoid asserting (or generating non-legal code on noassert builds) 6969 // we remove all candidates which would need more than one stack fixup by 6970 // pruning the cases where the candidate has calls while also having no 6971 // available LR and having no available general purpose registers to copy 6972 // LR to (ie one extra stack save/restore). 6973 // 6974 if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) { 6975 erase_if(RepeatedSequenceLocs, [this](outliner::Candidate &C) { 6976 return (std::any_of( 6977 C.front(), std::next(C.back()), 6978 [](const MachineInstr &MI) { return MI.isCall(); })) && 6979 (!C.LRU.available(AArch64::LR) || !findRegisterToSaveLRTo(C)); 6980 }); 6981 } 6982 } 6983 6984 // If we dropped all of the candidates, bail out here. 6985 if (RepeatedSequenceLocs.size() < 2) { 6986 RepeatedSequenceLocs.clear(); 6987 return outliner::OutlinedFunction(); 6988 } 6989 } 6990 6991 // Does every candidate's MBB contain a call? If so, then we might have a call 6992 // in the range. 6993 if (FlagsSetInAll & MachineOutlinerMBBFlags::HasCalls) { 6994 // Check if the range contains a call. These require a save + restore of the 6995 // link register. 6996 bool ModStackToSaveLR = false; 6997 if (std::any_of(FirstCand.front(), FirstCand.back(), 6998 [](const MachineInstr &MI) { return MI.isCall(); })) 6999 ModStackToSaveLR = true; 7000 7001 // Handle the last instruction separately. If this is a tail call, then the 7002 // last instruction is a call. We don't want to save + restore in this case. 7003 // However, it could be possible that the last instruction is a call without 7004 // it being valid to tail call this sequence. We should consider this as 7005 // well. 7006 else if (FrameID != MachineOutlinerThunk && 7007 FrameID != MachineOutlinerTailCall && FirstCand.back()->isCall()) 7008 ModStackToSaveLR = true; 7009 7010 if (ModStackToSaveLR) { 7011 // We can't fix up the stack. Bail out. 7012 if (!AllStackInstrsSafe) { 7013 RepeatedSequenceLocs.clear(); 7014 return outliner::OutlinedFunction(); 7015 } 7016 7017 // Save + restore LR. 7018 NumBytesToCreateFrame += 8; 7019 } 7020 } 7021 7022 // If we have CFI instructions, we can only outline if the outlined section 7023 // can be a tail call 7024 if (FrameID != MachineOutlinerTailCall && CFICount > 0) 7025 return outliner::OutlinedFunction(); 7026 7027 return outliner::OutlinedFunction(RepeatedSequenceLocs, SequenceSize, 7028 NumBytesToCreateFrame, FrameID); 7029 } 7030 7031 bool AArch64InstrInfo::isFunctionSafeToOutlineFrom( 7032 MachineFunction &MF, bool OutlineFromLinkOnceODRs) const { 7033 const Function &F = MF.getFunction(); 7034 7035 // Can F be deduplicated by the linker? If it can, don't outline from it. 7036 if (!OutlineFromLinkOnceODRs && F.hasLinkOnceODRLinkage()) 7037 return false; 7038 7039 // Don't outline from functions with section markings; the program could 7040 // expect that all the code is in the named section. 7041 // FIXME: Allow outlining from multiple functions with the same section 7042 // marking. 7043 if (F.hasSection()) 7044 return false; 7045 7046 // Outlining from functions with redzones is unsafe since the outliner may 7047 // modify the stack. Check if hasRedZone is true or unknown; if yes, don't 7048 // outline from it. 7049 AArch64FunctionInfo *AFI = MF.getInfo<AArch64FunctionInfo>(); 7050 if (!AFI || AFI->hasRedZone().getValueOr(true)) 7051 return false; 7052 7053 // FIXME: Teach the outliner to generate/handle Windows unwind info. 7054 if (MF.getTarget().getMCAsmInfo()->usesWindowsCFI()) 7055 return false; 7056 7057 // It's safe to outline from MF. 7058 return true; 7059 } 7060 7061 bool AArch64InstrInfo::isMBBSafeToOutlineFrom(MachineBasicBlock &MBB, 7062 unsigned &Flags) const { 7063 if (!TargetInstrInfo::isMBBSafeToOutlineFrom(MBB, Flags)) 7064 return false; 7065 // Check if LR is available through all of the MBB. If it's not, then set 7066 // a flag. 7067 assert(MBB.getParent()->getRegInfo().tracksLiveness() && 7068 "Suitable Machine Function for outlining must track liveness"); 7069 LiveRegUnits LRU(getRegisterInfo()); 7070 7071 std::for_each(MBB.rbegin(), MBB.rend(), 7072 [&LRU](MachineInstr &MI) { LRU.accumulate(MI); }); 7073 7074 // Check if each of the unsafe registers are available... 7075 bool W16AvailableInBlock = LRU.available(AArch64::W16); 7076 bool W17AvailableInBlock = LRU.available(AArch64::W17); 7077 bool NZCVAvailableInBlock = LRU.available(AArch64::NZCV); 7078 7079 // If all of these are dead (and not live out), we know we don't have to check 7080 // them later. 7081 if (W16AvailableInBlock && W17AvailableInBlock && NZCVAvailableInBlock) 7082 Flags |= MachineOutlinerMBBFlags::UnsafeRegsDead; 7083 7084 // Now, add the live outs to the set. 7085 LRU.addLiveOuts(MBB); 7086 7087 // If any of these registers is available in the MBB, but also a live out of 7088 // the block, then we know outlining is unsafe. 7089 if (W16AvailableInBlock && !LRU.available(AArch64::W16)) 7090 return false; 7091 if (W17AvailableInBlock && !LRU.available(AArch64::W17)) 7092 return false; 7093 if (NZCVAvailableInBlock && !LRU.available(AArch64::NZCV)) 7094 return false; 7095 7096 // Check if there's a call inside this MachineBasicBlock. If there is, then 7097 // set a flag. 7098 if (any_of(MBB, [](MachineInstr &MI) { return MI.isCall(); })) 7099 Flags |= MachineOutlinerMBBFlags::HasCalls; 7100 7101 MachineFunction *MF = MBB.getParent(); 7102 7103 // In the event that we outline, we may have to save LR. If there is an 7104 // available register in the MBB, then we'll always save LR there. Check if 7105 // this is true. 7106 bool CanSaveLR = false; 7107 const AArch64RegisterInfo *ARI = static_cast<const AArch64RegisterInfo *>( 7108 MF->getSubtarget().getRegisterInfo()); 7109 7110 // Check if there is an available register across the sequence that we can 7111 // use. 7112 for (unsigned Reg : AArch64::GPR64RegClass) { 7113 if (!ARI->isReservedReg(*MF, Reg) && Reg != AArch64::LR && 7114 Reg != AArch64::X16 && Reg != AArch64::X17 && LRU.available(Reg)) { 7115 CanSaveLR = true; 7116 break; 7117 } 7118 } 7119 7120 // Check if we have a register we can save LR to, and if LR was used 7121 // somewhere. If both of those things are true, then we need to evaluate the 7122 // safety of outlining stack instructions later. 7123 if (!CanSaveLR && !LRU.available(AArch64::LR)) 7124 Flags |= MachineOutlinerMBBFlags::LRUnavailableSomewhere; 7125 7126 return true; 7127 } 7128 7129 outliner::InstrType 7130 AArch64InstrInfo::getOutliningType(MachineBasicBlock::iterator &MIT, 7131 unsigned Flags) const { 7132 MachineInstr &MI = *MIT; 7133 MachineBasicBlock *MBB = MI.getParent(); 7134 MachineFunction *MF = MBB->getParent(); 7135 AArch64FunctionInfo *FuncInfo = MF->getInfo<AArch64FunctionInfo>(); 7136 7137 // Don't outline anything used for return address signing. The outlined 7138 // function will get signed later if needed 7139 switch (MI.getOpcode()) { 7140 case AArch64::PACIASP: 7141 case AArch64::PACIBSP: 7142 case AArch64::AUTIASP: 7143 case AArch64::AUTIBSP: 7144 case AArch64::RETAA: 7145 case AArch64::RETAB: 7146 case AArch64::EMITBKEY: 7147 return outliner::InstrType::Illegal; 7148 } 7149 7150 // Don't outline LOHs. 7151 if (FuncInfo->getLOHRelated().count(&MI)) 7152 return outliner::InstrType::Illegal; 7153 7154 // We can only outline these if we will tail call the outlined function, or 7155 // fix up the CFI offsets. Currently, CFI instructions are outlined only if 7156 // in a tail call. 7157 // 7158 // FIXME: If the proper fixups for the offset are implemented, this should be 7159 // possible. 7160 if (MI.isCFIInstruction()) 7161 return outliner::InstrType::Legal; 7162 7163 // Don't allow debug values to impact outlining type. 7164 if (MI.isDebugInstr() || MI.isIndirectDebugValue()) 7165 return outliner::InstrType::Invisible; 7166 7167 // At this point, KILL instructions don't really tell us much so we can go 7168 // ahead and skip over them. 7169 if (MI.isKill()) 7170 return outliner::InstrType::Invisible; 7171 7172 // Is this a terminator for a basic block? 7173 if (MI.isTerminator()) { 7174 7175 // Is this the end of a function? 7176 if (MI.getParent()->succ_empty()) 7177 return outliner::InstrType::Legal; 7178 7179 // It's not, so don't outline it. 7180 return outliner::InstrType::Illegal; 7181 } 7182 7183 // Make sure none of the operands are un-outlinable. 7184 for (const MachineOperand &MOP : MI.operands()) { 7185 if (MOP.isCPI() || MOP.isJTI() || MOP.isCFIIndex() || MOP.isFI() || 7186 MOP.isTargetIndex()) 7187 return outliner::InstrType::Illegal; 7188 7189 // If it uses LR or W30 explicitly, then don't touch it. 7190 if (MOP.isReg() && !MOP.isImplicit() && 7191 (MOP.getReg() == AArch64::LR || MOP.getReg() == AArch64::W30)) 7192 return outliner::InstrType::Illegal; 7193 } 7194 7195 // Special cases for instructions that can always be outlined, but will fail 7196 // the later tests. e.g, ADRPs, which are PC-relative use LR, but can always 7197 // be outlined because they don't require a *specific* value to be in LR. 7198 if (MI.getOpcode() == AArch64::ADRP) 7199 return outliner::InstrType::Legal; 7200 7201 // If MI is a call we might be able to outline it. We don't want to outline 7202 // any calls that rely on the position of items on the stack. When we outline 7203 // something containing a call, we have to emit a save and restore of LR in 7204 // the outlined function. Currently, this always happens by saving LR to the 7205 // stack. Thus, if we outline, say, half the parameters for a function call 7206 // plus the call, then we'll break the callee's expectations for the layout 7207 // of the stack. 7208 // 7209 // FIXME: Allow calls to functions which construct a stack frame, as long 7210 // as they don't access arguments on the stack. 7211 // FIXME: Figure out some way to analyze functions defined in other modules. 7212 // We should be able to compute the memory usage based on the IR calling 7213 // convention, even if we can't see the definition. 7214 if (MI.isCall()) { 7215 // Get the function associated with the call. Look at each operand and find 7216 // the one that represents the callee and get its name. 7217 const Function *Callee = nullptr; 7218 for (const MachineOperand &MOP : MI.operands()) { 7219 if (MOP.isGlobal()) { 7220 Callee = dyn_cast<Function>(MOP.getGlobal()); 7221 break; 7222 } 7223 } 7224 7225 // Never outline calls to mcount. There isn't any rule that would require 7226 // this, but the Linux kernel's "ftrace" feature depends on it. 7227 if (Callee && Callee->getName() == "\01_mcount") 7228 return outliner::InstrType::Illegal; 7229 7230 // If we don't know anything about the callee, assume it depends on the 7231 // stack layout of the caller. In that case, it's only legal to outline 7232 // as a tail-call. Explicitly list the call instructions we know about so we 7233 // don't get unexpected results with call pseudo-instructions. 7234 auto UnknownCallOutlineType = outliner::InstrType::Illegal; 7235 if (MI.getOpcode() == AArch64::BLR || 7236 MI.getOpcode() == AArch64::BLRNoIP || MI.getOpcode() == AArch64::BL) 7237 UnknownCallOutlineType = outliner::InstrType::LegalTerminator; 7238 7239 if (!Callee) 7240 return UnknownCallOutlineType; 7241 7242 // We have a function we have information about. Check it if it's something 7243 // can safely outline. 7244 MachineFunction *CalleeMF = MF->getMMI().getMachineFunction(*Callee); 7245 7246 // We don't know what's going on with the callee at all. Don't touch it. 7247 if (!CalleeMF) 7248 return UnknownCallOutlineType; 7249 7250 // Check if we know anything about the callee saves on the function. If we 7251 // don't, then don't touch it, since that implies that we haven't 7252 // computed anything about its stack frame yet. 7253 MachineFrameInfo &MFI = CalleeMF->getFrameInfo(); 7254 if (!MFI.isCalleeSavedInfoValid() || MFI.getStackSize() > 0 || 7255 MFI.getNumObjects() > 0) 7256 return UnknownCallOutlineType; 7257 7258 // At this point, we can say that CalleeMF ought to not pass anything on the 7259 // stack. Therefore, we can outline it. 7260 return outliner::InstrType::Legal; 7261 } 7262 7263 // Don't outline positions. 7264 if (MI.isPosition()) 7265 return outliner::InstrType::Illegal; 7266 7267 // Don't touch the link register or W30. 7268 if (MI.readsRegister(AArch64::W30, &getRegisterInfo()) || 7269 MI.modifiesRegister(AArch64::W30, &getRegisterInfo())) 7270 return outliner::InstrType::Illegal; 7271 7272 // Don't outline BTI instructions, because that will prevent the outlining 7273 // site from being indirectly callable. 7274 if (MI.getOpcode() == AArch64::HINT) { 7275 int64_t Imm = MI.getOperand(0).getImm(); 7276 if (Imm == 32 || Imm == 34 || Imm == 36 || Imm == 38) 7277 return outliner::InstrType::Illegal; 7278 } 7279 7280 return outliner::InstrType::Legal; 7281 } 7282 7283 void AArch64InstrInfo::fixupPostOutline(MachineBasicBlock &MBB) const { 7284 for (MachineInstr &MI : MBB) { 7285 const MachineOperand *Base; 7286 unsigned Width; 7287 int64_t Offset; 7288 bool OffsetIsScalable; 7289 7290 // Is this a load or store with an immediate offset with SP as the base? 7291 if (!MI.mayLoadOrStore() || 7292 !getMemOperandWithOffsetWidth(MI, Base, Offset, OffsetIsScalable, Width, 7293 &RI) || 7294 (Base->isReg() && Base->getReg() != AArch64::SP)) 7295 continue; 7296 7297 // It is, so we have to fix it up. 7298 TypeSize Scale(0U, false); 7299 int64_t Dummy1, Dummy2; 7300 7301 MachineOperand &StackOffsetOperand = getMemOpBaseRegImmOfsOffsetOperand(MI); 7302 assert(StackOffsetOperand.isImm() && "Stack offset wasn't immediate!"); 7303 getMemOpInfo(MI.getOpcode(), Scale, Width, Dummy1, Dummy2); 7304 assert(Scale != 0 && "Unexpected opcode!"); 7305 assert(!OffsetIsScalable && "Expected offset to be a byte offset"); 7306 7307 // We've pushed the return address to the stack, so add 16 to the offset. 7308 // This is safe, since we already checked if it would overflow when we 7309 // checked if this instruction was legal to outline. 7310 int64_t NewImm = (Offset + 16) / (int64_t)Scale.getFixedSize(); 7311 StackOffsetOperand.setImm(NewImm); 7312 } 7313 } 7314 7315 static void signOutlinedFunction(MachineFunction &MF, MachineBasicBlock &MBB, 7316 bool ShouldSignReturnAddr, 7317 bool ShouldSignReturnAddrWithAKey) { 7318 if (ShouldSignReturnAddr) { 7319 MachineBasicBlock::iterator MBBPAC = MBB.begin(); 7320 MachineBasicBlock::iterator MBBAUT = MBB.getFirstTerminator(); 7321 const AArch64Subtarget &Subtarget = MF.getSubtarget<AArch64Subtarget>(); 7322 const TargetInstrInfo *TII = Subtarget.getInstrInfo(); 7323 DebugLoc DL; 7324 7325 if (MBBAUT != MBB.end()) 7326 DL = MBBAUT->getDebugLoc(); 7327 7328 // At the very beginning of the basic block we insert the following 7329 // depending on the key type 7330 // 7331 // a_key: b_key: 7332 // PACIASP EMITBKEY 7333 // CFI_INSTRUCTION PACIBSP 7334 // CFI_INSTRUCTION 7335 unsigned PACI; 7336 if (ShouldSignReturnAddrWithAKey) { 7337 PACI = Subtarget.hasPAuth() ? AArch64::PACIA : AArch64::PACIASP; 7338 } else { 7339 BuildMI(MBB, MBBPAC, DebugLoc(), TII->get(AArch64::EMITBKEY)) 7340 .setMIFlag(MachineInstr::FrameSetup); 7341 PACI = Subtarget.hasPAuth() ? AArch64::PACIB : AArch64::PACIBSP; 7342 } 7343 7344 auto MI = BuildMI(MBB, MBBPAC, DebugLoc(), TII->get(PACI)); 7345 if (Subtarget.hasPAuth()) 7346 MI.addReg(AArch64::LR, RegState::Define) 7347 .addReg(AArch64::LR) 7348 .addReg(AArch64::SP, RegState::InternalRead); 7349 MI.setMIFlag(MachineInstr::FrameSetup); 7350 7351 unsigned CFIIndex = 7352 MF.addFrameInst(MCCFIInstruction::createNegateRAState(nullptr)); 7353 BuildMI(MBB, MBBPAC, DebugLoc(), TII->get(AArch64::CFI_INSTRUCTION)) 7354 .addCFIIndex(CFIIndex) 7355 .setMIFlags(MachineInstr::FrameSetup); 7356 7357 // If v8.3a features are available we can replace a RET instruction by 7358 // RETAA or RETAB and omit the AUT instructions 7359 if (Subtarget.hasPAuth() && MBBAUT != MBB.end() && 7360 MBBAUT->getOpcode() == AArch64::RET) { 7361 BuildMI(MBB, MBBAUT, DL, 7362 TII->get(ShouldSignReturnAddrWithAKey ? AArch64::RETAA 7363 : AArch64::RETAB)) 7364 .copyImplicitOps(*MBBAUT); 7365 MBB.erase(MBBAUT); 7366 } else { 7367 BuildMI(MBB, MBBAUT, DL, 7368 TII->get(ShouldSignReturnAddrWithAKey ? AArch64::AUTIASP 7369 : AArch64::AUTIBSP)) 7370 .setMIFlag(MachineInstr::FrameDestroy); 7371 } 7372 } 7373 } 7374 7375 void AArch64InstrInfo::buildOutlinedFrame( 7376 MachineBasicBlock &MBB, MachineFunction &MF, 7377 const outliner::OutlinedFunction &OF) const { 7378 7379 AArch64FunctionInfo *FI = MF.getInfo<AArch64FunctionInfo>(); 7380 7381 if (OF.FrameConstructionID == MachineOutlinerTailCall) 7382 FI->setOutliningStyle("Tail Call"); 7383 else if (OF.FrameConstructionID == MachineOutlinerThunk) { 7384 // For thunk outlining, rewrite the last instruction from a call to a 7385 // tail-call. 7386 MachineInstr *Call = &*--MBB.instr_end(); 7387 unsigned TailOpcode; 7388 if (Call->getOpcode() == AArch64::BL) { 7389 TailOpcode = AArch64::TCRETURNdi; 7390 } else { 7391 assert(Call->getOpcode() == AArch64::BLR || 7392 Call->getOpcode() == AArch64::BLRNoIP); 7393 TailOpcode = AArch64::TCRETURNriALL; 7394 } 7395 MachineInstr *TC = BuildMI(MF, DebugLoc(), get(TailOpcode)) 7396 .add(Call->getOperand(0)) 7397 .addImm(0); 7398 MBB.insert(MBB.end(), TC); 7399 Call->eraseFromParent(); 7400 7401 FI->setOutliningStyle("Thunk"); 7402 } 7403 7404 bool IsLeafFunction = true; 7405 7406 // Is there a call in the outlined range? 7407 auto IsNonTailCall = [](const MachineInstr &MI) { 7408 return MI.isCall() && !MI.isReturn(); 7409 }; 7410 7411 if (llvm::any_of(MBB.instrs(), IsNonTailCall)) { 7412 // Fix up the instructions in the range, since we're going to modify the 7413 // stack. 7414 7415 // Bugzilla ID: 46767 7416 // TODO: Check if fixing up twice is safe so we can outline these. 7417 assert(OF.FrameConstructionID != MachineOutlinerDefault && 7418 "Can only fix up stack references once"); 7419 fixupPostOutline(MBB); 7420 7421 IsLeafFunction = false; 7422 7423 // LR has to be a live in so that we can save it. 7424 if (!MBB.isLiveIn(AArch64::LR)) 7425 MBB.addLiveIn(AArch64::LR); 7426 7427 MachineBasicBlock::iterator It = MBB.begin(); 7428 MachineBasicBlock::iterator Et = MBB.end(); 7429 7430 if (OF.FrameConstructionID == MachineOutlinerTailCall || 7431 OF.FrameConstructionID == MachineOutlinerThunk) 7432 Et = std::prev(MBB.end()); 7433 7434 // Insert a save before the outlined region 7435 MachineInstr *STRXpre = BuildMI(MF, DebugLoc(), get(AArch64::STRXpre)) 7436 .addReg(AArch64::SP, RegState::Define) 7437 .addReg(AArch64::LR) 7438 .addReg(AArch64::SP) 7439 .addImm(-16); 7440 It = MBB.insert(It, STRXpre); 7441 7442 const TargetSubtargetInfo &STI = MF.getSubtarget(); 7443 const MCRegisterInfo *MRI = STI.getRegisterInfo(); 7444 unsigned DwarfReg = MRI->getDwarfRegNum(AArch64::LR, true); 7445 7446 // Add a CFI saying the stack was moved 16 B down. 7447 int64_t StackPosEntry = 7448 MF.addFrameInst(MCCFIInstruction::cfiDefCfaOffset(nullptr, 16)); 7449 BuildMI(MBB, It, DebugLoc(), get(AArch64::CFI_INSTRUCTION)) 7450 .addCFIIndex(StackPosEntry) 7451 .setMIFlags(MachineInstr::FrameSetup); 7452 7453 // Add a CFI saying that the LR that we want to find is now 16 B higher than 7454 // before. 7455 int64_t LRPosEntry = 7456 MF.addFrameInst(MCCFIInstruction::createOffset(nullptr, DwarfReg, -16)); 7457 BuildMI(MBB, It, DebugLoc(), get(AArch64::CFI_INSTRUCTION)) 7458 .addCFIIndex(LRPosEntry) 7459 .setMIFlags(MachineInstr::FrameSetup); 7460 7461 // Insert a restore before the terminator for the function. 7462 MachineInstr *LDRXpost = BuildMI(MF, DebugLoc(), get(AArch64::LDRXpost)) 7463 .addReg(AArch64::SP, RegState::Define) 7464 .addReg(AArch64::LR, RegState::Define) 7465 .addReg(AArch64::SP) 7466 .addImm(16); 7467 Et = MBB.insert(Et, LDRXpost); 7468 } 7469 7470 // If a bunch of candidates reach this point they must agree on their return 7471 // address signing. It is therefore enough to just consider the signing 7472 // behaviour of one of them 7473 const auto &MFI = *OF.Candidates.front().getMF()->getInfo<AArch64FunctionInfo>(); 7474 bool ShouldSignReturnAddr = MFI.shouldSignReturnAddress(!IsLeafFunction); 7475 7476 // a_key is the default 7477 bool ShouldSignReturnAddrWithAKey = !MFI.shouldSignWithBKey(); 7478 7479 // If this is a tail call outlined function, then there's already a return. 7480 if (OF.FrameConstructionID == MachineOutlinerTailCall || 7481 OF.FrameConstructionID == MachineOutlinerThunk) { 7482 signOutlinedFunction(MF, MBB, ShouldSignReturnAddr, 7483 ShouldSignReturnAddrWithAKey); 7484 return; 7485 } 7486 7487 // It's not a tail call, so we have to insert the return ourselves. 7488 7489 // LR has to be a live in so that we can return to it. 7490 if (!MBB.isLiveIn(AArch64::LR)) 7491 MBB.addLiveIn(AArch64::LR); 7492 7493 MachineInstr *ret = BuildMI(MF, DebugLoc(), get(AArch64::RET)) 7494 .addReg(AArch64::LR); 7495 MBB.insert(MBB.end(), ret); 7496 7497 signOutlinedFunction(MF, MBB, ShouldSignReturnAddr, 7498 ShouldSignReturnAddrWithAKey); 7499 7500 FI->setOutliningStyle("Function"); 7501 7502 // Did we have to modify the stack by saving the link register? 7503 if (OF.FrameConstructionID != MachineOutlinerDefault) 7504 return; 7505 7506 // We modified the stack. 7507 // Walk over the basic block and fix up all the stack accesses. 7508 fixupPostOutline(MBB); 7509 } 7510 7511 MachineBasicBlock::iterator AArch64InstrInfo::insertOutlinedCall( 7512 Module &M, MachineBasicBlock &MBB, MachineBasicBlock::iterator &It, 7513 MachineFunction &MF, const outliner::Candidate &C) const { 7514 7515 // Are we tail calling? 7516 if (C.CallConstructionID == MachineOutlinerTailCall) { 7517 // If yes, then we can just branch to the label. 7518 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::TCRETURNdi)) 7519 .addGlobalAddress(M.getNamedValue(MF.getName())) 7520 .addImm(0)); 7521 return It; 7522 } 7523 7524 // Are we saving the link register? 7525 if (C.CallConstructionID == MachineOutlinerNoLRSave || 7526 C.CallConstructionID == MachineOutlinerThunk) { 7527 // No, so just insert the call. 7528 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::BL)) 7529 .addGlobalAddress(M.getNamedValue(MF.getName()))); 7530 return It; 7531 } 7532 7533 // We want to return the spot where we inserted the call. 7534 MachineBasicBlock::iterator CallPt; 7535 7536 // Instructions for saving and restoring LR around the call instruction we're 7537 // going to insert. 7538 MachineInstr *Save; 7539 MachineInstr *Restore; 7540 // Can we save to a register? 7541 if (C.CallConstructionID == MachineOutlinerRegSave) { 7542 // FIXME: This logic should be sunk into a target-specific interface so that 7543 // we don't have to recompute the register. 7544 unsigned Reg = findRegisterToSaveLRTo(C); 7545 assert(Reg != 0 && "No callee-saved register available?"); 7546 7547 // LR has to be a live in so that we can save it. 7548 if (!MBB.isLiveIn(AArch64::LR)) 7549 MBB.addLiveIn(AArch64::LR); 7550 7551 // Save and restore LR from Reg. 7552 Save = BuildMI(MF, DebugLoc(), get(AArch64::ORRXrs), Reg) 7553 .addReg(AArch64::XZR) 7554 .addReg(AArch64::LR) 7555 .addImm(0); 7556 Restore = BuildMI(MF, DebugLoc(), get(AArch64::ORRXrs), AArch64::LR) 7557 .addReg(AArch64::XZR) 7558 .addReg(Reg) 7559 .addImm(0); 7560 } else { 7561 // We have the default case. Save and restore from SP. 7562 Save = BuildMI(MF, DebugLoc(), get(AArch64::STRXpre)) 7563 .addReg(AArch64::SP, RegState::Define) 7564 .addReg(AArch64::LR) 7565 .addReg(AArch64::SP) 7566 .addImm(-16); 7567 Restore = BuildMI(MF, DebugLoc(), get(AArch64::LDRXpost)) 7568 .addReg(AArch64::SP, RegState::Define) 7569 .addReg(AArch64::LR, RegState::Define) 7570 .addReg(AArch64::SP) 7571 .addImm(16); 7572 } 7573 7574 It = MBB.insert(It, Save); 7575 It++; 7576 7577 // Insert the call. 7578 It = MBB.insert(It, BuildMI(MF, DebugLoc(), get(AArch64::BL)) 7579 .addGlobalAddress(M.getNamedValue(MF.getName()))); 7580 CallPt = It; 7581 It++; 7582 7583 It = MBB.insert(It, Restore); 7584 return CallPt; 7585 } 7586 7587 bool AArch64InstrInfo::shouldOutlineFromFunctionByDefault( 7588 MachineFunction &MF) const { 7589 return MF.getFunction().hasMinSize(); 7590 } 7591 7592 Optional<DestSourcePair> 7593 AArch64InstrInfo::isCopyInstrImpl(const MachineInstr &MI) const { 7594 7595 // AArch64::ORRWrs and AArch64::ORRXrs with WZR/XZR reg 7596 // and zero immediate operands used as an alias for mov instruction. 7597 if (MI.getOpcode() == AArch64::ORRWrs && 7598 MI.getOperand(1).getReg() == AArch64::WZR && 7599 MI.getOperand(3).getImm() == 0x0) { 7600 return DestSourcePair{MI.getOperand(0), MI.getOperand(2)}; 7601 } 7602 7603 if (MI.getOpcode() == AArch64::ORRXrs && 7604 MI.getOperand(1).getReg() == AArch64::XZR && 7605 MI.getOperand(3).getImm() == 0x0) { 7606 return DestSourcePair{MI.getOperand(0), MI.getOperand(2)}; 7607 } 7608 7609 return None; 7610 } 7611 7612 Optional<RegImmPair> AArch64InstrInfo::isAddImmediate(const MachineInstr &MI, 7613 Register Reg) const { 7614 int Sign = 1; 7615 int64_t Offset = 0; 7616 7617 // TODO: Handle cases where Reg is a super- or sub-register of the 7618 // destination register. 7619 const MachineOperand &Op0 = MI.getOperand(0); 7620 if (!Op0.isReg() || Reg != Op0.getReg()) 7621 return None; 7622 7623 switch (MI.getOpcode()) { 7624 default: 7625 return None; 7626 case AArch64::SUBWri: 7627 case AArch64::SUBXri: 7628 case AArch64::SUBSWri: 7629 case AArch64::SUBSXri: 7630 Sign *= -1; 7631 LLVM_FALLTHROUGH; 7632 case AArch64::ADDSWri: 7633 case AArch64::ADDSXri: 7634 case AArch64::ADDWri: 7635 case AArch64::ADDXri: { 7636 // TODO: Third operand can be global address (usually some string). 7637 if (!MI.getOperand(0).isReg() || !MI.getOperand(1).isReg() || 7638 !MI.getOperand(2).isImm()) 7639 return None; 7640 int Shift = MI.getOperand(3).getImm(); 7641 assert((Shift == 0 || Shift == 12) && "Shift can be either 0 or 12"); 7642 Offset = Sign * (MI.getOperand(2).getImm() << Shift); 7643 } 7644 } 7645 return RegImmPair{MI.getOperand(1).getReg(), Offset}; 7646 } 7647 7648 /// If the given ORR instruction is a copy, and \p DescribedReg overlaps with 7649 /// the destination register then, if possible, describe the value in terms of 7650 /// the source register. 7651 static Optional<ParamLoadedValue> 7652 describeORRLoadedValue(const MachineInstr &MI, Register DescribedReg, 7653 const TargetInstrInfo *TII, 7654 const TargetRegisterInfo *TRI) { 7655 auto DestSrc = TII->isCopyInstr(MI); 7656 if (!DestSrc) 7657 return None; 7658 7659 Register DestReg = DestSrc->Destination->getReg(); 7660 Register SrcReg = DestSrc->Source->getReg(); 7661 7662 auto Expr = DIExpression::get(MI.getMF()->getFunction().getContext(), {}); 7663 7664 // If the described register is the destination, just return the source. 7665 if (DestReg == DescribedReg) 7666 return ParamLoadedValue(MachineOperand::CreateReg(SrcReg, false), Expr); 7667 7668 // ORRWrs zero-extends to 64-bits, so we need to consider such cases. 7669 if (MI.getOpcode() == AArch64::ORRWrs && 7670 TRI->isSuperRegister(DestReg, DescribedReg)) 7671 return ParamLoadedValue(MachineOperand::CreateReg(SrcReg, false), Expr); 7672 7673 // We may need to describe the lower part of a ORRXrs move. 7674 if (MI.getOpcode() == AArch64::ORRXrs && 7675 TRI->isSubRegister(DestReg, DescribedReg)) { 7676 Register SrcSubReg = TRI->getSubReg(SrcReg, AArch64::sub_32); 7677 return ParamLoadedValue(MachineOperand::CreateReg(SrcSubReg, false), Expr); 7678 } 7679 7680 assert(!TRI->isSuperOrSubRegisterEq(DestReg, DescribedReg) && 7681 "Unhandled ORR[XW]rs copy case"); 7682 7683 return None; 7684 } 7685 7686 Optional<ParamLoadedValue> 7687 AArch64InstrInfo::describeLoadedValue(const MachineInstr &MI, 7688 Register Reg) const { 7689 const MachineFunction *MF = MI.getMF(); 7690 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 7691 switch (MI.getOpcode()) { 7692 case AArch64::MOVZWi: 7693 case AArch64::MOVZXi: { 7694 // MOVZWi may be used for producing zero-extended 32-bit immediates in 7695 // 64-bit parameters, so we need to consider super-registers. 7696 if (!TRI->isSuperRegisterEq(MI.getOperand(0).getReg(), Reg)) 7697 return None; 7698 7699 if (!MI.getOperand(1).isImm()) 7700 return None; 7701 int64_t Immediate = MI.getOperand(1).getImm(); 7702 int Shift = MI.getOperand(2).getImm(); 7703 return ParamLoadedValue(MachineOperand::CreateImm(Immediate << Shift), 7704 nullptr); 7705 } 7706 case AArch64::ORRWrs: 7707 case AArch64::ORRXrs: 7708 return describeORRLoadedValue(MI, Reg, this, TRI); 7709 } 7710 7711 return TargetInstrInfo::describeLoadedValue(MI, Reg); 7712 } 7713 7714 bool AArch64InstrInfo::isExtendLikelyToBeFolded( 7715 MachineInstr &ExtMI, MachineRegisterInfo &MRI) const { 7716 assert(ExtMI.getOpcode() == TargetOpcode::G_SEXT || 7717 ExtMI.getOpcode() == TargetOpcode::G_ZEXT || 7718 ExtMI.getOpcode() == TargetOpcode::G_ANYEXT); 7719 7720 // Anyexts are nops. 7721 if (ExtMI.getOpcode() == TargetOpcode::G_ANYEXT) 7722 return true; 7723 7724 Register DefReg = ExtMI.getOperand(0).getReg(); 7725 if (!MRI.hasOneNonDBGUse(DefReg)) 7726 return false; 7727 7728 // It's likely that a sext/zext as a G_PTR_ADD offset will be folded into an 7729 // addressing mode. 7730 auto *UserMI = &*MRI.use_instr_nodbg_begin(DefReg); 7731 return UserMI->getOpcode() == TargetOpcode::G_PTR_ADD; 7732 } 7733 7734 uint64_t AArch64InstrInfo::getElementSizeForOpcode(unsigned Opc) const { 7735 return get(Opc).TSFlags & AArch64::ElementSizeMask; 7736 } 7737 7738 bool AArch64InstrInfo::isPTestLikeOpcode(unsigned Opc) const { 7739 return get(Opc).TSFlags & AArch64::InstrFlagIsPTestLike; 7740 } 7741 7742 bool AArch64InstrInfo::isWhileOpcode(unsigned Opc) const { 7743 return get(Opc).TSFlags & AArch64::InstrFlagIsWhile; 7744 } 7745 7746 unsigned int 7747 AArch64InstrInfo::getTailDuplicateSize(CodeGenOpt::Level OptLevel) const { 7748 return OptLevel >= CodeGenOpt::Aggressive ? 6 : 2; 7749 } 7750 7751 unsigned llvm::getBLRCallOpcode(const MachineFunction &MF) { 7752 if (MF.getSubtarget<AArch64Subtarget>().hardenSlsBlr()) 7753 return AArch64::BLRNoIP; 7754 else 7755 return AArch64::BLR; 7756 } 7757 7758 #define GET_INSTRINFO_HELPERS 7759 #define GET_INSTRMAP_INFO 7760 #include "AArch64GenInstrInfo.inc" 7761