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