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