1 //===- AArch64InstrInfo.cpp - AArch64 Instruction Information -------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the AArch64 implementation of the TargetInstrInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "AArch64InstrInfo.h" 15 #include "AArch64Subtarget.h" 16 #include "MCTargetDesc/AArch64AddressingModes.h" 17 #include "llvm/CodeGen/MachineFrameInfo.h" 18 #include "llvm/CodeGen/MachineInstrBuilder.h" 19 #include "llvm/CodeGen/MachineMemOperand.h" 20 #include "llvm/CodeGen/MachineRegisterInfo.h" 21 #include "llvm/CodeGen/PseudoSourceValue.h" 22 #include "llvm/MC/MCInst.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/TargetRegistry.h" 25 #include <algorithm> 26 27 using namespace llvm; 28 29 #define GET_INSTRINFO_CTOR_DTOR 30 #include "AArch64GenInstrInfo.inc" 31 32 AArch64InstrInfo::AArch64InstrInfo(const AArch64Subtarget &STI) 33 : AArch64GenInstrInfo(AArch64::ADJCALLSTACKDOWN, AArch64::ADJCALLSTACKUP), 34 RI(STI.getTargetTriple()), Subtarget(STI) {} 35 36 /// GetInstSize - Return the number of bytes of code the specified 37 /// instruction may be. This returns the maximum number of bytes. 38 unsigned AArch64InstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { 39 const MachineBasicBlock &MBB = *MI->getParent(); 40 const MachineFunction *MF = MBB.getParent(); 41 const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo(); 42 43 if (MI->getOpcode() == AArch64::INLINEASM) 44 return getInlineAsmLength(MI->getOperand(0).getSymbolName(), *MAI); 45 46 const MCInstrDesc &Desc = MI->getDesc(); 47 switch (Desc.getOpcode()) { 48 default: 49 // Anything not explicitly designated otherwise is a nomal 4-byte insn. 50 return 4; 51 case TargetOpcode::DBG_VALUE: 52 case TargetOpcode::EH_LABEL: 53 case TargetOpcode::IMPLICIT_DEF: 54 case TargetOpcode::KILL: 55 return 0; 56 } 57 58 llvm_unreachable("GetInstSizeInBytes()- Unable to determin insn size"); 59 } 60 61 static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, 62 SmallVectorImpl<MachineOperand> &Cond) { 63 // Block ends with fall-through condbranch. 64 switch (LastInst->getOpcode()) { 65 default: 66 llvm_unreachable("Unknown branch instruction?"); 67 case AArch64::Bcc: 68 Target = LastInst->getOperand(1).getMBB(); 69 Cond.push_back(LastInst->getOperand(0)); 70 break; 71 case AArch64::CBZW: 72 case AArch64::CBZX: 73 case AArch64::CBNZW: 74 case AArch64::CBNZX: 75 Target = LastInst->getOperand(1).getMBB(); 76 Cond.push_back(MachineOperand::CreateImm(-1)); 77 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); 78 Cond.push_back(LastInst->getOperand(0)); 79 break; 80 case AArch64::TBZW: 81 case AArch64::TBZX: 82 case AArch64::TBNZW: 83 case AArch64::TBNZX: 84 Target = LastInst->getOperand(2).getMBB(); 85 Cond.push_back(MachineOperand::CreateImm(-1)); 86 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); 87 Cond.push_back(LastInst->getOperand(0)); 88 Cond.push_back(LastInst->getOperand(1)); 89 } 90 } 91 92 // Branch analysis. 93 bool AArch64InstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 94 MachineBasicBlock *&TBB, 95 MachineBasicBlock *&FBB, 96 SmallVectorImpl<MachineOperand> &Cond, 97 bool AllowModify) const { 98 // If the block has no terminators, it just falls into the block after it. 99 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 100 if (I == MBB.end()) 101 return false; 102 103 if (!isUnpredicatedTerminator(*I)) 104 return false; 105 106 // Get the last instruction in the block. 107 MachineInstr *LastInst = I; 108 109 // If there is only one terminator instruction, process it. 110 unsigned LastOpc = LastInst->getOpcode(); 111 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 112 if (isUncondBranchOpcode(LastOpc)) { 113 TBB = LastInst->getOperand(0).getMBB(); 114 return false; 115 } 116 if (isCondBranchOpcode(LastOpc)) { 117 // Block ends with fall-through condbranch. 118 parseCondBranch(LastInst, TBB, Cond); 119 return false; 120 } 121 return true; // Can't handle indirect branch. 122 } 123 124 // Get the instruction before it if it is a terminator. 125 MachineInstr *SecondLastInst = I; 126 unsigned SecondLastOpc = SecondLastInst->getOpcode(); 127 128 // If AllowModify is true and the block ends with two or more unconditional 129 // branches, delete all but the first unconditional branch. 130 if (AllowModify && isUncondBranchOpcode(LastOpc)) { 131 while (isUncondBranchOpcode(SecondLastOpc)) { 132 LastInst->eraseFromParent(); 133 LastInst = SecondLastInst; 134 LastOpc = LastInst->getOpcode(); 135 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) { 136 // Return now the only terminator is an unconditional branch. 137 TBB = LastInst->getOperand(0).getMBB(); 138 return false; 139 } else { 140 SecondLastInst = I; 141 SecondLastOpc = SecondLastInst->getOpcode(); 142 } 143 } 144 } 145 146 // If there are three terminators, we don't know what sort of block this is. 147 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I)) 148 return true; 149 150 // If the block ends with a B and a Bcc, handle it. 151 if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 152 parseCondBranch(SecondLastInst, TBB, Cond); 153 FBB = LastInst->getOperand(0).getMBB(); 154 return false; 155 } 156 157 // If the block ends with two unconditional branches, handle it. The second 158 // one is not executed, so remove it. 159 if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 160 TBB = SecondLastInst->getOperand(0).getMBB(); 161 I = LastInst; 162 if (AllowModify) 163 I->eraseFromParent(); 164 return false; 165 } 166 167 // ...likewise if it ends with an indirect branch followed by an unconditional 168 // branch. 169 if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) { 170 I = LastInst; 171 if (AllowModify) 172 I->eraseFromParent(); 173 return true; 174 } 175 176 // Otherwise, can't handle this. 177 return true; 178 } 179 180 bool AArch64InstrInfo::ReverseBranchCondition( 181 SmallVectorImpl<MachineOperand> &Cond) const { 182 if (Cond[0].getImm() != -1) { 183 // Regular Bcc 184 AArch64CC::CondCode CC = (AArch64CC::CondCode)(int)Cond[0].getImm(); 185 Cond[0].setImm(AArch64CC::getInvertedCondCode(CC)); 186 } else { 187 // Folded compare-and-branch 188 switch (Cond[1].getImm()) { 189 default: 190 llvm_unreachable("Unknown conditional branch!"); 191 case AArch64::CBZW: 192 Cond[1].setImm(AArch64::CBNZW); 193 break; 194 case AArch64::CBNZW: 195 Cond[1].setImm(AArch64::CBZW); 196 break; 197 case AArch64::CBZX: 198 Cond[1].setImm(AArch64::CBNZX); 199 break; 200 case AArch64::CBNZX: 201 Cond[1].setImm(AArch64::CBZX); 202 break; 203 case AArch64::TBZW: 204 Cond[1].setImm(AArch64::TBNZW); 205 break; 206 case AArch64::TBNZW: 207 Cond[1].setImm(AArch64::TBZW); 208 break; 209 case AArch64::TBZX: 210 Cond[1].setImm(AArch64::TBNZX); 211 break; 212 case AArch64::TBNZX: 213 Cond[1].setImm(AArch64::TBZX); 214 break; 215 } 216 } 217 218 return false; 219 } 220 221 unsigned AArch64InstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 222 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr(); 223 if (I == MBB.end()) 224 return 0; 225 226 if (!isUncondBranchOpcode(I->getOpcode()) && 227 !isCondBranchOpcode(I->getOpcode())) 228 return 0; 229 230 // Remove the branch. 231 I->eraseFromParent(); 232 233 I = MBB.end(); 234 235 if (I == MBB.begin()) 236 return 1; 237 --I; 238 if (!isCondBranchOpcode(I->getOpcode())) 239 return 1; 240 241 // Remove the branch. 242 I->eraseFromParent(); 243 return 2; 244 } 245 246 void AArch64InstrInfo::instantiateCondBranch( 247 MachineBasicBlock &MBB, DebugLoc DL, MachineBasicBlock *TBB, 248 ArrayRef<MachineOperand> Cond) const { 249 if (Cond[0].getImm() != -1) { 250 // Regular Bcc 251 BuildMI(&MBB, DL, get(AArch64::Bcc)).addImm(Cond[0].getImm()).addMBB(TBB); 252 } else { 253 // Folded compare-and-branch 254 // Note that we use addOperand instead of addReg to keep the flags. 255 const MachineInstrBuilder MIB = 256 BuildMI(&MBB, DL, get(Cond[1].getImm())).addOperand(Cond[2]); 257 if (Cond.size() > 3) 258 MIB.addImm(Cond[3].getImm()); 259 MIB.addMBB(TBB); 260 } 261 } 262 263 unsigned AArch64InstrInfo::InsertBranch( 264 MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, 265 ArrayRef<MachineOperand> Cond, DebugLoc DL) const { 266 // Shouldn't be a fall through. 267 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 268 269 if (!FBB) { 270 if (Cond.empty()) // Unconditional branch? 271 BuildMI(&MBB, DL, get(AArch64::B)).addMBB(TBB); 272 else 273 instantiateCondBranch(MBB, DL, TBB, Cond); 274 return 1; 275 } 276 277 // Two-way conditional branch. 278 instantiateCondBranch(MBB, DL, TBB, Cond); 279 BuildMI(&MBB, DL, get(AArch64::B)).addMBB(FBB); 280 return 2; 281 } 282 283 // Find the original register that VReg is copied from. 284 static unsigned removeCopies(const MachineRegisterInfo &MRI, unsigned VReg) { 285 while (TargetRegisterInfo::isVirtualRegister(VReg)) { 286 const MachineInstr *DefMI = MRI.getVRegDef(VReg); 287 if (!DefMI->isFullCopy()) 288 return VReg; 289 VReg = DefMI->getOperand(1).getReg(); 290 } 291 return VReg; 292 } 293 294 // Determine if VReg is defined by an instruction that can be folded into a 295 // csel instruction. If so, return the folded opcode, and the replacement 296 // register. 297 static unsigned canFoldIntoCSel(const MachineRegisterInfo &MRI, unsigned VReg, 298 unsigned *NewVReg = nullptr) { 299 VReg = removeCopies(MRI, VReg); 300 if (!TargetRegisterInfo::isVirtualRegister(VReg)) 301 return 0; 302 303 bool Is64Bit = AArch64::GPR64allRegClass.hasSubClassEq(MRI.getRegClass(VReg)); 304 const MachineInstr *DefMI = MRI.getVRegDef(VReg); 305 unsigned Opc = 0; 306 unsigned SrcOpNum = 0; 307 switch (DefMI->getOpcode()) { 308 case AArch64::ADDSXri: 309 case AArch64::ADDSWri: 310 // if NZCV is used, do not fold. 311 if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) == -1) 312 return 0; 313 // fall-through to ADDXri and ADDWri. 314 case AArch64::ADDXri: 315 case AArch64::ADDWri: 316 // add x, 1 -> csinc. 317 if (!DefMI->getOperand(2).isImm() || DefMI->getOperand(2).getImm() != 1 || 318 DefMI->getOperand(3).getImm() != 0) 319 return 0; 320 SrcOpNum = 1; 321 Opc = Is64Bit ? AArch64::CSINCXr : AArch64::CSINCWr; 322 break; 323 324 case AArch64::ORNXrr: 325 case AArch64::ORNWrr: { 326 // not x -> csinv, represented as orn dst, xzr, src. 327 unsigned ZReg = removeCopies(MRI, DefMI->getOperand(1).getReg()); 328 if (ZReg != AArch64::XZR && ZReg != AArch64::WZR) 329 return 0; 330 SrcOpNum = 2; 331 Opc = Is64Bit ? AArch64::CSINVXr : AArch64::CSINVWr; 332 break; 333 } 334 335 case AArch64::SUBSXrr: 336 case AArch64::SUBSWrr: 337 // if NZCV is used, do not fold. 338 if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) == -1) 339 return 0; 340 // fall-through to SUBXrr and SUBWrr. 341 case AArch64::SUBXrr: 342 case AArch64::SUBWrr: { 343 // neg x -> csneg, represented as sub dst, xzr, src. 344 unsigned ZReg = removeCopies(MRI, DefMI->getOperand(1).getReg()); 345 if (ZReg != AArch64::XZR && ZReg != AArch64::WZR) 346 return 0; 347 SrcOpNum = 2; 348 Opc = Is64Bit ? AArch64::CSNEGXr : AArch64::CSNEGWr; 349 break; 350 } 351 default: 352 return 0; 353 } 354 assert(Opc && SrcOpNum && "Missing parameters"); 355 356 if (NewVReg) 357 *NewVReg = DefMI->getOperand(SrcOpNum).getReg(); 358 return Opc; 359 } 360 361 bool AArch64InstrInfo::canInsertSelect( 362 const MachineBasicBlock &MBB, ArrayRef<MachineOperand> Cond, 363 unsigned TrueReg, unsigned FalseReg, int &CondCycles, int &TrueCycles, 364 int &FalseCycles) const { 365 // Check register classes. 366 const MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 367 const TargetRegisterClass *RC = 368 RI.getCommonSubClass(MRI.getRegClass(TrueReg), MRI.getRegClass(FalseReg)); 369 if (!RC) 370 return false; 371 372 // Expanding cbz/tbz requires an extra cycle of latency on the condition. 373 unsigned ExtraCondLat = Cond.size() != 1; 374 375 // GPRs are handled by csel. 376 // FIXME: Fold in x+1, -x, and ~x when applicable. 377 if (AArch64::GPR64allRegClass.hasSubClassEq(RC) || 378 AArch64::GPR32allRegClass.hasSubClassEq(RC)) { 379 // Single-cycle csel, csinc, csinv, and csneg. 380 CondCycles = 1 + ExtraCondLat; 381 TrueCycles = FalseCycles = 1; 382 if (canFoldIntoCSel(MRI, TrueReg)) 383 TrueCycles = 0; 384 else if (canFoldIntoCSel(MRI, FalseReg)) 385 FalseCycles = 0; 386 return true; 387 } 388 389 // Scalar floating point is handled by fcsel. 390 // FIXME: Form fabs, fmin, and fmax when applicable. 391 if (AArch64::FPR64RegClass.hasSubClassEq(RC) || 392 AArch64::FPR32RegClass.hasSubClassEq(RC)) { 393 CondCycles = 5 + ExtraCondLat; 394 TrueCycles = FalseCycles = 2; 395 return true; 396 } 397 398 // Can't do vectors. 399 return false; 400 } 401 402 void AArch64InstrInfo::insertSelect(MachineBasicBlock &MBB, 403 MachineBasicBlock::iterator I, DebugLoc DL, 404 unsigned DstReg, 405 ArrayRef<MachineOperand> Cond, 406 unsigned TrueReg, unsigned FalseReg) const { 407 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 408 409 // Parse the condition code, see parseCondBranch() above. 410 AArch64CC::CondCode CC; 411 switch (Cond.size()) { 412 default: 413 llvm_unreachable("Unknown condition opcode in Cond"); 414 case 1: // b.cc 415 CC = AArch64CC::CondCode(Cond[0].getImm()); 416 break; 417 case 3: { // cbz/cbnz 418 // We must insert a compare against 0. 419 bool Is64Bit; 420 switch (Cond[1].getImm()) { 421 default: 422 llvm_unreachable("Unknown branch opcode in Cond"); 423 case AArch64::CBZW: 424 Is64Bit = 0; 425 CC = AArch64CC::EQ; 426 break; 427 case AArch64::CBZX: 428 Is64Bit = 1; 429 CC = AArch64CC::EQ; 430 break; 431 case AArch64::CBNZW: 432 Is64Bit = 0; 433 CC = AArch64CC::NE; 434 break; 435 case AArch64::CBNZX: 436 Is64Bit = 1; 437 CC = AArch64CC::NE; 438 break; 439 } 440 unsigned SrcReg = Cond[2].getReg(); 441 if (Is64Bit) { 442 // cmp reg, #0 is actually subs xzr, reg, #0. 443 MRI.constrainRegClass(SrcReg, &AArch64::GPR64spRegClass); 444 BuildMI(MBB, I, DL, get(AArch64::SUBSXri), AArch64::XZR) 445 .addReg(SrcReg) 446 .addImm(0) 447 .addImm(0); 448 } else { 449 MRI.constrainRegClass(SrcReg, &AArch64::GPR32spRegClass); 450 BuildMI(MBB, I, DL, get(AArch64::SUBSWri), AArch64::WZR) 451 .addReg(SrcReg) 452 .addImm(0) 453 .addImm(0); 454 } 455 break; 456 } 457 case 4: { // tbz/tbnz 458 // We must insert a tst instruction. 459 switch (Cond[1].getImm()) { 460 default: 461 llvm_unreachable("Unknown branch opcode in Cond"); 462 case AArch64::TBZW: 463 case AArch64::TBZX: 464 CC = AArch64CC::EQ; 465 break; 466 case AArch64::TBNZW: 467 case AArch64::TBNZX: 468 CC = AArch64CC::NE; 469 break; 470 } 471 // cmp reg, #foo is actually ands xzr, reg, #1<<foo. 472 if (Cond[1].getImm() == AArch64::TBZW || Cond[1].getImm() == AArch64::TBNZW) 473 BuildMI(MBB, I, DL, get(AArch64::ANDSWri), AArch64::WZR) 474 .addReg(Cond[2].getReg()) 475 .addImm( 476 AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 32)); 477 else 478 BuildMI(MBB, I, DL, get(AArch64::ANDSXri), AArch64::XZR) 479 .addReg(Cond[2].getReg()) 480 .addImm( 481 AArch64_AM::encodeLogicalImmediate(1ull << Cond[3].getImm(), 64)); 482 break; 483 } 484 } 485 486 unsigned Opc = 0; 487 const TargetRegisterClass *RC = nullptr; 488 bool TryFold = false; 489 if (MRI.constrainRegClass(DstReg, &AArch64::GPR64RegClass)) { 490 RC = &AArch64::GPR64RegClass; 491 Opc = AArch64::CSELXr; 492 TryFold = true; 493 } else if (MRI.constrainRegClass(DstReg, &AArch64::GPR32RegClass)) { 494 RC = &AArch64::GPR32RegClass; 495 Opc = AArch64::CSELWr; 496 TryFold = true; 497 } else if (MRI.constrainRegClass(DstReg, &AArch64::FPR64RegClass)) { 498 RC = &AArch64::FPR64RegClass; 499 Opc = AArch64::FCSELDrrr; 500 } else if (MRI.constrainRegClass(DstReg, &AArch64::FPR32RegClass)) { 501 RC = &AArch64::FPR32RegClass; 502 Opc = AArch64::FCSELSrrr; 503 } 504 assert(RC && "Unsupported regclass"); 505 506 // Try folding simple instructions into the csel. 507 if (TryFold) { 508 unsigned NewVReg = 0; 509 unsigned FoldedOpc = canFoldIntoCSel(MRI, TrueReg, &NewVReg); 510 if (FoldedOpc) { 511 // The folded opcodes csinc, csinc and csneg apply the operation to 512 // FalseReg, so we need to invert the condition. 513 CC = AArch64CC::getInvertedCondCode(CC); 514 TrueReg = FalseReg; 515 } else 516 FoldedOpc = canFoldIntoCSel(MRI, FalseReg, &NewVReg); 517 518 // Fold the operation. Leave any dead instructions for DCE to clean up. 519 if (FoldedOpc) { 520 FalseReg = NewVReg; 521 Opc = FoldedOpc; 522 // The extends the live range of NewVReg. 523 MRI.clearKillFlags(NewVReg); 524 } 525 } 526 527 // Pull all virtual register into the appropriate class. 528 MRI.constrainRegClass(TrueReg, RC); 529 MRI.constrainRegClass(FalseReg, RC); 530 531 // Insert the csel. 532 BuildMI(MBB, I, DL, get(Opc), DstReg).addReg(TrueReg).addReg(FalseReg).addImm( 533 CC); 534 } 535 536 /// Returns true if a MOVi32imm or MOVi64imm can be expanded to an ORRxx. 537 static bool canBeExpandedToORR(const MachineInstr *MI, unsigned BitSize) { 538 uint64_t Imm = MI->getOperand(1).getImm(); 539 uint64_t UImm = Imm << (64 - BitSize) >> (64 - BitSize); 540 uint64_t Encoding; 541 return AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding); 542 } 543 544 // FIXME: this implementation should be micro-architecture dependent, so a 545 // micro-architecture target hook should be introduced here in future. 546 bool AArch64InstrInfo::isAsCheapAsAMove(const MachineInstr *MI) const { 547 if (!Subtarget.isCortexA57() && !Subtarget.isCortexA53() && 548 !Subtarget.isExynosM1() && !Subtarget.isKryo()) 549 return MI->isAsCheapAsAMove(); 550 551 unsigned Imm; 552 553 switch (MI->getOpcode()) { 554 default: 555 return false; 556 557 // add/sub on register without shift 558 case AArch64::ADDWri: 559 case AArch64::ADDXri: 560 case AArch64::SUBWri: 561 case AArch64::SUBXri: 562 return (Subtarget.isExynosM1() || 563 MI->getOperand(3).getImm() == 0); 564 565 // add/sub on register with shift 566 case AArch64::ADDWrs: 567 case AArch64::ADDXrs: 568 case AArch64::SUBWrs: 569 case AArch64::SUBXrs: 570 Imm = MI->getOperand(3).getImm(); 571 return (Subtarget.isExynosM1() && 572 AArch64_AM::getArithShiftValue(Imm) < 4); 573 574 // logical ops on immediate 575 case AArch64::ANDWri: 576 case AArch64::ANDXri: 577 case AArch64::EORWri: 578 case AArch64::EORXri: 579 case AArch64::ORRWri: 580 case AArch64::ORRXri: 581 return true; 582 583 // logical ops on register without shift 584 case AArch64::ANDWrr: 585 case AArch64::ANDXrr: 586 case AArch64::BICWrr: 587 case AArch64::BICXrr: 588 case AArch64::EONWrr: 589 case AArch64::EONXrr: 590 case AArch64::EORWrr: 591 case AArch64::EORXrr: 592 case AArch64::ORNWrr: 593 case AArch64::ORNXrr: 594 case AArch64::ORRWrr: 595 case AArch64::ORRXrr: 596 return true; 597 598 // logical ops on register with shift 599 case AArch64::ANDWrs: 600 case AArch64::ANDXrs: 601 case AArch64::BICWrs: 602 case AArch64::BICXrs: 603 case AArch64::EONWrs: 604 case AArch64::EONXrs: 605 case AArch64::EORWrs: 606 case AArch64::EORXrs: 607 case AArch64::ORNWrs: 608 case AArch64::ORNXrs: 609 case AArch64::ORRWrs: 610 case AArch64::ORRXrs: 611 Imm = MI->getOperand(3).getImm(); 612 return (Subtarget.isExynosM1() && 613 AArch64_AM::getShiftValue(Imm) < 4 && 614 AArch64_AM::getShiftType(Imm) == AArch64_AM::LSL); 615 616 // If MOVi32imm or MOVi64imm can be expanded into ORRWri or 617 // ORRXri, it is as cheap as MOV 618 case AArch64::MOVi32imm: 619 return canBeExpandedToORR(MI, 32); 620 case AArch64::MOVi64imm: 621 return canBeExpandedToORR(MI, 64); 622 } 623 624 llvm_unreachable("Unknown opcode to check as cheap as a move!"); 625 } 626 627 bool AArch64InstrInfo::isCoalescableExtInstr(const MachineInstr &MI, 628 unsigned &SrcReg, unsigned &DstReg, 629 unsigned &SubIdx) const { 630 switch (MI.getOpcode()) { 631 default: 632 return false; 633 case AArch64::SBFMXri: // aka sxtw 634 case AArch64::UBFMXri: // aka uxtw 635 // Check for the 32 -> 64 bit extension case, these instructions can do 636 // much more. 637 if (MI.getOperand(2).getImm() != 0 || MI.getOperand(3).getImm() != 31) 638 return false; 639 // This is a signed or unsigned 32 -> 64 bit extension. 640 SrcReg = MI.getOperand(1).getReg(); 641 DstReg = MI.getOperand(0).getReg(); 642 SubIdx = AArch64::sub_32; 643 return true; 644 } 645 } 646 647 bool 648 AArch64InstrInfo::areMemAccessesTriviallyDisjoint(MachineInstr *MIa, 649 MachineInstr *MIb, 650 AliasAnalysis *AA) const { 651 const TargetRegisterInfo *TRI = &getRegisterInfo(); 652 unsigned BaseRegA = 0, BaseRegB = 0; 653 int64_t OffsetA = 0, OffsetB = 0; 654 unsigned WidthA = 0, WidthB = 0; 655 656 assert(MIa && MIa->mayLoadOrStore() && "MIa must be a load or store."); 657 assert(MIb && MIb->mayLoadOrStore() && "MIb must be a load or store."); 658 659 if (MIa->hasUnmodeledSideEffects() || MIb->hasUnmodeledSideEffects() || 660 MIa->hasOrderedMemoryRef() || MIb->hasOrderedMemoryRef()) 661 return false; 662 663 // Retrieve the base register, offset from the base register and width. Width 664 // is the size of memory that is being loaded/stored (e.g. 1, 2, 4, 8). If 665 // base registers are identical, and the offset of a lower memory access + 666 // the width doesn't overlap the offset of a higher memory access, 667 // then the memory accesses are different. 668 if (getMemOpBaseRegImmOfsWidth(MIa, BaseRegA, OffsetA, WidthA, TRI) && 669 getMemOpBaseRegImmOfsWidth(MIb, BaseRegB, OffsetB, WidthB, TRI)) { 670 if (BaseRegA == BaseRegB) { 671 int LowOffset = OffsetA < OffsetB ? OffsetA : OffsetB; 672 int HighOffset = OffsetA < OffsetB ? OffsetB : OffsetA; 673 int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB; 674 if (LowOffset + LowWidth <= HighOffset) 675 return true; 676 } 677 } 678 return false; 679 } 680 681 /// analyzeCompare - For a comparison instruction, return the source registers 682 /// in SrcReg and SrcReg2, and the value it compares against in CmpValue. 683 /// Return true if the comparison instruction can be analyzed. 684 bool AArch64InstrInfo::analyzeCompare(const MachineInstr *MI, unsigned &SrcReg, 685 unsigned &SrcReg2, int &CmpMask, 686 int &CmpValue) const { 687 switch (MI->getOpcode()) { 688 default: 689 break; 690 case AArch64::SUBSWrr: 691 case AArch64::SUBSWrs: 692 case AArch64::SUBSWrx: 693 case AArch64::SUBSXrr: 694 case AArch64::SUBSXrs: 695 case AArch64::SUBSXrx: 696 case AArch64::ADDSWrr: 697 case AArch64::ADDSWrs: 698 case AArch64::ADDSWrx: 699 case AArch64::ADDSXrr: 700 case AArch64::ADDSXrs: 701 case AArch64::ADDSXrx: 702 // Replace SUBSWrr with SUBWrr if NZCV is not used. 703 SrcReg = MI->getOperand(1).getReg(); 704 SrcReg2 = MI->getOperand(2).getReg(); 705 CmpMask = ~0; 706 CmpValue = 0; 707 return true; 708 case AArch64::SUBSWri: 709 case AArch64::ADDSWri: 710 case AArch64::SUBSXri: 711 case AArch64::ADDSXri: 712 SrcReg = MI->getOperand(1).getReg(); 713 SrcReg2 = 0; 714 CmpMask = ~0; 715 // FIXME: In order to convert CmpValue to 0 or 1 716 CmpValue = (MI->getOperand(2).getImm() != 0); 717 return true; 718 case AArch64::ANDSWri: 719 case AArch64::ANDSXri: 720 // ANDS does not use the same encoding scheme as the others xxxS 721 // instructions. 722 SrcReg = MI->getOperand(1).getReg(); 723 SrcReg2 = 0; 724 CmpMask = ~0; 725 // FIXME:The return val type of decodeLogicalImmediate is uint64_t, 726 // while the type of CmpValue is int. When converting uint64_t to int, 727 // the high 32 bits of uint64_t will be lost. 728 // In fact it causes a bug in spec2006-483.xalancbmk 729 // CmpValue is only used to compare with zero in OptimizeCompareInstr 730 CmpValue = (AArch64_AM::decodeLogicalImmediate( 731 MI->getOperand(2).getImm(), 732 MI->getOpcode() == AArch64::ANDSWri ? 32 : 64) != 0); 733 return true; 734 } 735 736 return false; 737 } 738 739 static bool UpdateOperandRegClass(MachineInstr *Instr) { 740 MachineBasicBlock *MBB = Instr->getParent(); 741 assert(MBB && "Can't get MachineBasicBlock here"); 742 MachineFunction *MF = MBB->getParent(); 743 assert(MF && "Can't get MachineFunction here"); 744 const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo(); 745 const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo(); 746 MachineRegisterInfo *MRI = &MF->getRegInfo(); 747 748 for (unsigned OpIdx = 0, EndIdx = Instr->getNumOperands(); OpIdx < EndIdx; 749 ++OpIdx) { 750 MachineOperand &MO = Instr->getOperand(OpIdx); 751 const TargetRegisterClass *OpRegCstraints = 752 Instr->getRegClassConstraint(OpIdx, TII, TRI); 753 754 // If there's no constraint, there's nothing to do. 755 if (!OpRegCstraints) 756 continue; 757 // If the operand is a frame index, there's nothing to do here. 758 // A frame index operand will resolve correctly during PEI. 759 if (MO.isFI()) 760 continue; 761 762 assert(MO.isReg() && 763 "Operand has register constraints without being a register!"); 764 765 unsigned Reg = MO.getReg(); 766 if (TargetRegisterInfo::isPhysicalRegister(Reg)) { 767 if (!OpRegCstraints->contains(Reg)) 768 return false; 769 } else if (!OpRegCstraints->hasSubClassEq(MRI->getRegClass(Reg)) && 770 !MRI->constrainRegClass(Reg, OpRegCstraints)) 771 return false; 772 } 773 774 return true; 775 } 776 777 /// \brief Return the opcode that does not set flags when possible - otherwise 778 /// return the original opcode. The caller is responsible to do the actual 779 /// substitution and legality checking. 780 static unsigned convertFlagSettingOpcode(const MachineInstr *MI) { 781 // Don't convert all compare instructions, because for some the zero register 782 // encoding becomes the sp register. 783 bool MIDefinesZeroReg = false; 784 if (MI->definesRegister(AArch64::WZR) || MI->definesRegister(AArch64::XZR)) 785 MIDefinesZeroReg = true; 786 787 switch (MI->getOpcode()) { 788 default: 789 return MI->getOpcode(); 790 case AArch64::ADDSWrr: 791 return AArch64::ADDWrr; 792 case AArch64::ADDSWri: 793 return MIDefinesZeroReg ? AArch64::ADDSWri : AArch64::ADDWri; 794 case AArch64::ADDSWrs: 795 return MIDefinesZeroReg ? AArch64::ADDSWrs : AArch64::ADDWrs; 796 case AArch64::ADDSWrx: 797 return AArch64::ADDWrx; 798 case AArch64::ADDSXrr: 799 return AArch64::ADDXrr; 800 case AArch64::ADDSXri: 801 return MIDefinesZeroReg ? AArch64::ADDSXri : AArch64::ADDXri; 802 case AArch64::ADDSXrs: 803 return MIDefinesZeroReg ? AArch64::ADDSXrs : AArch64::ADDXrs; 804 case AArch64::ADDSXrx: 805 return AArch64::ADDXrx; 806 case AArch64::SUBSWrr: 807 return AArch64::SUBWrr; 808 case AArch64::SUBSWri: 809 return MIDefinesZeroReg ? AArch64::SUBSWri : AArch64::SUBWri; 810 case AArch64::SUBSWrs: 811 return MIDefinesZeroReg ? AArch64::SUBSWrs : AArch64::SUBWrs; 812 case AArch64::SUBSWrx: 813 return AArch64::SUBWrx; 814 case AArch64::SUBSXrr: 815 return AArch64::SUBXrr; 816 case AArch64::SUBSXri: 817 return MIDefinesZeroReg ? AArch64::SUBSXri : AArch64::SUBXri; 818 case AArch64::SUBSXrs: 819 return MIDefinesZeroReg ? AArch64::SUBSXrs : AArch64::SUBXrs; 820 case AArch64::SUBSXrx: 821 return AArch64::SUBXrx; 822 } 823 } 824 825 enum AccessKind { 826 AK_Write = 0x01, 827 AK_Read = 0x10, 828 AK_All = 0x11 829 }; 830 831 /// True when condition flags are accessed (either by writing or reading) 832 /// on the instruction trace starting at From and ending at To. 833 /// 834 /// Note: If From and To are from different blocks it's assumed CC are accessed 835 /// on the path. 836 static bool areCFlagsAccessedBetweenInstrs(MachineInstr *From, MachineInstr *To, 837 const TargetRegisterInfo *TRI, 838 const AccessKind AccessToCheck = AK_All) { 839 // We iterate backward starting \p To until we hit \p From 840 MachineBasicBlock::iterator I = To, E = From, B = To->getParent()->begin(); 841 842 // Early exit if To is at the beginning of the BB. 843 if (I == B) 844 return true; 845 846 // Check whether the instructions are in the same basic block 847 // If not, assume the condition flags might get modified somewhere. 848 if (To->getParent() != From->getParent()) 849 return true; 850 851 // From must be above To. 852 assert(std::find_if(MachineBasicBlock::reverse_iterator(To), 853 To->getParent()->rend(), 854 [From](MachineInstr &MI) { 855 return &MI == From; 856 }) != To->getParent()->rend()); 857 858 for (--I; I != E; --I) { 859 const MachineInstr &Instr = *I; 860 861 if ( ((AccessToCheck & AK_Write) && Instr.modifiesRegister(AArch64::NZCV, TRI)) || 862 ((AccessToCheck & AK_Read) && Instr.readsRegister(AArch64::NZCV, TRI))) 863 return true; 864 } 865 return false; 866 } 867 868 /// Try to optimize a compare instruction. A compare instruction is an 869 /// instruction which produces AArch64::NZCV. It can be truly compare instruction 870 /// when there are no uses of its destination register. 871 /// 872 /// The following steps are tried in order: 873 /// 1. Convert CmpInstr into an unconditional version. 874 /// 2. Remove CmpInstr if above there is an instruction producing a needed 875 /// condition code or an instruction which can be converted into such an instruction. 876 /// Only comparison with zero is supported. 877 bool AArch64InstrInfo::optimizeCompareInstr( 878 MachineInstr *CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask, 879 int CmpValue, const MachineRegisterInfo *MRI) const { 880 assert(CmpInstr); 881 assert(CmpInstr->getParent()); 882 assert(MRI); 883 884 // Replace SUBSWrr with SUBWrr if NZCV is not used. 885 int DeadNZCVIdx = CmpInstr->findRegisterDefOperandIdx(AArch64::NZCV, true); 886 if (DeadNZCVIdx != -1) { 887 if (CmpInstr->definesRegister(AArch64::WZR) || 888 CmpInstr->definesRegister(AArch64::XZR)) { 889 CmpInstr->eraseFromParent(); 890 return true; 891 } 892 unsigned Opc = CmpInstr->getOpcode(); 893 unsigned NewOpc = convertFlagSettingOpcode(CmpInstr); 894 if (NewOpc == Opc) 895 return false; 896 const MCInstrDesc &MCID = get(NewOpc); 897 CmpInstr->setDesc(MCID); 898 CmpInstr->RemoveOperand(DeadNZCVIdx); 899 bool succeeded = UpdateOperandRegClass(CmpInstr); 900 (void)succeeded; 901 assert(succeeded && "Some operands reg class are incompatible!"); 902 return true; 903 } 904 905 // Continue only if we have a "ri" where immediate is zero. 906 // FIXME:CmpValue has already been converted to 0 or 1 in analyzeCompare 907 // function. 908 assert((CmpValue == 0 || CmpValue == 1) && "CmpValue must be 0 or 1!"); 909 if (CmpValue != 0 || SrcReg2 != 0) 910 return false; 911 912 // CmpInstr is a Compare instruction if destination register is not used. 913 if (!MRI->use_nodbg_empty(CmpInstr->getOperand(0).getReg())) 914 return false; 915 916 return substituteCmpToZero(CmpInstr, SrcReg, MRI); 917 } 918 919 /// Get opcode of S version of Instr. 920 /// If Instr is S version its opcode is returned. 921 /// AArch64::INSTRUCTION_LIST_END is returned if Instr does not have S version 922 /// or we are not interested in it. 923 static unsigned sForm(MachineInstr &Instr) { 924 switch (Instr.getOpcode()) { 925 default: 926 return AArch64::INSTRUCTION_LIST_END; 927 928 case AArch64::ADDSWrr: 929 case AArch64::ADDSWri: 930 case AArch64::ADDSXrr: 931 case AArch64::ADDSXri: 932 case AArch64::SUBSWrr: 933 case AArch64::SUBSWri: 934 case AArch64::SUBSXrr: 935 case AArch64::SUBSXri: 936 return Instr.getOpcode();; 937 938 case AArch64::ADDWrr: return AArch64::ADDSWrr; 939 case AArch64::ADDWri: return AArch64::ADDSWri; 940 case AArch64::ADDXrr: return AArch64::ADDSXrr; 941 case AArch64::ADDXri: return AArch64::ADDSXri; 942 case AArch64::ADCWr: return AArch64::ADCSWr; 943 case AArch64::ADCXr: return AArch64::ADCSXr; 944 case AArch64::SUBWrr: return AArch64::SUBSWrr; 945 case AArch64::SUBWri: return AArch64::SUBSWri; 946 case AArch64::SUBXrr: return AArch64::SUBSXrr; 947 case AArch64::SUBXri: return AArch64::SUBSXri; 948 case AArch64::SBCWr: return AArch64::SBCSWr; 949 case AArch64::SBCXr: return AArch64::SBCSXr; 950 case AArch64::ANDWri: return AArch64::ANDSWri; 951 case AArch64::ANDXri: return AArch64::ANDSXri; 952 } 953 } 954 955 /// Check if AArch64::NZCV should be alive in successors of MBB. 956 static bool areCFlagsAliveInSuccessors(MachineBasicBlock *MBB) { 957 for (auto *BB : MBB->successors()) 958 if (BB->isLiveIn(AArch64::NZCV)) 959 return true; 960 return false; 961 } 962 963 struct UsedNZCV { 964 bool N; 965 bool Z; 966 bool C; 967 bool V; 968 UsedNZCV(): N(false), Z(false), C(false), V(false) {} 969 UsedNZCV& operator |=(const UsedNZCV& UsedFlags) { 970 this->N |= UsedFlags.N; 971 this->Z |= UsedFlags.Z; 972 this->C |= UsedFlags.C; 973 this->V |= UsedFlags.V; 974 return *this; 975 } 976 }; 977 978 /// Find a condition code used by the instruction. 979 /// Returns AArch64CC::Invalid if either the instruction does not use condition 980 /// codes or we don't optimize CmpInstr in the presence of such instructions. 981 static AArch64CC::CondCode findCondCodeUsedByInstr(const MachineInstr &Instr) { 982 switch (Instr.getOpcode()) { 983 default: 984 return AArch64CC::Invalid; 985 986 case AArch64::Bcc: { 987 int Idx = Instr.findRegisterUseOperandIdx(AArch64::NZCV); 988 assert(Idx >= 2); 989 return static_cast<AArch64CC::CondCode>(Instr.getOperand(Idx - 2).getImm()); 990 } 991 992 case AArch64::CSINVWr: 993 case AArch64::CSINVXr: 994 case AArch64::CSINCWr: 995 case AArch64::CSINCXr: 996 case AArch64::CSELWr: 997 case AArch64::CSELXr: 998 case AArch64::CSNEGWr: 999 case AArch64::CSNEGXr: 1000 case AArch64::FCSELSrrr: 1001 case AArch64::FCSELDrrr: { 1002 int Idx = Instr.findRegisterUseOperandIdx(AArch64::NZCV); 1003 assert(Idx >= 1); 1004 return static_cast<AArch64CC::CondCode>(Instr.getOperand(Idx - 1).getImm()); 1005 } 1006 } 1007 } 1008 1009 static UsedNZCV getUsedNZCV(AArch64CC::CondCode CC) { 1010 assert(CC != AArch64CC::Invalid); 1011 UsedNZCV UsedFlags; 1012 switch (CC) { 1013 default: 1014 break; 1015 1016 case AArch64CC::EQ: // Z set 1017 case AArch64CC::NE: // Z clear 1018 UsedFlags.Z = true; 1019 break; 1020 1021 case AArch64CC::HI: // Z clear and C set 1022 case AArch64CC::LS: // Z set or C clear 1023 UsedFlags.Z = true; 1024 case AArch64CC::HS: // C set 1025 case AArch64CC::LO: // C clear 1026 UsedFlags.C = true; 1027 break; 1028 1029 case AArch64CC::MI: // N set 1030 case AArch64CC::PL: // N clear 1031 UsedFlags.N = true; 1032 break; 1033 1034 case AArch64CC::VS: // V set 1035 case AArch64CC::VC: // V clear 1036 UsedFlags.V = true; 1037 break; 1038 1039 case AArch64CC::GT: // Z clear, N and V the same 1040 case AArch64CC::LE: // Z set, N and V differ 1041 UsedFlags.Z = true; 1042 case AArch64CC::GE: // N and V the same 1043 case AArch64CC::LT: // N and V differ 1044 UsedFlags.N = true; 1045 UsedFlags.V = true; 1046 break; 1047 } 1048 return UsedFlags; 1049 } 1050 1051 static bool isADDSRegImm(unsigned Opcode) { 1052 return Opcode == AArch64::ADDSWri || Opcode == AArch64::ADDSXri; 1053 } 1054 1055 static bool isSUBSRegImm(unsigned Opcode) { 1056 return Opcode == AArch64::SUBSWri || Opcode == AArch64::SUBSXri; 1057 } 1058 1059 /// Check if CmpInstr can be substituted by MI. 1060 /// 1061 /// CmpInstr can be substituted: 1062 /// - CmpInstr is either 'ADDS %vreg, 0' or 'SUBS %vreg, 0' 1063 /// - and, MI and CmpInstr are from the same MachineBB 1064 /// - and, condition flags are not alive in successors of the CmpInstr parent 1065 /// - and, if MI opcode is the S form there must be no defs of flags between 1066 /// MI and CmpInstr 1067 /// or if MI opcode is not the S form there must be neither defs of flags 1068 /// nor uses of flags between MI and CmpInstr. 1069 /// - and C/V flags are not used after CmpInstr 1070 static bool canInstrSubstituteCmpInstr(MachineInstr *MI, MachineInstr *CmpInstr, 1071 const TargetRegisterInfo *TRI) { 1072 assert(MI); 1073 assert(sForm(*MI) != AArch64::INSTRUCTION_LIST_END); 1074 assert(CmpInstr); 1075 1076 const unsigned CmpOpcode = CmpInstr->getOpcode(); 1077 if (!isADDSRegImm(CmpOpcode) && !isSUBSRegImm(CmpOpcode)) 1078 return false; 1079 1080 if (MI->getParent() != CmpInstr->getParent()) 1081 return false; 1082 1083 if (areCFlagsAliveInSuccessors(CmpInstr->getParent())) 1084 return false; 1085 1086 AccessKind AccessToCheck = AK_Write; 1087 if (sForm(*MI) != MI->getOpcode()) 1088 AccessToCheck = AK_All; 1089 if (areCFlagsAccessedBetweenInstrs(MI, CmpInstr, TRI, AccessToCheck)) 1090 return false; 1091 1092 UsedNZCV NZCVUsedAfterCmp; 1093 for (auto I = std::next(CmpInstr->getIterator()), E = CmpInstr->getParent()->instr_end(); 1094 I != E; ++I) { 1095 const MachineInstr &Instr = *I; 1096 if (Instr.readsRegister(AArch64::NZCV, TRI)) { 1097 AArch64CC::CondCode CC = findCondCodeUsedByInstr(Instr); 1098 if (CC == AArch64CC::Invalid) // Unsupported conditional instruction 1099 return false; 1100 NZCVUsedAfterCmp |= getUsedNZCV(CC); 1101 } 1102 1103 if (Instr.modifiesRegister(AArch64::NZCV, TRI)) 1104 break; 1105 } 1106 1107 return !NZCVUsedAfterCmp.C && !NZCVUsedAfterCmp.V; 1108 } 1109 1110 /// Substitute an instruction comparing to zero with another instruction 1111 /// which produces needed condition flags. 1112 /// 1113 /// Return true on success. 1114 bool AArch64InstrInfo::substituteCmpToZero(MachineInstr *CmpInstr, 1115 unsigned SrcReg, const MachineRegisterInfo *MRI) const { 1116 assert(CmpInstr); 1117 assert(MRI); 1118 // Get the unique definition of SrcReg. 1119 MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg); 1120 if (!MI) 1121 return false; 1122 1123 const TargetRegisterInfo *TRI = &getRegisterInfo(); 1124 1125 unsigned NewOpc = sForm(*MI); 1126 if (NewOpc == AArch64::INSTRUCTION_LIST_END) 1127 return false; 1128 1129 if (!canInstrSubstituteCmpInstr(MI, CmpInstr, TRI)) 1130 return false; 1131 1132 // Update the instruction to set NZCV. 1133 MI->setDesc(get(NewOpc)); 1134 CmpInstr->eraseFromParent(); 1135 bool succeeded = UpdateOperandRegClass(MI); 1136 (void)succeeded; 1137 assert(succeeded && "Some operands reg class are incompatible!"); 1138 MI->addRegisterDefined(AArch64::NZCV, TRI); 1139 return true; 1140 } 1141 1142 bool 1143 AArch64InstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const { 1144 if (MI->getOpcode() != TargetOpcode::LOAD_STACK_GUARD) 1145 return false; 1146 1147 MachineBasicBlock &MBB = *MI->getParent(); 1148 DebugLoc DL = MI->getDebugLoc(); 1149 unsigned Reg = MI->getOperand(0).getReg(); 1150 const GlobalValue *GV = 1151 cast<GlobalValue>((*MI->memoperands_begin())->getValue()); 1152 const TargetMachine &TM = MBB.getParent()->getTarget(); 1153 unsigned char OpFlags = Subtarget.ClassifyGlobalReference(GV, TM); 1154 const unsigned char MO_NC = AArch64II::MO_NC; 1155 1156 if ((OpFlags & AArch64II::MO_GOT) != 0) { 1157 BuildMI(MBB, MI, DL, get(AArch64::LOADgot), Reg) 1158 .addGlobalAddress(GV, 0, AArch64II::MO_GOT); 1159 BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg) 1160 .addReg(Reg, RegState::Kill).addImm(0) 1161 .addMemOperand(*MI->memoperands_begin()); 1162 } else if (TM.getCodeModel() == CodeModel::Large) { 1163 BuildMI(MBB, MI, DL, get(AArch64::MOVZXi), Reg) 1164 .addGlobalAddress(GV, 0, AArch64II::MO_G3).addImm(48); 1165 BuildMI(MBB, MI, DL, get(AArch64::MOVKXi), Reg) 1166 .addReg(Reg, RegState::Kill) 1167 .addGlobalAddress(GV, 0, AArch64II::MO_G2 | MO_NC).addImm(32); 1168 BuildMI(MBB, MI, DL, get(AArch64::MOVKXi), Reg) 1169 .addReg(Reg, RegState::Kill) 1170 .addGlobalAddress(GV, 0, AArch64II::MO_G1 | MO_NC).addImm(16); 1171 BuildMI(MBB, MI, DL, get(AArch64::MOVKXi), Reg) 1172 .addReg(Reg, RegState::Kill) 1173 .addGlobalAddress(GV, 0, AArch64II::MO_G0 | MO_NC).addImm(0); 1174 BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg) 1175 .addReg(Reg, RegState::Kill).addImm(0) 1176 .addMemOperand(*MI->memoperands_begin()); 1177 } else { 1178 BuildMI(MBB, MI, DL, get(AArch64::ADRP), Reg) 1179 .addGlobalAddress(GV, 0, OpFlags | AArch64II::MO_PAGE); 1180 unsigned char LoFlags = OpFlags | AArch64II::MO_PAGEOFF | MO_NC; 1181 BuildMI(MBB, MI, DL, get(AArch64::LDRXui), Reg) 1182 .addReg(Reg, RegState::Kill) 1183 .addGlobalAddress(GV, 0, LoFlags) 1184 .addMemOperand(*MI->memoperands_begin()); 1185 } 1186 1187 MBB.erase(MI); 1188 1189 return true; 1190 } 1191 1192 /// Return true if this is this instruction has a non-zero immediate 1193 bool AArch64InstrInfo::hasShiftedReg(const MachineInstr *MI) const { 1194 switch (MI->getOpcode()) { 1195 default: 1196 break; 1197 case AArch64::ADDSWrs: 1198 case AArch64::ADDSXrs: 1199 case AArch64::ADDWrs: 1200 case AArch64::ADDXrs: 1201 case AArch64::ANDSWrs: 1202 case AArch64::ANDSXrs: 1203 case AArch64::ANDWrs: 1204 case AArch64::ANDXrs: 1205 case AArch64::BICSWrs: 1206 case AArch64::BICSXrs: 1207 case AArch64::BICWrs: 1208 case AArch64::BICXrs: 1209 case AArch64::CRC32Brr: 1210 case AArch64::CRC32CBrr: 1211 case AArch64::CRC32CHrr: 1212 case AArch64::CRC32CWrr: 1213 case AArch64::CRC32CXrr: 1214 case AArch64::CRC32Hrr: 1215 case AArch64::CRC32Wrr: 1216 case AArch64::CRC32Xrr: 1217 case AArch64::EONWrs: 1218 case AArch64::EONXrs: 1219 case AArch64::EORWrs: 1220 case AArch64::EORXrs: 1221 case AArch64::ORNWrs: 1222 case AArch64::ORNXrs: 1223 case AArch64::ORRWrs: 1224 case AArch64::ORRXrs: 1225 case AArch64::SUBSWrs: 1226 case AArch64::SUBSXrs: 1227 case AArch64::SUBWrs: 1228 case AArch64::SUBXrs: 1229 if (MI->getOperand(3).isImm()) { 1230 unsigned val = MI->getOperand(3).getImm(); 1231 return (val != 0); 1232 } 1233 break; 1234 } 1235 return false; 1236 } 1237 1238 /// Return true if this is this instruction has a non-zero immediate 1239 bool AArch64InstrInfo::hasExtendedReg(const MachineInstr *MI) const { 1240 switch (MI->getOpcode()) { 1241 default: 1242 break; 1243 case AArch64::ADDSWrx: 1244 case AArch64::ADDSXrx: 1245 case AArch64::ADDSXrx64: 1246 case AArch64::ADDWrx: 1247 case AArch64::ADDXrx: 1248 case AArch64::ADDXrx64: 1249 case AArch64::SUBSWrx: 1250 case AArch64::SUBSXrx: 1251 case AArch64::SUBSXrx64: 1252 case AArch64::SUBWrx: 1253 case AArch64::SUBXrx: 1254 case AArch64::SUBXrx64: 1255 if (MI->getOperand(3).isImm()) { 1256 unsigned val = MI->getOperand(3).getImm(); 1257 return (val != 0); 1258 } 1259 break; 1260 } 1261 1262 return false; 1263 } 1264 1265 // Return true if this instruction simply sets its single destination register 1266 // to zero. This is equivalent to a register rename of the zero-register. 1267 bool AArch64InstrInfo::isGPRZero(const MachineInstr *MI) const { 1268 switch (MI->getOpcode()) { 1269 default: 1270 break; 1271 case AArch64::MOVZWi: 1272 case AArch64::MOVZXi: // movz Rd, #0 (LSL #0) 1273 if (MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0) { 1274 assert(MI->getDesc().getNumOperands() == 3 && 1275 MI->getOperand(2).getImm() == 0 && "invalid MOVZi operands"); 1276 return true; 1277 } 1278 break; 1279 case AArch64::ANDWri: // and Rd, Rzr, #imm 1280 return MI->getOperand(1).getReg() == AArch64::WZR; 1281 case AArch64::ANDXri: 1282 return MI->getOperand(1).getReg() == AArch64::XZR; 1283 case TargetOpcode::COPY: 1284 return MI->getOperand(1).getReg() == AArch64::WZR; 1285 } 1286 return false; 1287 } 1288 1289 // Return true if this instruction simply renames a general register without 1290 // modifying bits. 1291 bool AArch64InstrInfo::isGPRCopy(const MachineInstr *MI) const { 1292 switch (MI->getOpcode()) { 1293 default: 1294 break; 1295 case TargetOpcode::COPY: { 1296 // GPR32 copies will by lowered to ORRXrs 1297 unsigned DstReg = MI->getOperand(0).getReg(); 1298 return (AArch64::GPR32RegClass.contains(DstReg) || 1299 AArch64::GPR64RegClass.contains(DstReg)); 1300 } 1301 case AArch64::ORRXrs: // orr Xd, Xzr, Xm (LSL #0) 1302 if (MI->getOperand(1).getReg() == AArch64::XZR) { 1303 assert(MI->getDesc().getNumOperands() == 4 && 1304 MI->getOperand(3).getImm() == 0 && "invalid ORRrs operands"); 1305 return true; 1306 } 1307 break; 1308 case AArch64::ADDXri: // add Xd, Xn, #0 (LSL #0) 1309 if (MI->getOperand(2).getImm() == 0) { 1310 assert(MI->getDesc().getNumOperands() == 4 && 1311 MI->getOperand(3).getImm() == 0 && "invalid ADDXri operands"); 1312 return true; 1313 } 1314 break; 1315 } 1316 return false; 1317 } 1318 1319 // Return true if this instruction simply renames a general register without 1320 // modifying bits. 1321 bool AArch64InstrInfo::isFPRCopy(const MachineInstr *MI) const { 1322 switch (MI->getOpcode()) { 1323 default: 1324 break; 1325 case TargetOpcode::COPY: { 1326 // FPR64 copies will by lowered to ORR.16b 1327 unsigned DstReg = MI->getOperand(0).getReg(); 1328 return (AArch64::FPR64RegClass.contains(DstReg) || 1329 AArch64::FPR128RegClass.contains(DstReg)); 1330 } 1331 case AArch64::ORRv16i8: 1332 if (MI->getOperand(1).getReg() == MI->getOperand(2).getReg()) { 1333 assert(MI->getDesc().getNumOperands() == 3 && MI->getOperand(0).isReg() && 1334 "invalid ORRv16i8 operands"); 1335 return true; 1336 } 1337 break; 1338 } 1339 return false; 1340 } 1341 1342 unsigned AArch64InstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 1343 int &FrameIndex) const { 1344 switch (MI->getOpcode()) { 1345 default: 1346 break; 1347 case AArch64::LDRWui: 1348 case AArch64::LDRXui: 1349 case AArch64::LDRBui: 1350 case AArch64::LDRHui: 1351 case AArch64::LDRSui: 1352 case AArch64::LDRDui: 1353 case AArch64::LDRQui: 1354 if (MI->getOperand(0).getSubReg() == 0 && MI->getOperand(1).isFI() && 1355 MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) { 1356 FrameIndex = MI->getOperand(1).getIndex(); 1357 return MI->getOperand(0).getReg(); 1358 } 1359 break; 1360 } 1361 1362 return 0; 1363 } 1364 1365 unsigned AArch64InstrInfo::isStoreToStackSlot(const MachineInstr *MI, 1366 int &FrameIndex) const { 1367 switch (MI->getOpcode()) { 1368 default: 1369 break; 1370 case AArch64::STRWui: 1371 case AArch64::STRXui: 1372 case AArch64::STRBui: 1373 case AArch64::STRHui: 1374 case AArch64::STRSui: 1375 case AArch64::STRDui: 1376 case AArch64::STRQui: 1377 if (MI->getOperand(0).getSubReg() == 0 && MI->getOperand(1).isFI() && 1378 MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) { 1379 FrameIndex = MI->getOperand(1).getIndex(); 1380 return MI->getOperand(0).getReg(); 1381 } 1382 break; 1383 } 1384 return 0; 1385 } 1386 1387 /// Return true if this is load/store scales or extends its register offset. 1388 /// This refers to scaling a dynamic index as opposed to scaled immediates. 1389 /// MI should be a memory op that allows scaled addressing. 1390 bool AArch64InstrInfo::isScaledAddr(const MachineInstr *MI) const { 1391 switch (MI->getOpcode()) { 1392 default: 1393 break; 1394 case AArch64::LDRBBroW: 1395 case AArch64::LDRBroW: 1396 case AArch64::LDRDroW: 1397 case AArch64::LDRHHroW: 1398 case AArch64::LDRHroW: 1399 case AArch64::LDRQroW: 1400 case AArch64::LDRSBWroW: 1401 case AArch64::LDRSBXroW: 1402 case AArch64::LDRSHWroW: 1403 case AArch64::LDRSHXroW: 1404 case AArch64::LDRSWroW: 1405 case AArch64::LDRSroW: 1406 case AArch64::LDRWroW: 1407 case AArch64::LDRXroW: 1408 case AArch64::STRBBroW: 1409 case AArch64::STRBroW: 1410 case AArch64::STRDroW: 1411 case AArch64::STRHHroW: 1412 case AArch64::STRHroW: 1413 case AArch64::STRQroW: 1414 case AArch64::STRSroW: 1415 case AArch64::STRWroW: 1416 case AArch64::STRXroW: 1417 case AArch64::LDRBBroX: 1418 case AArch64::LDRBroX: 1419 case AArch64::LDRDroX: 1420 case AArch64::LDRHHroX: 1421 case AArch64::LDRHroX: 1422 case AArch64::LDRQroX: 1423 case AArch64::LDRSBWroX: 1424 case AArch64::LDRSBXroX: 1425 case AArch64::LDRSHWroX: 1426 case AArch64::LDRSHXroX: 1427 case AArch64::LDRSWroX: 1428 case AArch64::LDRSroX: 1429 case AArch64::LDRWroX: 1430 case AArch64::LDRXroX: 1431 case AArch64::STRBBroX: 1432 case AArch64::STRBroX: 1433 case AArch64::STRDroX: 1434 case AArch64::STRHHroX: 1435 case AArch64::STRHroX: 1436 case AArch64::STRQroX: 1437 case AArch64::STRSroX: 1438 case AArch64::STRWroX: 1439 case AArch64::STRXroX: 1440 1441 unsigned Val = MI->getOperand(3).getImm(); 1442 AArch64_AM::ShiftExtendType ExtType = AArch64_AM::getMemExtendType(Val); 1443 return (ExtType != AArch64_AM::UXTX) || AArch64_AM::getMemDoShift(Val); 1444 } 1445 return false; 1446 } 1447 1448 /// Check all MachineMemOperands for a hint to suppress pairing. 1449 bool AArch64InstrInfo::isLdStPairSuppressed(const MachineInstr *MI) const { 1450 static_assert(MOSuppressPair < (1 << MachineMemOperand::MOTargetNumBits), 1451 "Too many target MO flags"); 1452 for (auto *MM : MI->memoperands()) { 1453 if (MM->getFlags() & 1454 (MOSuppressPair << MachineMemOperand::MOTargetStartBit)) { 1455 return true; 1456 } 1457 } 1458 return false; 1459 } 1460 1461 /// Set a flag on the first MachineMemOperand to suppress pairing. 1462 void AArch64InstrInfo::suppressLdStPair(MachineInstr *MI) const { 1463 if (MI->memoperands_empty()) 1464 return; 1465 1466 static_assert(MOSuppressPair < (1 << MachineMemOperand::MOTargetNumBits), 1467 "Too many target MO flags"); 1468 (*MI->memoperands_begin()) 1469 ->setFlags(MOSuppressPair << MachineMemOperand::MOTargetStartBit); 1470 } 1471 1472 bool AArch64InstrInfo::isUnscaledLdSt(unsigned Opc) const { 1473 switch (Opc) { 1474 default: 1475 return false; 1476 case AArch64::STURSi: 1477 case AArch64::STURDi: 1478 case AArch64::STURQi: 1479 case AArch64::STURBBi: 1480 case AArch64::STURHHi: 1481 case AArch64::STURWi: 1482 case AArch64::STURXi: 1483 case AArch64::LDURSi: 1484 case AArch64::LDURDi: 1485 case AArch64::LDURQi: 1486 case AArch64::LDURWi: 1487 case AArch64::LDURXi: 1488 case AArch64::LDURSWi: 1489 case AArch64::LDURHHi: 1490 case AArch64::LDURBBi: 1491 case AArch64::LDURSBWi: 1492 case AArch64::LDURSHWi: 1493 return true; 1494 } 1495 } 1496 1497 bool AArch64InstrInfo::isUnscaledLdSt(MachineInstr *MI) const { 1498 return isUnscaledLdSt(MI->getOpcode()); 1499 } 1500 1501 // Is this a candidate for ld/st merging or pairing? For example, we don't 1502 // touch volatiles or load/stores that have a hint to avoid pair formation. 1503 bool AArch64InstrInfo::isCandidateToMergeOrPair(MachineInstr *MI) const { 1504 // If this is a volatile load/store, don't mess with it. 1505 if (MI->hasOrderedMemoryRef()) 1506 return false; 1507 1508 // Make sure this is a reg+imm (as opposed to an address reloc). 1509 assert(MI->getOperand(1).isReg() && "Expected a reg operand."); 1510 if (!MI->getOperand(2).isImm()) 1511 return false; 1512 1513 // Can't merge/pair if the instruction modifies the base register. 1514 // e.g., ldr x0, [x0] 1515 unsigned BaseReg = MI->getOperand(1).getReg(); 1516 const TargetRegisterInfo *TRI = &getRegisterInfo(); 1517 if (MI->modifiesRegister(BaseReg, TRI)) 1518 return false; 1519 1520 // Check if this load/store has a hint to avoid pair formation. 1521 // MachineMemOperands hints are set by the AArch64StorePairSuppress pass. 1522 if (isLdStPairSuppressed(MI)) 1523 return false; 1524 1525 // Do not pair quad ld/st for Exynos. 1526 if (Subtarget.isExynosM1()) { 1527 switch (MI->getOpcode()) { 1528 default: 1529 break; 1530 1531 case AArch64::LDURQi: 1532 case AArch64::STURQi: 1533 case AArch64::LDRQui: 1534 case AArch64::STRQui: 1535 return false; 1536 } 1537 } 1538 1539 return true; 1540 } 1541 1542 bool AArch64InstrInfo::getMemOpBaseRegImmOfs( 1543 MachineInstr *LdSt, unsigned &BaseReg, int64_t &Offset, 1544 const TargetRegisterInfo *TRI) const { 1545 switch (LdSt->getOpcode()) { 1546 default: 1547 return false; 1548 // Scaled instructions. 1549 case AArch64::STRSui: 1550 case AArch64::STRDui: 1551 case AArch64::STRQui: 1552 case AArch64::STRXui: 1553 case AArch64::STRWui: 1554 case AArch64::LDRSui: 1555 case AArch64::LDRDui: 1556 case AArch64::LDRQui: 1557 case AArch64::LDRXui: 1558 case AArch64::LDRWui: 1559 case AArch64::LDRSWui: 1560 // Unscaled instructions. 1561 case AArch64::STURSi: 1562 case AArch64::STURDi: 1563 case AArch64::STURQi: 1564 case AArch64::STURXi: 1565 case AArch64::STURWi: 1566 case AArch64::LDURSi: 1567 case AArch64::LDURDi: 1568 case AArch64::LDURQi: 1569 case AArch64::LDURWi: 1570 case AArch64::LDURXi: 1571 case AArch64::LDURSWi: 1572 unsigned Width; 1573 return getMemOpBaseRegImmOfsWidth(LdSt, BaseReg, Offset, Width, TRI); 1574 }; 1575 } 1576 1577 bool AArch64InstrInfo::getMemOpBaseRegImmOfsWidth( 1578 MachineInstr *LdSt, unsigned &BaseReg, int64_t &Offset, unsigned &Width, 1579 const TargetRegisterInfo *TRI) const { 1580 assert(LdSt->mayLoadOrStore() && "Expected a memory operation."); 1581 // Handle only loads/stores with base register followed by immediate offset. 1582 if (LdSt->getNumExplicitOperands() == 3) { 1583 // Non-paired instruction (e.g., ldr x1, [x0, #8]). 1584 if (!LdSt->getOperand(1).isReg() || !LdSt->getOperand(2).isImm()) 1585 return false; 1586 } else if (LdSt->getNumExplicitOperands() == 4) { 1587 // Paired instruction (e.g., ldp x1, x2, [x0, #8]). 1588 if (!LdSt->getOperand(1).isReg() || !LdSt->getOperand(2).isReg() || !LdSt->getOperand(3).isImm()) 1589 return false; 1590 } else 1591 return false; 1592 1593 // Offset is calculated as the immediate operand multiplied by the scaling factor. 1594 // Unscaled instructions have scaling factor set to 1. 1595 unsigned Scale = 0; 1596 switch (LdSt->getOpcode()) { 1597 default: 1598 return false; 1599 case AArch64::LDURQi: 1600 case AArch64::STURQi: 1601 Width = 16; 1602 Scale = 1; 1603 break; 1604 case AArch64::LDURXi: 1605 case AArch64::LDURDi: 1606 case AArch64::STURXi: 1607 case AArch64::STURDi: 1608 Width = 8; 1609 Scale = 1; 1610 break; 1611 case AArch64::LDURWi: 1612 case AArch64::LDURSi: 1613 case AArch64::LDURSWi: 1614 case AArch64::STURWi: 1615 case AArch64::STURSi: 1616 Width = 4; 1617 Scale = 1; 1618 break; 1619 case AArch64::LDURHi: 1620 case AArch64::LDURHHi: 1621 case AArch64::LDURSHXi: 1622 case AArch64::LDURSHWi: 1623 case AArch64::STURHi: 1624 case AArch64::STURHHi: 1625 Width = 2; 1626 Scale = 1; 1627 break; 1628 case AArch64::LDURBi: 1629 case AArch64::LDURBBi: 1630 case AArch64::LDURSBXi: 1631 case AArch64::LDURSBWi: 1632 case AArch64::STURBi: 1633 case AArch64::STURBBi: 1634 Width = 1; 1635 Scale = 1; 1636 break; 1637 case AArch64::LDPQi: 1638 case AArch64::LDNPQi: 1639 case AArch64::STPQi: 1640 case AArch64::STNPQi: 1641 Scale = 16; 1642 Width = 32; 1643 break; 1644 case AArch64::LDRQui: 1645 case AArch64::STRQui: 1646 Scale = Width = 16; 1647 break; 1648 case AArch64::LDPXi: 1649 case AArch64::LDPDi: 1650 case AArch64::LDNPXi: 1651 case AArch64::LDNPDi: 1652 case AArch64::STPXi: 1653 case AArch64::STPDi: 1654 case AArch64::STNPXi: 1655 case AArch64::STNPDi: 1656 Scale = 8; 1657 Width = 16; 1658 break; 1659 case AArch64::LDRXui: 1660 case AArch64::LDRDui: 1661 case AArch64::STRXui: 1662 case AArch64::STRDui: 1663 Scale = Width = 8; 1664 break; 1665 case AArch64::LDPWi: 1666 case AArch64::LDPSi: 1667 case AArch64::LDNPWi: 1668 case AArch64::LDNPSi: 1669 case AArch64::STPWi: 1670 case AArch64::STPSi: 1671 case AArch64::STNPWi: 1672 case AArch64::STNPSi: 1673 Scale = 4; 1674 Width = 8; 1675 break; 1676 case AArch64::LDRWui: 1677 case AArch64::LDRSui: 1678 case AArch64::LDRSWui: 1679 case AArch64::STRWui: 1680 case AArch64::STRSui: 1681 Scale = Width = 4; 1682 break; 1683 case AArch64::LDRHui: 1684 case AArch64::LDRHHui: 1685 case AArch64::STRHui: 1686 case AArch64::STRHHui: 1687 Scale = Width = 2; 1688 break; 1689 case AArch64::LDRBui: 1690 case AArch64::LDRBBui: 1691 case AArch64::STRBui: 1692 case AArch64::STRBBui: 1693 Scale = Width = 1; 1694 break; 1695 } 1696 1697 if (LdSt->getNumExplicitOperands() == 3) { 1698 BaseReg = LdSt->getOperand(1).getReg(); 1699 Offset = LdSt->getOperand(2).getImm() * Scale; 1700 } else { 1701 assert(LdSt->getNumExplicitOperands() == 4 && "invalid number of operands"); 1702 BaseReg = LdSt->getOperand(2).getReg(); 1703 Offset = LdSt->getOperand(3).getImm() * Scale; 1704 } 1705 return true; 1706 } 1707 1708 // Scale the unscaled offsets. Returns false if the unscaled offset can't be 1709 // scaled. 1710 static bool scaleOffset(unsigned Opc, int64_t &Offset) { 1711 unsigned OffsetStride = 1; 1712 switch (Opc) { 1713 default: 1714 return false; 1715 case AArch64::LDURQi: 1716 case AArch64::STURQi: 1717 OffsetStride = 16; 1718 break; 1719 case AArch64::LDURXi: 1720 case AArch64::LDURDi: 1721 case AArch64::STURXi: 1722 case AArch64::STURDi: 1723 OffsetStride = 8; 1724 break; 1725 case AArch64::LDURWi: 1726 case AArch64::LDURSi: 1727 case AArch64::LDURSWi: 1728 case AArch64::STURWi: 1729 case AArch64::STURSi: 1730 OffsetStride = 4; 1731 break; 1732 } 1733 // If the byte-offset isn't a multiple of the stride, we can't scale this 1734 // offset. 1735 if (Offset % OffsetStride != 0) 1736 return false; 1737 1738 // Convert the byte-offset used by unscaled into an "element" offset used 1739 // by the scaled pair load/store instructions. 1740 Offset /= OffsetStride; 1741 return true; 1742 } 1743 1744 static bool canPairLdStOpc(unsigned FirstOpc, unsigned SecondOpc) { 1745 if (FirstOpc == SecondOpc) 1746 return true; 1747 // We can also pair sign-ext and zero-ext instructions. 1748 switch (FirstOpc) { 1749 default: 1750 return false; 1751 case AArch64::LDRWui: 1752 case AArch64::LDURWi: 1753 return SecondOpc == AArch64::LDRSWui || SecondOpc == AArch64::LDURSWi; 1754 case AArch64::LDRSWui: 1755 case AArch64::LDURSWi: 1756 return SecondOpc == AArch64::LDRWui || SecondOpc == AArch64::LDURWi; 1757 } 1758 // These instructions can't be paired based on their opcodes. 1759 return false; 1760 } 1761 1762 /// Detect opportunities for ldp/stp formation. 1763 /// 1764 /// Only called for LdSt for which getMemOpBaseRegImmOfs returns true. 1765 bool AArch64InstrInfo::shouldClusterMemOps(MachineInstr *FirstLdSt, 1766 MachineInstr *SecondLdSt, 1767 unsigned NumLoads) const { 1768 // Only cluster up to a single pair. 1769 if (NumLoads > 1) 1770 return false; 1771 1772 // Can we pair these instructions based on their opcodes? 1773 unsigned FirstOpc = FirstLdSt->getOpcode(); 1774 unsigned SecondOpc = SecondLdSt->getOpcode(); 1775 if (!canPairLdStOpc(FirstOpc, SecondOpc)) 1776 return false; 1777 1778 // Can't merge volatiles or load/stores that have a hint to avoid pair 1779 // formation, for example. 1780 if (!isCandidateToMergeOrPair(FirstLdSt) || 1781 !isCandidateToMergeOrPair(SecondLdSt)) 1782 return false; 1783 1784 // isCandidateToMergeOrPair guarantees that operand 2 is an immediate. 1785 int64_t Offset1 = FirstLdSt->getOperand(2).getImm(); 1786 if (isUnscaledLdSt(FirstOpc) && !scaleOffset(FirstOpc, Offset1)) 1787 return false; 1788 1789 int64_t Offset2 = SecondLdSt->getOperand(2).getImm(); 1790 if (isUnscaledLdSt(SecondOpc) && !scaleOffset(SecondOpc, Offset2)) 1791 return false; 1792 1793 // Pairwise instructions have a 7-bit signed offset field. 1794 if (Offset1 > 63 || Offset1 < -64) 1795 return false; 1796 1797 // The caller should already have ordered First/SecondLdSt by offset. 1798 assert(Offset1 <= Offset2 && "Caller should have ordered offsets."); 1799 return Offset1 + 1 == Offset2; 1800 } 1801 1802 bool AArch64InstrInfo::shouldScheduleAdjacent(MachineInstr *First, 1803 MachineInstr *Second) const { 1804 if (Subtarget.isCyclone()) { 1805 // Cyclone can fuse CMN, CMP, TST followed by Bcc. 1806 unsigned SecondOpcode = Second->getOpcode(); 1807 if (SecondOpcode == AArch64::Bcc) { 1808 switch (First->getOpcode()) { 1809 default: 1810 return false; 1811 case AArch64::SUBSWri: 1812 case AArch64::ADDSWri: 1813 case AArch64::ANDSWri: 1814 case AArch64::SUBSXri: 1815 case AArch64::ADDSXri: 1816 case AArch64::ANDSXri: 1817 return true; 1818 } 1819 } 1820 // Cyclone B0 also supports ALU operations followed by CBZ/CBNZ. 1821 if (SecondOpcode == AArch64::CBNZW || SecondOpcode == AArch64::CBNZX || 1822 SecondOpcode == AArch64::CBZW || SecondOpcode == AArch64::CBZX) { 1823 switch (First->getOpcode()) { 1824 default: 1825 return false; 1826 case AArch64::ADDWri: 1827 case AArch64::ADDXri: 1828 case AArch64::ANDWri: 1829 case AArch64::ANDXri: 1830 case AArch64::EORWri: 1831 case AArch64::EORXri: 1832 case AArch64::ORRWri: 1833 case AArch64::ORRXri: 1834 case AArch64::SUBWri: 1835 case AArch64::SUBXri: 1836 return true; 1837 } 1838 } 1839 } 1840 return false; 1841 } 1842 1843 MachineInstr *AArch64InstrInfo::emitFrameIndexDebugValue( 1844 MachineFunction &MF, int FrameIx, uint64_t Offset, const MDNode *Var, 1845 const MDNode *Expr, DebugLoc DL) const { 1846 MachineInstrBuilder MIB = BuildMI(MF, DL, get(AArch64::DBG_VALUE)) 1847 .addFrameIndex(FrameIx) 1848 .addImm(0) 1849 .addImm(Offset) 1850 .addMetadata(Var) 1851 .addMetadata(Expr); 1852 return &*MIB; 1853 } 1854 1855 static const MachineInstrBuilder &AddSubReg(const MachineInstrBuilder &MIB, 1856 unsigned Reg, unsigned SubIdx, 1857 unsigned State, 1858 const TargetRegisterInfo *TRI) { 1859 if (!SubIdx) 1860 return MIB.addReg(Reg, State); 1861 1862 if (TargetRegisterInfo::isPhysicalRegister(Reg)) 1863 return MIB.addReg(TRI->getSubReg(Reg, SubIdx), State); 1864 return MIB.addReg(Reg, State, SubIdx); 1865 } 1866 1867 static bool forwardCopyWillClobberTuple(unsigned DestReg, unsigned SrcReg, 1868 unsigned NumRegs) { 1869 // We really want the positive remainder mod 32 here, that happens to be 1870 // easily obtainable with a mask. 1871 return ((DestReg - SrcReg) & 0x1f) < NumRegs; 1872 } 1873 1874 void AArch64InstrInfo::copyPhysRegTuple( 1875 MachineBasicBlock &MBB, MachineBasicBlock::iterator I, DebugLoc DL, 1876 unsigned DestReg, unsigned SrcReg, bool KillSrc, unsigned Opcode, 1877 llvm::ArrayRef<unsigned> Indices) const { 1878 assert(Subtarget.hasNEON() && 1879 "Unexpected register copy without NEON"); 1880 const TargetRegisterInfo *TRI = &getRegisterInfo(); 1881 uint16_t DestEncoding = TRI->getEncodingValue(DestReg); 1882 uint16_t SrcEncoding = TRI->getEncodingValue(SrcReg); 1883 unsigned NumRegs = Indices.size(); 1884 1885 int SubReg = 0, End = NumRegs, Incr = 1; 1886 if (forwardCopyWillClobberTuple(DestEncoding, SrcEncoding, NumRegs)) { 1887 SubReg = NumRegs - 1; 1888 End = -1; 1889 Incr = -1; 1890 } 1891 1892 for (; SubReg != End; SubReg += Incr) { 1893 const MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opcode)); 1894 AddSubReg(MIB, DestReg, Indices[SubReg], RegState::Define, TRI); 1895 AddSubReg(MIB, SrcReg, Indices[SubReg], 0, TRI); 1896 AddSubReg(MIB, SrcReg, Indices[SubReg], getKillRegState(KillSrc), TRI); 1897 } 1898 } 1899 1900 void AArch64InstrInfo::copyPhysReg(MachineBasicBlock &MBB, 1901 MachineBasicBlock::iterator I, DebugLoc DL, 1902 unsigned DestReg, unsigned SrcReg, 1903 bool KillSrc) const { 1904 if (AArch64::GPR32spRegClass.contains(DestReg) && 1905 (AArch64::GPR32spRegClass.contains(SrcReg) || SrcReg == AArch64::WZR)) { 1906 const TargetRegisterInfo *TRI = &getRegisterInfo(); 1907 1908 if (DestReg == AArch64::WSP || SrcReg == AArch64::WSP) { 1909 // If either operand is WSP, expand to ADD #0. 1910 if (Subtarget.hasZeroCycleRegMove()) { 1911 // Cyclone recognizes "ADD Xd, Xn, #0" as a zero-cycle register move. 1912 unsigned DestRegX = TRI->getMatchingSuperReg(DestReg, AArch64::sub_32, 1913 &AArch64::GPR64spRegClass); 1914 unsigned SrcRegX = TRI->getMatchingSuperReg(SrcReg, AArch64::sub_32, 1915 &AArch64::GPR64spRegClass); 1916 // This instruction is reading and writing X registers. This may upset 1917 // the register scavenger and machine verifier, so we need to indicate 1918 // that we are reading an undefined value from SrcRegX, but a proper 1919 // value from SrcReg. 1920 BuildMI(MBB, I, DL, get(AArch64::ADDXri), DestRegX) 1921 .addReg(SrcRegX, RegState::Undef) 1922 .addImm(0) 1923 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)) 1924 .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc)); 1925 } else { 1926 BuildMI(MBB, I, DL, get(AArch64::ADDWri), DestReg) 1927 .addReg(SrcReg, getKillRegState(KillSrc)) 1928 .addImm(0) 1929 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 1930 } 1931 } else if (SrcReg == AArch64::WZR && Subtarget.hasZeroCycleZeroing()) { 1932 BuildMI(MBB, I, DL, get(AArch64::MOVZWi), DestReg).addImm(0).addImm( 1933 AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 1934 } else { 1935 if (Subtarget.hasZeroCycleRegMove()) { 1936 // Cyclone recognizes "ORR Xd, XZR, Xm" as a zero-cycle register move. 1937 unsigned DestRegX = TRI->getMatchingSuperReg(DestReg, AArch64::sub_32, 1938 &AArch64::GPR64spRegClass); 1939 unsigned SrcRegX = TRI->getMatchingSuperReg(SrcReg, AArch64::sub_32, 1940 &AArch64::GPR64spRegClass); 1941 // This instruction is reading and writing X registers. This may upset 1942 // the register scavenger and machine verifier, so we need to indicate 1943 // that we are reading an undefined value from SrcRegX, but a proper 1944 // value from SrcReg. 1945 BuildMI(MBB, I, DL, get(AArch64::ORRXrr), DestRegX) 1946 .addReg(AArch64::XZR) 1947 .addReg(SrcRegX, RegState::Undef) 1948 .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc)); 1949 } else { 1950 // Otherwise, expand to ORR WZR. 1951 BuildMI(MBB, I, DL, get(AArch64::ORRWrr), DestReg) 1952 .addReg(AArch64::WZR) 1953 .addReg(SrcReg, getKillRegState(KillSrc)); 1954 } 1955 } 1956 return; 1957 } 1958 1959 if (AArch64::GPR64spRegClass.contains(DestReg) && 1960 (AArch64::GPR64spRegClass.contains(SrcReg) || SrcReg == AArch64::XZR)) { 1961 if (DestReg == AArch64::SP || SrcReg == AArch64::SP) { 1962 // If either operand is SP, expand to ADD #0. 1963 BuildMI(MBB, I, DL, get(AArch64::ADDXri), DestReg) 1964 .addReg(SrcReg, getKillRegState(KillSrc)) 1965 .addImm(0) 1966 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 1967 } else if (SrcReg == AArch64::XZR && Subtarget.hasZeroCycleZeroing()) { 1968 BuildMI(MBB, I, DL, get(AArch64::MOVZXi), DestReg).addImm(0).addImm( 1969 AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)); 1970 } else { 1971 // Otherwise, expand to ORR XZR. 1972 BuildMI(MBB, I, DL, get(AArch64::ORRXrr), DestReg) 1973 .addReg(AArch64::XZR) 1974 .addReg(SrcReg, getKillRegState(KillSrc)); 1975 } 1976 return; 1977 } 1978 1979 // Copy a DDDD register quad by copying the individual sub-registers. 1980 if (AArch64::DDDDRegClass.contains(DestReg) && 1981 AArch64::DDDDRegClass.contains(SrcReg)) { 1982 static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1, 1983 AArch64::dsub2, AArch64::dsub3 }; 1984 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8, 1985 Indices); 1986 return; 1987 } 1988 1989 // Copy a DDD register triple by copying the individual sub-registers. 1990 if (AArch64::DDDRegClass.contains(DestReg) && 1991 AArch64::DDDRegClass.contains(SrcReg)) { 1992 static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1, 1993 AArch64::dsub2 }; 1994 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8, 1995 Indices); 1996 return; 1997 } 1998 1999 // Copy a DD register pair by copying the individual sub-registers. 2000 if (AArch64::DDRegClass.contains(DestReg) && 2001 AArch64::DDRegClass.contains(SrcReg)) { 2002 static const unsigned Indices[] = { AArch64::dsub0, AArch64::dsub1 }; 2003 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv8i8, 2004 Indices); 2005 return; 2006 } 2007 2008 // Copy a QQQQ register quad by copying the individual sub-registers. 2009 if (AArch64::QQQQRegClass.contains(DestReg) && 2010 AArch64::QQQQRegClass.contains(SrcReg)) { 2011 static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1, 2012 AArch64::qsub2, AArch64::qsub3 }; 2013 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8, 2014 Indices); 2015 return; 2016 } 2017 2018 // Copy a QQQ register triple by copying the individual sub-registers. 2019 if (AArch64::QQQRegClass.contains(DestReg) && 2020 AArch64::QQQRegClass.contains(SrcReg)) { 2021 static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1, 2022 AArch64::qsub2 }; 2023 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8, 2024 Indices); 2025 return; 2026 } 2027 2028 // Copy a QQ register pair by copying the individual sub-registers. 2029 if (AArch64::QQRegClass.contains(DestReg) && 2030 AArch64::QQRegClass.contains(SrcReg)) { 2031 static const unsigned Indices[] = { AArch64::qsub0, AArch64::qsub1 }; 2032 copyPhysRegTuple(MBB, I, DL, DestReg, SrcReg, KillSrc, AArch64::ORRv16i8, 2033 Indices); 2034 return; 2035 } 2036 2037 if (AArch64::FPR128RegClass.contains(DestReg) && 2038 AArch64::FPR128RegClass.contains(SrcReg)) { 2039 if(Subtarget.hasNEON()) { 2040 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 2041 .addReg(SrcReg) 2042 .addReg(SrcReg, getKillRegState(KillSrc)); 2043 } else { 2044 BuildMI(MBB, I, DL, get(AArch64::STRQpre)) 2045 .addReg(AArch64::SP, RegState::Define) 2046 .addReg(SrcReg, getKillRegState(KillSrc)) 2047 .addReg(AArch64::SP) 2048 .addImm(-16); 2049 BuildMI(MBB, I, DL, get(AArch64::LDRQpre)) 2050 .addReg(AArch64::SP, RegState::Define) 2051 .addReg(DestReg, RegState::Define) 2052 .addReg(AArch64::SP) 2053 .addImm(16); 2054 } 2055 return; 2056 } 2057 2058 if (AArch64::FPR64RegClass.contains(DestReg) && 2059 AArch64::FPR64RegClass.contains(SrcReg)) { 2060 if(Subtarget.hasNEON()) { 2061 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::dsub, 2062 &AArch64::FPR128RegClass); 2063 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::dsub, 2064 &AArch64::FPR128RegClass); 2065 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 2066 .addReg(SrcReg) 2067 .addReg(SrcReg, getKillRegState(KillSrc)); 2068 } else { 2069 BuildMI(MBB, I, DL, get(AArch64::FMOVDr), DestReg) 2070 .addReg(SrcReg, getKillRegState(KillSrc)); 2071 } 2072 return; 2073 } 2074 2075 if (AArch64::FPR32RegClass.contains(DestReg) && 2076 AArch64::FPR32RegClass.contains(SrcReg)) { 2077 if(Subtarget.hasNEON()) { 2078 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::ssub, 2079 &AArch64::FPR128RegClass); 2080 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::ssub, 2081 &AArch64::FPR128RegClass); 2082 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 2083 .addReg(SrcReg) 2084 .addReg(SrcReg, getKillRegState(KillSrc)); 2085 } else { 2086 BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg) 2087 .addReg(SrcReg, getKillRegState(KillSrc)); 2088 } 2089 return; 2090 } 2091 2092 if (AArch64::FPR16RegClass.contains(DestReg) && 2093 AArch64::FPR16RegClass.contains(SrcReg)) { 2094 if(Subtarget.hasNEON()) { 2095 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub, 2096 &AArch64::FPR128RegClass); 2097 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub, 2098 &AArch64::FPR128RegClass); 2099 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 2100 .addReg(SrcReg) 2101 .addReg(SrcReg, getKillRegState(KillSrc)); 2102 } else { 2103 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::hsub, 2104 &AArch64::FPR32RegClass); 2105 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::hsub, 2106 &AArch64::FPR32RegClass); 2107 BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg) 2108 .addReg(SrcReg, getKillRegState(KillSrc)); 2109 } 2110 return; 2111 } 2112 2113 if (AArch64::FPR8RegClass.contains(DestReg) && 2114 AArch64::FPR8RegClass.contains(SrcReg)) { 2115 if(Subtarget.hasNEON()) { 2116 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub, 2117 &AArch64::FPR128RegClass); 2118 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub, 2119 &AArch64::FPR128RegClass); 2120 BuildMI(MBB, I, DL, get(AArch64::ORRv16i8), DestReg) 2121 .addReg(SrcReg) 2122 .addReg(SrcReg, getKillRegState(KillSrc)); 2123 } else { 2124 DestReg = RI.getMatchingSuperReg(DestReg, AArch64::bsub, 2125 &AArch64::FPR32RegClass); 2126 SrcReg = RI.getMatchingSuperReg(SrcReg, AArch64::bsub, 2127 &AArch64::FPR32RegClass); 2128 BuildMI(MBB, I, DL, get(AArch64::FMOVSr), DestReg) 2129 .addReg(SrcReg, getKillRegState(KillSrc)); 2130 } 2131 return; 2132 } 2133 2134 // Copies between GPR64 and FPR64. 2135 if (AArch64::FPR64RegClass.contains(DestReg) && 2136 AArch64::GPR64RegClass.contains(SrcReg)) { 2137 BuildMI(MBB, I, DL, get(AArch64::FMOVXDr), DestReg) 2138 .addReg(SrcReg, getKillRegState(KillSrc)); 2139 return; 2140 } 2141 if (AArch64::GPR64RegClass.contains(DestReg) && 2142 AArch64::FPR64RegClass.contains(SrcReg)) { 2143 BuildMI(MBB, I, DL, get(AArch64::FMOVDXr), DestReg) 2144 .addReg(SrcReg, getKillRegState(KillSrc)); 2145 return; 2146 } 2147 // Copies between GPR32 and FPR32. 2148 if (AArch64::FPR32RegClass.contains(DestReg) && 2149 AArch64::GPR32RegClass.contains(SrcReg)) { 2150 BuildMI(MBB, I, DL, get(AArch64::FMOVWSr), DestReg) 2151 .addReg(SrcReg, getKillRegState(KillSrc)); 2152 return; 2153 } 2154 if (AArch64::GPR32RegClass.contains(DestReg) && 2155 AArch64::FPR32RegClass.contains(SrcReg)) { 2156 BuildMI(MBB, I, DL, get(AArch64::FMOVSWr), DestReg) 2157 .addReg(SrcReg, getKillRegState(KillSrc)); 2158 return; 2159 } 2160 2161 if (DestReg == AArch64::NZCV) { 2162 assert(AArch64::GPR64RegClass.contains(SrcReg) && "Invalid NZCV copy"); 2163 BuildMI(MBB, I, DL, get(AArch64::MSR)) 2164 .addImm(AArch64SysReg::NZCV) 2165 .addReg(SrcReg, getKillRegState(KillSrc)) 2166 .addReg(AArch64::NZCV, RegState::Implicit | RegState::Define); 2167 return; 2168 } 2169 2170 if (SrcReg == AArch64::NZCV) { 2171 assert(AArch64::GPR64RegClass.contains(DestReg) && "Invalid NZCV copy"); 2172 BuildMI(MBB, I, DL, get(AArch64::MRS), DestReg) 2173 .addImm(AArch64SysReg::NZCV) 2174 .addReg(AArch64::NZCV, RegState::Implicit | getKillRegState(KillSrc)); 2175 return; 2176 } 2177 2178 llvm_unreachable("unimplemented reg-to-reg copy"); 2179 } 2180 2181 void AArch64InstrInfo::storeRegToStackSlot( 2182 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned SrcReg, 2183 bool isKill, int FI, const TargetRegisterClass *RC, 2184 const TargetRegisterInfo *TRI) const { 2185 DebugLoc DL; 2186 if (MBBI != MBB.end()) 2187 DL = MBBI->getDebugLoc(); 2188 MachineFunction &MF = *MBB.getParent(); 2189 MachineFrameInfo &MFI = *MF.getFrameInfo(); 2190 unsigned Align = MFI.getObjectAlignment(FI); 2191 2192 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FI); 2193 MachineMemOperand *MMO = MF.getMachineMemOperand( 2194 PtrInfo, MachineMemOperand::MOStore, MFI.getObjectSize(FI), Align); 2195 unsigned Opc = 0; 2196 bool Offset = true; 2197 switch (RC->getSize()) { 2198 case 1: 2199 if (AArch64::FPR8RegClass.hasSubClassEq(RC)) 2200 Opc = AArch64::STRBui; 2201 break; 2202 case 2: 2203 if (AArch64::FPR16RegClass.hasSubClassEq(RC)) 2204 Opc = AArch64::STRHui; 2205 break; 2206 case 4: 2207 if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) { 2208 Opc = AArch64::STRWui; 2209 if (TargetRegisterInfo::isVirtualRegister(SrcReg)) 2210 MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR32RegClass); 2211 else 2212 assert(SrcReg != AArch64::WSP); 2213 } else if (AArch64::FPR32RegClass.hasSubClassEq(RC)) 2214 Opc = AArch64::STRSui; 2215 break; 2216 case 8: 2217 if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) { 2218 Opc = AArch64::STRXui; 2219 if (TargetRegisterInfo::isVirtualRegister(SrcReg)) 2220 MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR64RegClass); 2221 else 2222 assert(SrcReg != AArch64::SP); 2223 } else if (AArch64::FPR64RegClass.hasSubClassEq(RC)) 2224 Opc = AArch64::STRDui; 2225 break; 2226 case 16: 2227 if (AArch64::FPR128RegClass.hasSubClassEq(RC)) 2228 Opc = AArch64::STRQui; 2229 else if (AArch64::DDRegClass.hasSubClassEq(RC)) { 2230 assert(Subtarget.hasNEON() && 2231 "Unexpected register store without NEON"); 2232 Opc = AArch64::ST1Twov1d; 2233 Offset = false; 2234 } 2235 break; 2236 case 24: 2237 if (AArch64::DDDRegClass.hasSubClassEq(RC)) { 2238 assert(Subtarget.hasNEON() && 2239 "Unexpected register store without NEON"); 2240 Opc = AArch64::ST1Threev1d; 2241 Offset = false; 2242 } 2243 break; 2244 case 32: 2245 if (AArch64::DDDDRegClass.hasSubClassEq(RC)) { 2246 assert(Subtarget.hasNEON() && 2247 "Unexpected register store without NEON"); 2248 Opc = AArch64::ST1Fourv1d; 2249 Offset = false; 2250 } else if (AArch64::QQRegClass.hasSubClassEq(RC)) { 2251 assert(Subtarget.hasNEON() && 2252 "Unexpected register store without NEON"); 2253 Opc = AArch64::ST1Twov2d; 2254 Offset = false; 2255 } 2256 break; 2257 case 48: 2258 if (AArch64::QQQRegClass.hasSubClassEq(RC)) { 2259 assert(Subtarget.hasNEON() && 2260 "Unexpected register store without NEON"); 2261 Opc = AArch64::ST1Threev2d; 2262 Offset = false; 2263 } 2264 break; 2265 case 64: 2266 if (AArch64::QQQQRegClass.hasSubClassEq(RC)) { 2267 assert(Subtarget.hasNEON() && 2268 "Unexpected register store without NEON"); 2269 Opc = AArch64::ST1Fourv2d; 2270 Offset = false; 2271 } 2272 break; 2273 } 2274 assert(Opc && "Unknown register class"); 2275 2276 const MachineInstrBuilder MI = BuildMI(MBB, MBBI, DL, get(Opc)) 2277 .addReg(SrcReg, getKillRegState(isKill)) 2278 .addFrameIndex(FI); 2279 2280 if (Offset) 2281 MI.addImm(0); 2282 MI.addMemOperand(MMO); 2283 } 2284 2285 void AArch64InstrInfo::loadRegFromStackSlot( 2286 MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, unsigned DestReg, 2287 int FI, const TargetRegisterClass *RC, 2288 const TargetRegisterInfo *TRI) const { 2289 DebugLoc DL; 2290 if (MBBI != MBB.end()) 2291 DL = MBBI->getDebugLoc(); 2292 MachineFunction &MF = *MBB.getParent(); 2293 MachineFrameInfo &MFI = *MF.getFrameInfo(); 2294 unsigned Align = MFI.getObjectAlignment(FI); 2295 MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(MF, FI); 2296 MachineMemOperand *MMO = MF.getMachineMemOperand( 2297 PtrInfo, MachineMemOperand::MOLoad, MFI.getObjectSize(FI), Align); 2298 2299 unsigned Opc = 0; 2300 bool Offset = true; 2301 switch (RC->getSize()) { 2302 case 1: 2303 if (AArch64::FPR8RegClass.hasSubClassEq(RC)) 2304 Opc = AArch64::LDRBui; 2305 break; 2306 case 2: 2307 if (AArch64::FPR16RegClass.hasSubClassEq(RC)) 2308 Opc = AArch64::LDRHui; 2309 break; 2310 case 4: 2311 if (AArch64::GPR32allRegClass.hasSubClassEq(RC)) { 2312 Opc = AArch64::LDRWui; 2313 if (TargetRegisterInfo::isVirtualRegister(DestReg)) 2314 MF.getRegInfo().constrainRegClass(DestReg, &AArch64::GPR32RegClass); 2315 else 2316 assert(DestReg != AArch64::WSP); 2317 } else if (AArch64::FPR32RegClass.hasSubClassEq(RC)) 2318 Opc = AArch64::LDRSui; 2319 break; 2320 case 8: 2321 if (AArch64::GPR64allRegClass.hasSubClassEq(RC)) { 2322 Opc = AArch64::LDRXui; 2323 if (TargetRegisterInfo::isVirtualRegister(DestReg)) 2324 MF.getRegInfo().constrainRegClass(DestReg, &AArch64::GPR64RegClass); 2325 else 2326 assert(DestReg != AArch64::SP); 2327 } else if (AArch64::FPR64RegClass.hasSubClassEq(RC)) 2328 Opc = AArch64::LDRDui; 2329 break; 2330 case 16: 2331 if (AArch64::FPR128RegClass.hasSubClassEq(RC)) 2332 Opc = AArch64::LDRQui; 2333 else if (AArch64::DDRegClass.hasSubClassEq(RC)) { 2334 assert(Subtarget.hasNEON() && 2335 "Unexpected register load without NEON"); 2336 Opc = AArch64::LD1Twov1d; 2337 Offset = false; 2338 } 2339 break; 2340 case 24: 2341 if (AArch64::DDDRegClass.hasSubClassEq(RC)) { 2342 assert(Subtarget.hasNEON() && 2343 "Unexpected register load without NEON"); 2344 Opc = AArch64::LD1Threev1d; 2345 Offset = false; 2346 } 2347 break; 2348 case 32: 2349 if (AArch64::DDDDRegClass.hasSubClassEq(RC)) { 2350 assert(Subtarget.hasNEON() && 2351 "Unexpected register load without NEON"); 2352 Opc = AArch64::LD1Fourv1d; 2353 Offset = false; 2354 } else if (AArch64::QQRegClass.hasSubClassEq(RC)) { 2355 assert(Subtarget.hasNEON() && 2356 "Unexpected register load without NEON"); 2357 Opc = AArch64::LD1Twov2d; 2358 Offset = false; 2359 } 2360 break; 2361 case 48: 2362 if (AArch64::QQQRegClass.hasSubClassEq(RC)) { 2363 assert(Subtarget.hasNEON() && 2364 "Unexpected register load without NEON"); 2365 Opc = AArch64::LD1Threev2d; 2366 Offset = false; 2367 } 2368 break; 2369 case 64: 2370 if (AArch64::QQQQRegClass.hasSubClassEq(RC)) { 2371 assert(Subtarget.hasNEON() && 2372 "Unexpected register load without NEON"); 2373 Opc = AArch64::LD1Fourv2d; 2374 Offset = false; 2375 } 2376 break; 2377 } 2378 assert(Opc && "Unknown register class"); 2379 2380 const MachineInstrBuilder MI = BuildMI(MBB, MBBI, DL, get(Opc)) 2381 .addReg(DestReg, getDefRegState(true)) 2382 .addFrameIndex(FI); 2383 if (Offset) 2384 MI.addImm(0); 2385 MI.addMemOperand(MMO); 2386 } 2387 2388 void llvm::emitFrameOffset(MachineBasicBlock &MBB, 2389 MachineBasicBlock::iterator MBBI, DebugLoc DL, 2390 unsigned DestReg, unsigned SrcReg, int Offset, 2391 const TargetInstrInfo *TII, 2392 MachineInstr::MIFlag Flag, bool SetNZCV) { 2393 if (DestReg == SrcReg && Offset == 0) 2394 return; 2395 2396 assert((DestReg != AArch64::SP || Offset % 16 == 0) && 2397 "SP increment/decrement not 16-byte aligned"); 2398 2399 bool isSub = Offset < 0; 2400 if (isSub) 2401 Offset = -Offset; 2402 2403 // FIXME: If the offset won't fit in 24-bits, compute the offset into a 2404 // scratch register. If DestReg is a virtual register, use it as the 2405 // scratch register; otherwise, create a new virtual register (to be 2406 // replaced by the scavenger at the end of PEI). That case can be optimized 2407 // slightly if DestReg is SP which is always 16-byte aligned, so the scratch 2408 // register can be loaded with offset%8 and the add/sub can use an extending 2409 // instruction with LSL#3. 2410 // Currently the function handles any offsets but generates a poor sequence 2411 // of code. 2412 // assert(Offset < (1 << 24) && "unimplemented reg plus immediate"); 2413 2414 unsigned Opc; 2415 if (SetNZCV) 2416 Opc = isSub ? AArch64::SUBSXri : AArch64::ADDSXri; 2417 else 2418 Opc = isSub ? AArch64::SUBXri : AArch64::ADDXri; 2419 const unsigned MaxEncoding = 0xfff; 2420 const unsigned ShiftSize = 12; 2421 const unsigned MaxEncodableValue = MaxEncoding << ShiftSize; 2422 while (((unsigned)Offset) >= (1 << ShiftSize)) { 2423 unsigned ThisVal; 2424 if (((unsigned)Offset) > MaxEncodableValue) { 2425 ThisVal = MaxEncodableValue; 2426 } else { 2427 ThisVal = Offset & MaxEncodableValue; 2428 } 2429 assert((ThisVal >> ShiftSize) <= MaxEncoding && 2430 "Encoding cannot handle value that big"); 2431 BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) 2432 .addReg(SrcReg) 2433 .addImm(ThisVal >> ShiftSize) 2434 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftSize)) 2435 .setMIFlag(Flag); 2436 2437 SrcReg = DestReg; 2438 Offset -= ThisVal; 2439 if (Offset == 0) 2440 return; 2441 } 2442 BuildMI(MBB, MBBI, DL, TII->get(Opc), DestReg) 2443 .addReg(SrcReg) 2444 .addImm(Offset) 2445 .addImm(AArch64_AM::getShifterImm(AArch64_AM::LSL, 0)) 2446 .setMIFlag(Flag); 2447 } 2448 2449 MachineInstr *AArch64InstrInfo::foldMemoryOperandImpl( 2450 MachineFunction &MF, MachineInstr *MI, ArrayRef<unsigned> Ops, 2451 MachineBasicBlock::iterator InsertPt, int FrameIndex, 2452 LiveIntervals *LIS) const { 2453 // This is a bit of a hack. Consider this instruction: 2454 // 2455 // %vreg0<def> = COPY %SP; GPR64all:%vreg0 2456 // 2457 // We explicitly chose GPR64all for the virtual register so such a copy might 2458 // be eliminated by RegisterCoalescer. However, that may not be possible, and 2459 // %vreg0 may even spill. We can't spill %SP, and since it is in the GPR64all 2460 // register class, TargetInstrInfo::foldMemoryOperand() is going to try. 2461 // 2462 // To prevent that, we are going to constrain the %vreg0 register class here. 2463 // 2464 // <rdar://problem/11522048> 2465 // 2466 if (MI->isCopy()) { 2467 unsigned DstReg = MI->getOperand(0).getReg(); 2468 unsigned SrcReg = MI->getOperand(1).getReg(); 2469 if (SrcReg == AArch64::SP && 2470 TargetRegisterInfo::isVirtualRegister(DstReg)) { 2471 MF.getRegInfo().constrainRegClass(DstReg, &AArch64::GPR64RegClass); 2472 return nullptr; 2473 } 2474 if (DstReg == AArch64::SP && 2475 TargetRegisterInfo::isVirtualRegister(SrcReg)) { 2476 MF.getRegInfo().constrainRegClass(SrcReg, &AArch64::GPR64RegClass); 2477 return nullptr; 2478 } 2479 } 2480 2481 // Cannot fold. 2482 return nullptr; 2483 } 2484 2485 int llvm::isAArch64FrameOffsetLegal(const MachineInstr &MI, int &Offset, 2486 bool *OutUseUnscaledOp, 2487 unsigned *OutUnscaledOp, 2488 int *EmittableOffset) { 2489 int Scale = 1; 2490 bool IsSigned = false; 2491 // The ImmIdx should be changed case by case if it is not 2. 2492 unsigned ImmIdx = 2; 2493 unsigned UnscaledOp = 0; 2494 // Set output values in case of early exit. 2495 if (EmittableOffset) 2496 *EmittableOffset = 0; 2497 if (OutUseUnscaledOp) 2498 *OutUseUnscaledOp = false; 2499 if (OutUnscaledOp) 2500 *OutUnscaledOp = 0; 2501 switch (MI.getOpcode()) { 2502 default: 2503 llvm_unreachable("unhandled opcode in rewriteAArch64FrameIndex"); 2504 // Vector spills/fills can't take an immediate offset. 2505 case AArch64::LD1Twov2d: 2506 case AArch64::LD1Threev2d: 2507 case AArch64::LD1Fourv2d: 2508 case AArch64::LD1Twov1d: 2509 case AArch64::LD1Threev1d: 2510 case AArch64::LD1Fourv1d: 2511 case AArch64::ST1Twov2d: 2512 case AArch64::ST1Threev2d: 2513 case AArch64::ST1Fourv2d: 2514 case AArch64::ST1Twov1d: 2515 case AArch64::ST1Threev1d: 2516 case AArch64::ST1Fourv1d: 2517 return AArch64FrameOffsetCannotUpdate; 2518 case AArch64::PRFMui: 2519 Scale = 8; 2520 UnscaledOp = AArch64::PRFUMi; 2521 break; 2522 case AArch64::LDRXui: 2523 Scale = 8; 2524 UnscaledOp = AArch64::LDURXi; 2525 break; 2526 case AArch64::LDRWui: 2527 Scale = 4; 2528 UnscaledOp = AArch64::LDURWi; 2529 break; 2530 case AArch64::LDRBui: 2531 Scale = 1; 2532 UnscaledOp = AArch64::LDURBi; 2533 break; 2534 case AArch64::LDRHui: 2535 Scale = 2; 2536 UnscaledOp = AArch64::LDURHi; 2537 break; 2538 case AArch64::LDRSui: 2539 Scale = 4; 2540 UnscaledOp = AArch64::LDURSi; 2541 break; 2542 case AArch64::LDRDui: 2543 Scale = 8; 2544 UnscaledOp = AArch64::LDURDi; 2545 break; 2546 case AArch64::LDRQui: 2547 Scale = 16; 2548 UnscaledOp = AArch64::LDURQi; 2549 break; 2550 case AArch64::LDRBBui: 2551 Scale = 1; 2552 UnscaledOp = AArch64::LDURBBi; 2553 break; 2554 case AArch64::LDRHHui: 2555 Scale = 2; 2556 UnscaledOp = AArch64::LDURHHi; 2557 break; 2558 case AArch64::LDRSBXui: 2559 Scale = 1; 2560 UnscaledOp = AArch64::LDURSBXi; 2561 break; 2562 case AArch64::LDRSBWui: 2563 Scale = 1; 2564 UnscaledOp = AArch64::LDURSBWi; 2565 break; 2566 case AArch64::LDRSHXui: 2567 Scale = 2; 2568 UnscaledOp = AArch64::LDURSHXi; 2569 break; 2570 case AArch64::LDRSHWui: 2571 Scale = 2; 2572 UnscaledOp = AArch64::LDURSHWi; 2573 break; 2574 case AArch64::LDRSWui: 2575 Scale = 4; 2576 UnscaledOp = AArch64::LDURSWi; 2577 break; 2578 2579 case AArch64::STRXui: 2580 Scale = 8; 2581 UnscaledOp = AArch64::STURXi; 2582 break; 2583 case AArch64::STRWui: 2584 Scale = 4; 2585 UnscaledOp = AArch64::STURWi; 2586 break; 2587 case AArch64::STRBui: 2588 Scale = 1; 2589 UnscaledOp = AArch64::STURBi; 2590 break; 2591 case AArch64::STRHui: 2592 Scale = 2; 2593 UnscaledOp = AArch64::STURHi; 2594 break; 2595 case AArch64::STRSui: 2596 Scale = 4; 2597 UnscaledOp = AArch64::STURSi; 2598 break; 2599 case AArch64::STRDui: 2600 Scale = 8; 2601 UnscaledOp = AArch64::STURDi; 2602 break; 2603 case AArch64::STRQui: 2604 Scale = 16; 2605 UnscaledOp = AArch64::STURQi; 2606 break; 2607 case AArch64::STRBBui: 2608 Scale = 1; 2609 UnscaledOp = AArch64::STURBBi; 2610 break; 2611 case AArch64::STRHHui: 2612 Scale = 2; 2613 UnscaledOp = AArch64::STURHHi; 2614 break; 2615 2616 case AArch64::LDPXi: 2617 case AArch64::LDPDi: 2618 case AArch64::STPXi: 2619 case AArch64::STPDi: 2620 case AArch64::LDNPXi: 2621 case AArch64::LDNPDi: 2622 case AArch64::STNPXi: 2623 case AArch64::STNPDi: 2624 ImmIdx = 3; 2625 IsSigned = true; 2626 Scale = 8; 2627 break; 2628 case AArch64::LDPQi: 2629 case AArch64::STPQi: 2630 case AArch64::LDNPQi: 2631 case AArch64::STNPQi: 2632 ImmIdx = 3; 2633 IsSigned = true; 2634 Scale = 16; 2635 break; 2636 case AArch64::LDPWi: 2637 case AArch64::LDPSi: 2638 case AArch64::STPWi: 2639 case AArch64::STPSi: 2640 case AArch64::LDNPWi: 2641 case AArch64::LDNPSi: 2642 case AArch64::STNPWi: 2643 case AArch64::STNPSi: 2644 ImmIdx = 3; 2645 IsSigned = true; 2646 Scale = 4; 2647 break; 2648 2649 case AArch64::LDURXi: 2650 case AArch64::LDURWi: 2651 case AArch64::LDURBi: 2652 case AArch64::LDURHi: 2653 case AArch64::LDURSi: 2654 case AArch64::LDURDi: 2655 case AArch64::LDURQi: 2656 case AArch64::LDURHHi: 2657 case AArch64::LDURBBi: 2658 case AArch64::LDURSBXi: 2659 case AArch64::LDURSBWi: 2660 case AArch64::LDURSHXi: 2661 case AArch64::LDURSHWi: 2662 case AArch64::LDURSWi: 2663 case AArch64::STURXi: 2664 case AArch64::STURWi: 2665 case AArch64::STURBi: 2666 case AArch64::STURHi: 2667 case AArch64::STURSi: 2668 case AArch64::STURDi: 2669 case AArch64::STURQi: 2670 case AArch64::STURBBi: 2671 case AArch64::STURHHi: 2672 Scale = 1; 2673 break; 2674 } 2675 2676 Offset += MI.getOperand(ImmIdx).getImm() * Scale; 2677 2678 bool useUnscaledOp = false; 2679 // If the offset doesn't match the scale, we rewrite the instruction to 2680 // use the unscaled instruction instead. Likewise, if we have a negative 2681 // offset (and have an unscaled op to use). 2682 if ((Offset & (Scale - 1)) != 0 || (Offset < 0 && UnscaledOp != 0)) 2683 useUnscaledOp = true; 2684 2685 // Use an unscaled addressing mode if the instruction has a negative offset 2686 // (or if the instruction is already using an unscaled addressing mode). 2687 unsigned MaskBits; 2688 if (IsSigned) { 2689 // ldp/stp instructions. 2690 MaskBits = 7; 2691 Offset /= Scale; 2692 } else if (UnscaledOp == 0 || useUnscaledOp) { 2693 MaskBits = 9; 2694 IsSigned = true; 2695 Scale = 1; 2696 } else { 2697 MaskBits = 12; 2698 IsSigned = false; 2699 Offset /= Scale; 2700 } 2701 2702 // Attempt to fold address computation. 2703 int MaxOff = (1 << (MaskBits - IsSigned)) - 1; 2704 int MinOff = (IsSigned ? (-MaxOff - 1) : 0); 2705 if (Offset >= MinOff && Offset <= MaxOff) { 2706 if (EmittableOffset) 2707 *EmittableOffset = Offset; 2708 Offset = 0; 2709 } else { 2710 int NewOff = Offset < 0 ? MinOff : MaxOff; 2711 if (EmittableOffset) 2712 *EmittableOffset = NewOff; 2713 Offset = (Offset - NewOff) * Scale; 2714 } 2715 if (OutUseUnscaledOp) 2716 *OutUseUnscaledOp = useUnscaledOp; 2717 if (OutUnscaledOp) 2718 *OutUnscaledOp = UnscaledOp; 2719 return AArch64FrameOffsetCanUpdate | 2720 (Offset == 0 ? AArch64FrameOffsetIsLegal : 0); 2721 } 2722 2723 bool llvm::rewriteAArch64FrameIndex(MachineInstr &MI, unsigned FrameRegIdx, 2724 unsigned FrameReg, int &Offset, 2725 const AArch64InstrInfo *TII) { 2726 unsigned Opcode = MI.getOpcode(); 2727 unsigned ImmIdx = FrameRegIdx + 1; 2728 2729 if (Opcode == AArch64::ADDSXri || Opcode == AArch64::ADDXri) { 2730 Offset += MI.getOperand(ImmIdx).getImm(); 2731 emitFrameOffset(*MI.getParent(), MI, MI.getDebugLoc(), 2732 MI.getOperand(0).getReg(), FrameReg, Offset, TII, 2733 MachineInstr::NoFlags, (Opcode == AArch64::ADDSXri)); 2734 MI.eraseFromParent(); 2735 Offset = 0; 2736 return true; 2737 } 2738 2739 int NewOffset; 2740 unsigned UnscaledOp; 2741 bool UseUnscaledOp; 2742 int Status = isAArch64FrameOffsetLegal(MI, Offset, &UseUnscaledOp, 2743 &UnscaledOp, &NewOffset); 2744 if (Status & AArch64FrameOffsetCanUpdate) { 2745 if (Status & AArch64FrameOffsetIsLegal) 2746 // Replace the FrameIndex with FrameReg. 2747 MI.getOperand(FrameRegIdx).ChangeToRegister(FrameReg, false); 2748 if (UseUnscaledOp) 2749 MI.setDesc(TII->get(UnscaledOp)); 2750 2751 MI.getOperand(ImmIdx).ChangeToImmediate(NewOffset); 2752 return Offset == 0; 2753 } 2754 2755 return false; 2756 } 2757 2758 void AArch64InstrInfo::getNoopForMachoTarget(MCInst &NopInst) const { 2759 NopInst.setOpcode(AArch64::HINT); 2760 NopInst.addOperand(MCOperand::createImm(0)); 2761 } 2762 2763 // AArch64 supports MachineCombiner. 2764 bool AArch64InstrInfo::useMachineCombiner() const { 2765 2766 return true; 2767 } 2768 // 2769 // True when Opc sets flag 2770 static bool isCombineInstrSettingFlag(unsigned Opc) { 2771 switch (Opc) { 2772 case AArch64::ADDSWrr: 2773 case AArch64::ADDSWri: 2774 case AArch64::ADDSXrr: 2775 case AArch64::ADDSXri: 2776 case AArch64::SUBSWrr: 2777 case AArch64::SUBSXrr: 2778 // Note: MSUB Wd,Wn,Wm,Wi -> Wd = Wi - WnxWm, not Wd=WnxWm - Wi. 2779 case AArch64::SUBSWri: 2780 case AArch64::SUBSXri: 2781 return true; 2782 default: 2783 break; 2784 } 2785 return false; 2786 } 2787 // 2788 // 32b Opcodes that can be combined with a MUL 2789 static bool isCombineInstrCandidate32(unsigned Opc) { 2790 switch (Opc) { 2791 case AArch64::ADDWrr: 2792 case AArch64::ADDWri: 2793 case AArch64::SUBWrr: 2794 case AArch64::ADDSWrr: 2795 case AArch64::ADDSWri: 2796 case AArch64::SUBSWrr: 2797 // Note: MSUB Wd,Wn,Wm,Wi -> Wd = Wi - WnxWm, not Wd=WnxWm - Wi. 2798 case AArch64::SUBWri: 2799 case AArch64::SUBSWri: 2800 return true; 2801 default: 2802 break; 2803 } 2804 return false; 2805 } 2806 // 2807 // 64b Opcodes that can be combined with a MUL 2808 static bool isCombineInstrCandidate64(unsigned Opc) { 2809 switch (Opc) { 2810 case AArch64::ADDXrr: 2811 case AArch64::ADDXri: 2812 case AArch64::SUBXrr: 2813 case AArch64::ADDSXrr: 2814 case AArch64::ADDSXri: 2815 case AArch64::SUBSXrr: 2816 // Note: MSUB Wd,Wn,Wm,Wi -> Wd = Wi - WnxWm, not Wd=WnxWm - Wi. 2817 case AArch64::SUBXri: 2818 case AArch64::SUBSXri: 2819 return true; 2820 default: 2821 break; 2822 } 2823 return false; 2824 } 2825 // 2826 // FP Opcodes that can be combined with a FMUL 2827 static bool isCombineInstrCandidateFP(const MachineInstr &Inst) { 2828 switch (Inst.getOpcode()) { 2829 case AArch64::FADDSrr: 2830 case AArch64::FADDDrr: 2831 case AArch64::FADDv2f32: 2832 case AArch64::FADDv2f64: 2833 case AArch64::FADDv4f32: 2834 case AArch64::FSUBSrr: 2835 case AArch64::FSUBDrr: 2836 case AArch64::FSUBv2f32: 2837 case AArch64::FSUBv2f64: 2838 case AArch64::FSUBv4f32: 2839 return Inst.getParent()->getParent()->getTarget().Options.UnsafeFPMath; 2840 default: 2841 break; 2842 } 2843 return false; 2844 } 2845 // 2846 // Opcodes that can be combined with a MUL 2847 static bool isCombineInstrCandidate(unsigned Opc) { 2848 return (isCombineInstrCandidate32(Opc) || isCombineInstrCandidate64(Opc)); 2849 } 2850 2851 // 2852 // Utility routine that checks if \param MO is defined by an 2853 // \param CombineOpc instruction in the basic block \param MBB 2854 static bool canCombine(MachineBasicBlock &MBB, MachineOperand &MO, 2855 unsigned CombineOpc, unsigned ZeroReg = 0, 2856 bool CheckZeroReg = false) { 2857 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 2858 MachineInstr *MI = nullptr; 2859 2860 if (MO.isReg() && TargetRegisterInfo::isVirtualRegister(MO.getReg())) 2861 MI = MRI.getUniqueVRegDef(MO.getReg()); 2862 // And it needs to be in the trace (otherwise, it won't have a depth). 2863 if (!MI || MI->getParent() != &MBB || (unsigned)MI->getOpcode() != CombineOpc) 2864 return false; 2865 // Must only used by the user we combine with. 2866 if (!MRI.hasOneNonDBGUse(MI->getOperand(0).getReg())) 2867 return false; 2868 2869 if (CheckZeroReg) { 2870 assert(MI->getNumOperands() >= 4 && MI->getOperand(0).isReg() && 2871 MI->getOperand(1).isReg() && MI->getOperand(2).isReg() && 2872 MI->getOperand(3).isReg() && "MAdd/MSub must have a least 4 regs"); 2873 // The third input reg must be zero. 2874 if (MI->getOperand(3).getReg() != ZeroReg) 2875 return false; 2876 } 2877 2878 return true; 2879 } 2880 2881 // 2882 // Is \param MO defined by an integer multiply and can be combined? 2883 static bool canCombineWithMUL(MachineBasicBlock &MBB, MachineOperand &MO, 2884 unsigned MulOpc, unsigned ZeroReg) { 2885 return canCombine(MBB, MO, MulOpc, ZeroReg, true); 2886 } 2887 2888 // 2889 // Is \param MO defined by a floating-point multiply and can be combined? 2890 static bool canCombineWithFMUL(MachineBasicBlock &MBB, MachineOperand &MO, 2891 unsigned MulOpc) { 2892 return canCombine(MBB, MO, MulOpc); 2893 } 2894 2895 // TODO: There are many more machine instruction opcodes to match: 2896 // 1. Other data types (integer, vectors) 2897 // 2. Other math / logic operations (xor, or) 2898 // 3. Other forms of the same operation (intrinsics and other variants) 2899 bool AArch64InstrInfo::isAssociativeAndCommutative(const MachineInstr &Inst) const { 2900 switch (Inst.getOpcode()) { 2901 case AArch64::FADDDrr: 2902 case AArch64::FADDSrr: 2903 case AArch64::FADDv2f32: 2904 case AArch64::FADDv2f64: 2905 case AArch64::FADDv4f32: 2906 case AArch64::FMULDrr: 2907 case AArch64::FMULSrr: 2908 case AArch64::FMULX32: 2909 case AArch64::FMULX64: 2910 case AArch64::FMULXv2f32: 2911 case AArch64::FMULXv2f64: 2912 case AArch64::FMULXv4f32: 2913 case AArch64::FMULv2f32: 2914 case AArch64::FMULv2f64: 2915 case AArch64::FMULv4f32: 2916 return Inst.getParent()->getParent()->getTarget().Options.UnsafeFPMath; 2917 default: 2918 return false; 2919 } 2920 } 2921 2922 /// Find instructions that can be turned into madd. 2923 static bool getMaddPatterns(MachineInstr &Root, 2924 SmallVectorImpl<MachineCombinerPattern> &Patterns) { 2925 unsigned Opc = Root.getOpcode(); 2926 MachineBasicBlock &MBB = *Root.getParent(); 2927 bool Found = false; 2928 2929 if (!isCombineInstrCandidate(Opc)) 2930 return false; 2931 if (isCombineInstrSettingFlag(Opc)) { 2932 int Cmp_NZCV = Root.findRegisterDefOperandIdx(AArch64::NZCV, true); 2933 // When NZCV is live bail out. 2934 if (Cmp_NZCV == -1) 2935 return false; 2936 unsigned NewOpc = convertFlagSettingOpcode(&Root); 2937 // When opcode can't change bail out. 2938 // CHECKME: do we miss any cases for opcode conversion? 2939 if (NewOpc == Opc) 2940 return false; 2941 Opc = NewOpc; 2942 } 2943 2944 switch (Opc) { 2945 default: 2946 break; 2947 case AArch64::ADDWrr: 2948 assert(Root.getOperand(1).isReg() && Root.getOperand(2).isReg() && 2949 "ADDWrr does not have register operands"); 2950 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDWrrr, 2951 AArch64::WZR)) { 2952 Patterns.push_back(MachineCombinerPattern::MULADDW_OP1); 2953 Found = true; 2954 } 2955 if (canCombineWithMUL(MBB, Root.getOperand(2), AArch64::MADDWrrr, 2956 AArch64::WZR)) { 2957 Patterns.push_back(MachineCombinerPattern::MULADDW_OP2); 2958 Found = true; 2959 } 2960 break; 2961 case AArch64::ADDXrr: 2962 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDXrrr, 2963 AArch64::XZR)) { 2964 Patterns.push_back(MachineCombinerPattern::MULADDX_OP1); 2965 Found = true; 2966 } 2967 if (canCombineWithMUL(MBB, Root.getOperand(2), AArch64::MADDXrrr, 2968 AArch64::XZR)) { 2969 Patterns.push_back(MachineCombinerPattern::MULADDX_OP2); 2970 Found = true; 2971 } 2972 break; 2973 case AArch64::SUBWrr: 2974 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDWrrr, 2975 AArch64::WZR)) { 2976 Patterns.push_back(MachineCombinerPattern::MULSUBW_OP1); 2977 Found = true; 2978 } 2979 if (canCombineWithMUL(MBB, Root.getOperand(2), AArch64::MADDWrrr, 2980 AArch64::WZR)) { 2981 Patterns.push_back(MachineCombinerPattern::MULSUBW_OP2); 2982 Found = true; 2983 } 2984 break; 2985 case AArch64::SUBXrr: 2986 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDXrrr, 2987 AArch64::XZR)) { 2988 Patterns.push_back(MachineCombinerPattern::MULSUBX_OP1); 2989 Found = true; 2990 } 2991 if (canCombineWithMUL(MBB, Root.getOperand(2), AArch64::MADDXrrr, 2992 AArch64::XZR)) { 2993 Patterns.push_back(MachineCombinerPattern::MULSUBX_OP2); 2994 Found = true; 2995 } 2996 break; 2997 case AArch64::ADDWri: 2998 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDWrrr, 2999 AArch64::WZR)) { 3000 Patterns.push_back(MachineCombinerPattern::MULADDWI_OP1); 3001 Found = true; 3002 } 3003 break; 3004 case AArch64::ADDXri: 3005 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDXrrr, 3006 AArch64::XZR)) { 3007 Patterns.push_back(MachineCombinerPattern::MULADDXI_OP1); 3008 Found = true; 3009 } 3010 break; 3011 case AArch64::SUBWri: 3012 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDWrrr, 3013 AArch64::WZR)) { 3014 Patterns.push_back(MachineCombinerPattern::MULSUBWI_OP1); 3015 Found = true; 3016 } 3017 break; 3018 case AArch64::SUBXri: 3019 if (canCombineWithMUL(MBB, Root.getOperand(1), AArch64::MADDXrrr, 3020 AArch64::XZR)) { 3021 Patterns.push_back(MachineCombinerPattern::MULSUBXI_OP1); 3022 Found = true; 3023 } 3024 break; 3025 } 3026 return Found; 3027 } 3028 /// Floating-Point Support 3029 3030 /// Find instructions that can be turned into madd. 3031 static bool getFMAPatterns(MachineInstr &Root, 3032 SmallVectorImpl<MachineCombinerPattern> &Patterns) { 3033 3034 if (!isCombineInstrCandidateFP(Root)) 3035 return 0; 3036 3037 MachineBasicBlock &MBB = *Root.getParent(); 3038 bool Found = false; 3039 3040 switch (Root.getOpcode()) { 3041 default: 3042 assert(false && "Unsupported FP instruction in combiner\n"); 3043 break; 3044 case AArch64::FADDSrr: 3045 assert(Root.getOperand(1).isReg() && Root.getOperand(2).isReg() && 3046 "FADDWrr does not have register operands"); 3047 if (canCombineWithFMUL(MBB, Root.getOperand(1), AArch64::FMULSrr)) { 3048 Patterns.push_back(MachineCombinerPattern::FMULADDS_OP1); 3049 Found = true; 3050 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3051 AArch64::FMULv1i32_indexed)) { 3052 Patterns.push_back(MachineCombinerPattern::FMLAv1i32_indexed_OP1); 3053 Found = true; 3054 } 3055 if (canCombineWithFMUL(MBB, Root.getOperand(2), AArch64::FMULSrr)) { 3056 Patterns.push_back(MachineCombinerPattern::FMULADDS_OP2); 3057 Found = true; 3058 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3059 AArch64::FMULv1i32_indexed)) { 3060 Patterns.push_back(MachineCombinerPattern::FMLAv1i32_indexed_OP2); 3061 Found = true; 3062 } 3063 break; 3064 case AArch64::FADDDrr: 3065 if (canCombineWithFMUL(MBB, Root.getOperand(1), AArch64::FMULDrr)) { 3066 Patterns.push_back(MachineCombinerPattern::FMULADDD_OP1); 3067 Found = true; 3068 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3069 AArch64::FMULv1i64_indexed)) { 3070 Patterns.push_back(MachineCombinerPattern::FMLAv1i64_indexed_OP1); 3071 Found = true; 3072 } 3073 if (canCombineWithFMUL(MBB, Root.getOperand(2), AArch64::FMULDrr)) { 3074 Patterns.push_back(MachineCombinerPattern::FMULADDD_OP2); 3075 Found = true; 3076 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3077 AArch64::FMULv1i64_indexed)) { 3078 Patterns.push_back(MachineCombinerPattern::FMLAv1i64_indexed_OP2); 3079 Found = true; 3080 } 3081 break; 3082 case AArch64::FADDv2f32: 3083 if (canCombineWithFMUL(MBB, Root.getOperand(1), 3084 AArch64::FMULv2i32_indexed)) { 3085 Patterns.push_back(MachineCombinerPattern::FMLAv2i32_indexed_OP1); 3086 Found = true; 3087 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3088 AArch64::FMULv2f32)) { 3089 Patterns.push_back(MachineCombinerPattern::FMLAv2f32_OP1); 3090 Found = true; 3091 } 3092 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3093 AArch64::FMULv2i32_indexed)) { 3094 Patterns.push_back(MachineCombinerPattern::FMLAv2i32_indexed_OP2); 3095 Found = true; 3096 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3097 AArch64::FMULv2f32)) { 3098 Patterns.push_back(MachineCombinerPattern::FMLAv2f32_OP2); 3099 Found = true; 3100 } 3101 break; 3102 case AArch64::FADDv2f64: 3103 if (canCombineWithFMUL(MBB, Root.getOperand(1), 3104 AArch64::FMULv2i64_indexed)) { 3105 Patterns.push_back(MachineCombinerPattern::FMLAv2i64_indexed_OP1); 3106 Found = true; 3107 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3108 AArch64::FMULv2f64)) { 3109 Patterns.push_back(MachineCombinerPattern::FMLAv2f64_OP1); 3110 Found = true; 3111 } 3112 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3113 AArch64::FMULv2i64_indexed)) { 3114 Patterns.push_back(MachineCombinerPattern::FMLAv2i64_indexed_OP2); 3115 Found = true; 3116 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3117 AArch64::FMULv2f64)) { 3118 Patterns.push_back(MachineCombinerPattern::FMLAv2f64_OP2); 3119 Found = true; 3120 } 3121 break; 3122 case AArch64::FADDv4f32: 3123 if (canCombineWithFMUL(MBB, Root.getOperand(1), 3124 AArch64::FMULv4i32_indexed)) { 3125 Patterns.push_back(MachineCombinerPattern::FMLAv4i32_indexed_OP1); 3126 Found = true; 3127 } else if (canCombineWithFMUL(MBB, Root.getOperand(1), 3128 AArch64::FMULv4f32)) { 3129 Patterns.push_back(MachineCombinerPattern::FMLAv4f32_OP1); 3130 Found = true; 3131 } 3132 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3133 AArch64::FMULv4i32_indexed)) { 3134 Patterns.push_back(MachineCombinerPattern::FMLAv4i32_indexed_OP2); 3135 Found = true; 3136 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3137 AArch64::FMULv4f32)) { 3138 Patterns.push_back(MachineCombinerPattern::FMLAv4f32_OP2); 3139 Found = true; 3140 } 3141 break; 3142 3143 case AArch64::FSUBSrr: 3144 if (canCombineWithFMUL(MBB, Root.getOperand(1), AArch64::FMULSrr)) { 3145 Patterns.push_back(MachineCombinerPattern::FMULSUBS_OP1); 3146 Found = true; 3147 } 3148 if (canCombineWithFMUL(MBB, Root.getOperand(2), AArch64::FMULSrr)) { 3149 Patterns.push_back(MachineCombinerPattern::FMULSUBS_OP2); 3150 Found = true; 3151 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3152 AArch64::FMULv1i32_indexed)) { 3153 Patterns.push_back(MachineCombinerPattern::FMLSv1i32_indexed_OP2); 3154 Found = true; 3155 } 3156 break; 3157 case AArch64::FSUBDrr: 3158 if (canCombineWithFMUL(MBB, Root.getOperand(1), AArch64::FMULDrr)) { 3159 Patterns.push_back(MachineCombinerPattern::FMULSUBD_OP1); 3160 Found = true; 3161 } 3162 if (canCombineWithFMUL(MBB, Root.getOperand(2), AArch64::FMULDrr)) { 3163 Patterns.push_back(MachineCombinerPattern::FMULSUBD_OP2); 3164 Found = true; 3165 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3166 AArch64::FMULv1i64_indexed)) { 3167 Patterns.push_back(MachineCombinerPattern::FMLSv1i64_indexed_OP2); 3168 Found = true; 3169 } 3170 break; 3171 case AArch64::FSUBv2f32: 3172 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3173 AArch64::FMULv2i32_indexed)) { 3174 Patterns.push_back(MachineCombinerPattern::FMLSv2i32_indexed_OP2); 3175 Found = true; 3176 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3177 AArch64::FMULv2f32)) { 3178 Patterns.push_back(MachineCombinerPattern::FMLSv2f32_OP2); 3179 Found = true; 3180 } 3181 break; 3182 case AArch64::FSUBv2f64: 3183 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3184 AArch64::FMULv2i64_indexed)) { 3185 Patterns.push_back(MachineCombinerPattern::FMLSv2i64_indexed_OP2); 3186 Found = true; 3187 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3188 AArch64::FMULv2f64)) { 3189 Patterns.push_back(MachineCombinerPattern::FMLSv2f64_OP2); 3190 Found = true; 3191 } 3192 break; 3193 case AArch64::FSUBv4f32: 3194 if (canCombineWithFMUL(MBB, Root.getOperand(2), 3195 AArch64::FMULv4i32_indexed)) { 3196 Patterns.push_back(MachineCombinerPattern::FMLSv4i32_indexed_OP2); 3197 Found = true; 3198 } else if (canCombineWithFMUL(MBB, Root.getOperand(2), 3199 AArch64::FMULv4f32)) { 3200 Patterns.push_back(MachineCombinerPattern::FMLSv4f32_OP2); 3201 Found = true; 3202 } 3203 break; 3204 } 3205 return Found; 3206 } 3207 3208 /// Return true when a code sequence can improve throughput. It 3209 /// should be called only for instructions in loops. 3210 /// \param Pattern - combiner pattern 3211 bool 3212 AArch64InstrInfo::isThroughputPattern(MachineCombinerPattern Pattern) const { 3213 switch (Pattern) { 3214 default: 3215 break; 3216 case MachineCombinerPattern::FMULADDS_OP1: 3217 case MachineCombinerPattern::FMULADDS_OP2: 3218 case MachineCombinerPattern::FMULSUBS_OP1: 3219 case MachineCombinerPattern::FMULSUBS_OP2: 3220 case MachineCombinerPattern::FMULADDD_OP1: 3221 case MachineCombinerPattern::FMULADDD_OP2: 3222 case MachineCombinerPattern::FMULSUBD_OP1: 3223 case MachineCombinerPattern::FMULSUBD_OP2: 3224 case MachineCombinerPattern::FMLAv1i32_indexed_OP1: 3225 case MachineCombinerPattern::FMLAv1i32_indexed_OP2: 3226 case MachineCombinerPattern::FMLAv1i64_indexed_OP1: 3227 case MachineCombinerPattern::FMLAv1i64_indexed_OP2: 3228 case MachineCombinerPattern::FMLAv2f32_OP2: 3229 case MachineCombinerPattern::FMLAv2f32_OP1: 3230 case MachineCombinerPattern::FMLAv2f64_OP1: 3231 case MachineCombinerPattern::FMLAv2f64_OP2: 3232 case MachineCombinerPattern::FMLAv2i32_indexed_OP1: 3233 case MachineCombinerPattern::FMLAv2i32_indexed_OP2: 3234 case MachineCombinerPattern::FMLAv2i64_indexed_OP1: 3235 case MachineCombinerPattern::FMLAv2i64_indexed_OP2: 3236 case MachineCombinerPattern::FMLAv4f32_OP1: 3237 case MachineCombinerPattern::FMLAv4f32_OP2: 3238 case MachineCombinerPattern::FMLAv4i32_indexed_OP1: 3239 case MachineCombinerPattern::FMLAv4i32_indexed_OP2: 3240 case MachineCombinerPattern::FMLSv1i32_indexed_OP2: 3241 case MachineCombinerPattern::FMLSv1i64_indexed_OP2: 3242 case MachineCombinerPattern::FMLSv2i32_indexed_OP2: 3243 case MachineCombinerPattern::FMLSv2i64_indexed_OP2: 3244 case MachineCombinerPattern::FMLSv2f32_OP2: 3245 case MachineCombinerPattern::FMLSv2f64_OP2: 3246 case MachineCombinerPattern::FMLSv4i32_indexed_OP2: 3247 case MachineCombinerPattern::FMLSv4f32_OP2: 3248 return true; 3249 } // end switch (Pattern) 3250 return false; 3251 } 3252 /// Return true when there is potentially a faster code sequence for an 3253 /// instruction chain ending in \p Root. All potential patterns are listed in 3254 /// the \p Pattern vector. Pattern should be sorted in priority order since the 3255 /// pattern evaluator stops checking as soon as it finds a faster sequence. 3256 3257 bool AArch64InstrInfo::getMachineCombinerPatterns( 3258 MachineInstr &Root, 3259 SmallVectorImpl<MachineCombinerPattern> &Patterns) const { 3260 // Integer patterns 3261 if (getMaddPatterns(Root, Patterns)) 3262 return true; 3263 // Floating point patterns 3264 if (getFMAPatterns(Root, Patterns)) 3265 return true; 3266 3267 return TargetInstrInfo::getMachineCombinerPatterns(Root, Patterns); 3268 } 3269 3270 enum class FMAInstKind { Default, Indexed, Accumulator }; 3271 /// genFusedMultiply - Generate fused multiply instructions. 3272 /// This function supports both integer and floating point instructions. 3273 /// A typical example: 3274 /// F|MUL I=A,B,0 3275 /// F|ADD R,I,C 3276 /// ==> F|MADD R,A,B,C 3277 /// \param Root is the F|ADD instruction 3278 /// \param [out] InsInstrs is a vector of machine instructions and will 3279 /// contain the generated madd instruction 3280 /// \param IdxMulOpd is index of operand in Root that is the result of 3281 /// the F|MUL. In the example above IdxMulOpd is 1. 3282 /// \param MaddOpc the opcode fo the f|madd instruction 3283 static MachineInstr * 3284 genFusedMultiply(MachineFunction &MF, MachineRegisterInfo &MRI, 3285 const TargetInstrInfo *TII, MachineInstr &Root, 3286 SmallVectorImpl<MachineInstr *> &InsInstrs, unsigned IdxMulOpd, 3287 unsigned MaddOpc, const TargetRegisterClass *RC, 3288 FMAInstKind kind = FMAInstKind::Default) { 3289 assert(IdxMulOpd == 1 || IdxMulOpd == 2); 3290 3291 unsigned IdxOtherOpd = IdxMulOpd == 1 ? 2 : 1; 3292 MachineInstr *MUL = MRI.getUniqueVRegDef(Root.getOperand(IdxMulOpd).getReg()); 3293 unsigned ResultReg = Root.getOperand(0).getReg(); 3294 unsigned SrcReg0 = MUL->getOperand(1).getReg(); 3295 bool Src0IsKill = MUL->getOperand(1).isKill(); 3296 unsigned SrcReg1 = MUL->getOperand(2).getReg(); 3297 bool Src1IsKill = MUL->getOperand(2).isKill(); 3298 unsigned SrcReg2 = Root.getOperand(IdxOtherOpd).getReg(); 3299 bool Src2IsKill = Root.getOperand(IdxOtherOpd).isKill(); 3300 3301 if (TargetRegisterInfo::isVirtualRegister(ResultReg)) 3302 MRI.constrainRegClass(ResultReg, RC); 3303 if (TargetRegisterInfo::isVirtualRegister(SrcReg0)) 3304 MRI.constrainRegClass(SrcReg0, RC); 3305 if (TargetRegisterInfo::isVirtualRegister(SrcReg1)) 3306 MRI.constrainRegClass(SrcReg1, RC); 3307 if (TargetRegisterInfo::isVirtualRegister(SrcReg2)) 3308 MRI.constrainRegClass(SrcReg2, RC); 3309 3310 MachineInstrBuilder MIB; 3311 if (kind == FMAInstKind::Default) 3312 MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 3313 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 3314 .addReg(SrcReg1, getKillRegState(Src1IsKill)) 3315 .addReg(SrcReg2, getKillRegState(Src2IsKill)); 3316 else if (kind == FMAInstKind::Indexed) 3317 MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 3318 .addReg(SrcReg2, getKillRegState(Src2IsKill)) 3319 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 3320 .addReg(SrcReg1, getKillRegState(Src1IsKill)) 3321 .addImm(MUL->getOperand(3).getImm()); 3322 else if (kind == FMAInstKind::Accumulator) 3323 MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), ResultReg) 3324 .addReg(SrcReg2, getKillRegState(Src2IsKill)) 3325 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 3326 .addReg(SrcReg1, getKillRegState(Src1IsKill)); 3327 else 3328 assert(false && "Invalid FMA instruction kind \n"); 3329 // Insert the MADD (MADD, FMA, FMS, FMLA, FMSL) 3330 InsInstrs.push_back(MIB); 3331 return MUL; 3332 } 3333 3334 /// genMaddR - Generate madd instruction and combine mul and add using 3335 /// an extra virtual register 3336 /// Example - an ADD intermediate needs to be stored in a register: 3337 /// MUL I=A,B,0 3338 /// ADD R,I,Imm 3339 /// ==> ORR V, ZR, Imm 3340 /// ==> MADD R,A,B,V 3341 /// \param Root is the ADD instruction 3342 /// \param [out] InsInstrs is a vector of machine instructions and will 3343 /// contain the generated madd instruction 3344 /// \param IdxMulOpd is index of operand in Root that is the result of 3345 /// the MUL. In the example above IdxMulOpd is 1. 3346 /// \param MaddOpc the opcode fo the madd instruction 3347 /// \param VR is a virtual register that holds the value of an ADD operand 3348 /// (V in the example above). 3349 static MachineInstr *genMaddR(MachineFunction &MF, MachineRegisterInfo &MRI, 3350 const TargetInstrInfo *TII, MachineInstr &Root, 3351 SmallVectorImpl<MachineInstr *> &InsInstrs, 3352 unsigned IdxMulOpd, unsigned MaddOpc, 3353 unsigned VR, const TargetRegisterClass *RC) { 3354 assert(IdxMulOpd == 1 || IdxMulOpd == 2); 3355 3356 MachineInstr *MUL = MRI.getUniqueVRegDef(Root.getOperand(IdxMulOpd).getReg()); 3357 unsigned ResultReg = Root.getOperand(0).getReg(); 3358 unsigned SrcReg0 = MUL->getOperand(1).getReg(); 3359 bool Src0IsKill = MUL->getOperand(1).isKill(); 3360 unsigned SrcReg1 = MUL->getOperand(2).getReg(); 3361 bool Src1IsKill = MUL->getOperand(2).isKill(); 3362 3363 if (TargetRegisterInfo::isVirtualRegister(ResultReg)) 3364 MRI.constrainRegClass(ResultReg, RC); 3365 if (TargetRegisterInfo::isVirtualRegister(SrcReg0)) 3366 MRI.constrainRegClass(SrcReg0, RC); 3367 if (TargetRegisterInfo::isVirtualRegister(SrcReg1)) 3368 MRI.constrainRegClass(SrcReg1, RC); 3369 if (TargetRegisterInfo::isVirtualRegister(VR)) 3370 MRI.constrainRegClass(VR, RC); 3371 3372 MachineInstrBuilder MIB = BuildMI(MF, Root.getDebugLoc(), TII->get(MaddOpc), 3373 ResultReg) 3374 .addReg(SrcReg0, getKillRegState(Src0IsKill)) 3375 .addReg(SrcReg1, getKillRegState(Src1IsKill)) 3376 .addReg(VR); 3377 // Insert the MADD 3378 InsInstrs.push_back(MIB); 3379 return MUL; 3380 } 3381 3382 /// When getMachineCombinerPatterns() finds potential patterns, 3383 /// this function generates the instructions that could replace the 3384 /// original code sequence 3385 void AArch64InstrInfo::genAlternativeCodeSequence( 3386 MachineInstr &Root, MachineCombinerPattern Pattern, 3387 SmallVectorImpl<MachineInstr *> &InsInstrs, 3388 SmallVectorImpl<MachineInstr *> &DelInstrs, 3389 DenseMap<unsigned, unsigned> &InstrIdxForVirtReg) const { 3390 MachineBasicBlock &MBB = *Root.getParent(); 3391 MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo(); 3392 MachineFunction &MF = *MBB.getParent(); 3393 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 3394 3395 MachineInstr *MUL; 3396 const TargetRegisterClass *RC; 3397 unsigned Opc; 3398 switch (Pattern) { 3399 default: 3400 // Reassociate instructions. 3401 TargetInstrInfo::genAlternativeCodeSequence(Root, Pattern, InsInstrs, 3402 DelInstrs, InstrIdxForVirtReg); 3403 return; 3404 case MachineCombinerPattern::MULADDW_OP1: 3405 case MachineCombinerPattern::MULADDX_OP1: 3406 // MUL I=A,B,0 3407 // ADD R,I,C 3408 // ==> MADD R,A,B,C 3409 // --- Create(MADD); 3410 if (Pattern == MachineCombinerPattern::MULADDW_OP1) { 3411 Opc = AArch64::MADDWrrr; 3412 RC = &AArch64::GPR32RegClass; 3413 } else { 3414 Opc = AArch64::MADDXrrr; 3415 RC = &AArch64::GPR64RegClass; 3416 } 3417 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 3418 break; 3419 case MachineCombinerPattern::MULADDW_OP2: 3420 case MachineCombinerPattern::MULADDX_OP2: 3421 // MUL I=A,B,0 3422 // ADD R,C,I 3423 // ==> MADD R,A,B,C 3424 // --- Create(MADD); 3425 if (Pattern == MachineCombinerPattern::MULADDW_OP2) { 3426 Opc = AArch64::MADDWrrr; 3427 RC = &AArch64::GPR32RegClass; 3428 } else { 3429 Opc = AArch64::MADDXrrr; 3430 RC = &AArch64::GPR64RegClass; 3431 } 3432 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 3433 break; 3434 case MachineCombinerPattern::MULADDWI_OP1: 3435 case MachineCombinerPattern::MULADDXI_OP1: { 3436 // MUL I=A,B,0 3437 // ADD R,I,Imm 3438 // ==> ORR V, ZR, Imm 3439 // ==> MADD R,A,B,V 3440 // --- Create(MADD); 3441 const TargetRegisterClass *OrrRC; 3442 unsigned BitSize, OrrOpc, ZeroReg; 3443 if (Pattern == MachineCombinerPattern::MULADDWI_OP1) { 3444 OrrOpc = AArch64::ORRWri; 3445 OrrRC = &AArch64::GPR32spRegClass; 3446 BitSize = 32; 3447 ZeroReg = AArch64::WZR; 3448 Opc = AArch64::MADDWrrr; 3449 RC = &AArch64::GPR32RegClass; 3450 } else { 3451 OrrOpc = AArch64::ORRXri; 3452 OrrRC = &AArch64::GPR64spRegClass; 3453 BitSize = 64; 3454 ZeroReg = AArch64::XZR; 3455 Opc = AArch64::MADDXrrr; 3456 RC = &AArch64::GPR64RegClass; 3457 } 3458 unsigned NewVR = MRI.createVirtualRegister(OrrRC); 3459 uint64_t Imm = Root.getOperand(2).getImm(); 3460 3461 if (Root.getOperand(3).isImm()) { 3462 unsigned Val = Root.getOperand(3).getImm(); 3463 Imm = Imm << Val; 3464 } 3465 uint64_t UImm = Imm << (64 - BitSize) >> (64 - BitSize); 3466 uint64_t Encoding; 3467 if (AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding)) { 3468 MachineInstrBuilder MIB1 = 3469 BuildMI(MF, Root.getDebugLoc(), TII->get(OrrOpc), NewVR) 3470 .addReg(ZeroReg) 3471 .addImm(Encoding); 3472 InsInstrs.push_back(MIB1); 3473 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 3474 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC); 3475 } 3476 break; 3477 } 3478 case MachineCombinerPattern::MULSUBW_OP1: 3479 case MachineCombinerPattern::MULSUBX_OP1: { 3480 // MUL I=A,B,0 3481 // SUB R,I, C 3482 // ==> SUB V, 0, C 3483 // ==> MADD R,A,B,V // = -C + A*B 3484 // --- Create(MADD); 3485 const TargetRegisterClass *SubRC; 3486 unsigned SubOpc, ZeroReg; 3487 if (Pattern == MachineCombinerPattern::MULSUBW_OP1) { 3488 SubOpc = AArch64::SUBWrr; 3489 SubRC = &AArch64::GPR32spRegClass; 3490 ZeroReg = AArch64::WZR; 3491 Opc = AArch64::MADDWrrr; 3492 RC = &AArch64::GPR32RegClass; 3493 } else { 3494 SubOpc = AArch64::SUBXrr; 3495 SubRC = &AArch64::GPR64spRegClass; 3496 ZeroReg = AArch64::XZR; 3497 Opc = AArch64::MADDXrrr; 3498 RC = &AArch64::GPR64RegClass; 3499 } 3500 unsigned NewVR = MRI.createVirtualRegister(SubRC); 3501 // SUB NewVR, 0, C 3502 MachineInstrBuilder MIB1 = 3503 BuildMI(MF, Root.getDebugLoc(), TII->get(SubOpc), NewVR) 3504 .addReg(ZeroReg) 3505 .addOperand(Root.getOperand(2)); 3506 InsInstrs.push_back(MIB1); 3507 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 3508 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC); 3509 break; 3510 } 3511 case MachineCombinerPattern::MULSUBW_OP2: 3512 case MachineCombinerPattern::MULSUBX_OP2: 3513 // MUL I=A,B,0 3514 // SUB R,C,I 3515 // ==> MSUB R,A,B,C (computes C - A*B) 3516 // --- Create(MSUB); 3517 if (Pattern == MachineCombinerPattern::MULSUBW_OP2) { 3518 Opc = AArch64::MSUBWrrr; 3519 RC = &AArch64::GPR32RegClass; 3520 } else { 3521 Opc = AArch64::MSUBXrrr; 3522 RC = &AArch64::GPR64RegClass; 3523 } 3524 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 3525 break; 3526 case MachineCombinerPattern::MULSUBWI_OP1: 3527 case MachineCombinerPattern::MULSUBXI_OP1: { 3528 // MUL I=A,B,0 3529 // SUB R,I, Imm 3530 // ==> ORR V, ZR, -Imm 3531 // ==> MADD R,A,B,V // = -Imm + A*B 3532 // --- Create(MADD); 3533 const TargetRegisterClass *OrrRC; 3534 unsigned BitSize, OrrOpc, ZeroReg; 3535 if (Pattern == MachineCombinerPattern::MULSUBWI_OP1) { 3536 OrrOpc = AArch64::ORRWri; 3537 OrrRC = &AArch64::GPR32spRegClass; 3538 BitSize = 32; 3539 ZeroReg = AArch64::WZR; 3540 Opc = AArch64::MADDWrrr; 3541 RC = &AArch64::GPR32RegClass; 3542 } else { 3543 OrrOpc = AArch64::ORRXri; 3544 OrrRC = &AArch64::GPR64spRegClass; 3545 BitSize = 64; 3546 ZeroReg = AArch64::XZR; 3547 Opc = AArch64::MADDXrrr; 3548 RC = &AArch64::GPR64RegClass; 3549 } 3550 unsigned NewVR = MRI.createVirtualRegister(OrrRC); 3551 int Imm = Root.getOperand(2).getImm(); 3552 if (Root.getOperand(3).isImm()) { 3553 unsigned Val = Root.getOperand(3).getImm(); 3554 Imm = Imm << Val; 3555 } 3556 uint64_t UImm = -Imm << (64 - BitSize) >> (64 - BitSize); 3557 uint64_t Encoding; 3558 if (AArch64_AM::processLogicalImmediate(UImm, BitSize, Encoding)) { 3559 MachineInstrBuilder MIB1 = 3560 BuildMI(MF, Root.getDebugLoc(), TII->get(OrrOpc), NewVR) 3561 .addReg(ZeroReg) 3562 .addImm(Encoding); 3563 InsInstrs.push_back(MIB1); 3564 InstrIdxForVirtReg.insert(std::make_pair(NewVR, 0)); 3565 MUL = genMaddR(MF, MRI, TII, Root, InsInstrs, 1, Opc, NewVR, RC); 3566 } 3567 break; 3568 } 3569 // Floating Point Support 3570 case MachineCombinerPattern::FMULADDS_OP1: 3571 case MachineCombinerPattern::FMULADDD_OP1: 3572 // MUL I=A,B,0 3573 // ADD R,I,C 3574 // ==> MADD R,A,B,C 3575 // --- Create(MADD); 3576 if (Pattern == MachineCombinerPattern::FMULADDS_OP1) { 3577 Opc = AArch64::FMADDSrrr; 3578 RC = &AArch64::FPR32RegClass; 3579 } else { 3580 Opc = AArch64::FMADDDrrr; 3581 RC = &AArch64::FPR64RegClass; 3582 } 3583 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 3584 break; 3585 case MachineCombinerPattern::FMULADDS_OP2: 3586 case MachineCombinerPattern::FMULADDD_OP2: 3587 // FMUL I=A,B,0 3588 // FADD R,C,I 3589 // ==> FMADD R,A,B,C 3590 // --- Create(FMADD); 3591 if (Pattern == MachineCombinerPattern::FMULADDS_OP2) { 3592 Opc = AArch64::FMADDSrrr; 3593 RC = &AArch64::FPR32RegClass; 3594 } else { 3595 Opc = AArch64::FMADDDrrr; 3596 RC = &AArch64::FPR64RegClass; 3597 } 3598 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 3599 break; 3600 3601 case MachineCombinerPattern::FMLAv1i32_indexed_OP1: 3602 Opc = AArch64::FMLAv1i32_indexed; 3603 RC = &AArch64::FPR32RegClass; 3604 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 3605 FMAInstKind::Indexed); 3606 break; 3607 case MachineCombinerPattern::FMLAv1i32_indexed_OP2: 3608 Opc = AArch64::FMLAv1i32_indexed; 3609 RC = &AArch64::FPR32RegClass; 3610 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3611 FMAInstKind::Indexed); 3612 break; 3613 3614 case MachineCombinerPattern::FMLAv1i64_indexed_OP1: 3615 Opc = AArch64::FMLAv1i64_indexed; 3616 RC = &AArch64::FPR64RegClass; 3617 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 3618 FMAInstKind::Indexed); 3619 break; 3620 case MachineCombinerPattern::FMLAv1i64_indexed_OP2: 3621 Opc = AArch64::FMLAv1i64_indexed; 3622 RC = &AArch64::FPR64RegClass; 3623 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3624 FMAInstKind::Indexed); 3625 break; 3626 3627 case MachineCombinerPattern::FMLAv2i32_indexed_OP1: 3628 case MachineCombinerPattern::FMLAv2f32_OP1: 3629 RC = &AArch64::FPR64RegClass; 3630 if (Pattern == MachineCombinerPattern::FMLAv2i32_indexed_OP1) { 3631 Opc = AArch64::FMLAv2i32_indexed; 3632 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 3633 FMAInstKind::Indexed); 3634 } else { 3635 Opc = AArch64::FMLAv2f32; 3636 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 3637 FMAInstKind::Accumulator); 3638 } 3639 break; 3640 case MachineCombinerPattern::FMLAv2i32_indexed_OP2: 3641 case MachineCombinerPattern::FMLAv2f32_OP2: 3642 RC = &AArch64::FPR64RegClass; 3643 if (Pattern == MachineCombinerPattern::FMLAv2i32_indexed_OP2) { 3644 Opc = AArch64::FMLAv2i32_indexed; 3645 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3646 FMAInstKind::Indexed); 3647 } else { 3648 Opc = AArch64::FMLAv2f32; 3649 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3650 FMAInstKind::Accumulator); 3651 } 3652 break; 3653 3654 case MachineCombinerPattern::FMLAv2i64_indexed_OP1: 3655 case MachineCombinerPattern::FMLAv2f64_OP1: 3656 RC = &AArch64::FPR128RegClass; 3657 if (Pattern == MachineCombinerPattern::FMLAv2i64_indexed_OP1) { 3658 Opc = AArch64::FMLAv2i64_indexed; 3659 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 3660 FMAInstKind::Indexed); 3661 } else { 3662 Opc = AArch64::FMLAv2f64; 3663 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 3664 FMAInstKind::Accumulator); 3665 } 3666 break; 3667 case MachineCombinerPattern::FMLAv2i64_indexed_OP2: 3668 case MachineCombinerPattern::FMLAv2f64_OP2: 3669 RC = &AArch64::FPR128RegClass; 3670 if (Pattern == MachineCombinerPattern::FMLAv2i64_indexed_OP2) { 3671 Opc = AArch64::FMLAv2i64_indexed; 3672 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3673 FMAInstKind::Indexed); 3674 } else { 3675 Opc = AArch64::FMLAv2f64; 3676 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3677 FMAInstKind::Accumulator); 3678 } 3679 break; 3680 3681 case MachineCombinerPattern::FMLAv4i32_indexed_OP1: 3682 case MachineCombinerPattern::FMLAv4f32_OP1: 3683 RC = &AArch64::FPR128RegClass; 3684 if (Pattern == MachineCombinerPattern::FMLAv4i32_indexed_OP1) { 3685 Opc = AArch64::FMLAv4i32_indexed; 3686 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 3687 FMAInstKind::Indexed); 3688 } else { 3689 Opc = AArch64::FMLAv4f32; 3690 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC, 3691 FMAInstKind::Accumulator); 3692 } 3693 break; 3694 3695 case MachineCombinerPattern::FMLAv4i32_indexed_OP2: 3696 case MachineCombinerPattern::FMLAv4f32_OP2: 3697 RC = &AArch64::FPR128RegClass; 3698 if (Pattern == MachineCombinerPattern::FMLAv4i32_indexed_OP2) { 3699 Opc = AArch64::FMLAv4i32_indexed; 3700 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3701 FMAInstKind::Indexed); 3702 } else { 3703 Opc = AArch64::FMLAv4f32; 3704 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3705 FMAInstKind::Accumulator); 3706 } 3707 break; 3708 3709 case MachineCombinerPattern::FMULSUBS_OP1: 3710 case MachineCombinerPattern::FMULSUBD_OP1: { 3711 // FMUL I=A,B,0 3712 // FSUB R,I,C 3713 // ==> FNMSUB R,A,B,C // = -C + A*B 3714 // --- Create(FNMSUB); 3715 if (Pattern == MachineCombinerPattern::FMULSUBS_OP1) { 3716 Opc = AArch64::FNMSUBSrrr; 3717 RC = &AArch64::FPR32RegClass; 3718 } else { 3719 Opc = AArch64::FNMSUBDrrr; 3720 RC = &AArch64::FPR64RegClass; 3721 } 3722 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 1, Opc, RC); 3723 break; 3724 } 3725 case MachineCombinerPattern::FMULSUBS_OP2: 3726 case MachineCombinerPattern::FMULSUBD_OP2: { 3727 // FMUL I=A,B,0 3728 // FSUB R,C,I 3729 // ==> FMSUB R,A,B,C (computes C - A*B) 3730 // --- Create(FMSUB); 3731 if (Pattern == MachineCombinerPattern::FMULSUBS_OP2) { 3732 Opc = AArch64::FMSUBSrrr; 3733 RC = &AArch64::FPR32RegClass; 3734 } else { 3735 Opc = AArch64::FMSUBDrrr; 3736 RC = &AArch64::FPR64RegClass; 3737 } 3738 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC); 3739 break; 3740 3741 case MachineCombinerPattern::FMLSv1i32_indexed_OP2: 3742 Opc = AArch64::FMLSv1i32_indexed; 3743 RC = &AArch64::FPR32RegClass; 3744 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3745 FMAInstKind::Indexed); 3746 break; 3747 3748 case MachineCombinerPattern::FMLSv1i64_indexed_OP2: 3749 Opc = AArch64::FMLSv1i64_indexed; 3750 RC = &AArch64::FPR64RegClass; 3751 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3752 FMAInstKind::Indexed); 3753 break; 3754 3755 case MachineCombinerPattern::FMLSv2f32_OP2: 3756 case MachineCombinerPattern::FMLSv2i32_indexed_OP2: 3757 RC = &AArch64::FPR64RegClass; 3758 if (Pattern == MachineCombinerPattern::FMLSv2i32_indexed_OP2) { 3759 Opc = AArch64::FMLSv2i32_indexed; 3760 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3761 FMAInstKind::Indexed); 3762 } else { 3763 Opc = AArch64::FMLSv2f32; 3764 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3765 FMAInstKind::Accumulator); 3766 } 3767 break; 3768 3769 case MachineCombinerPattern::FMLSv2f64_OP2: 3770 case MachineCombinerPattern::FMLSv2i64_indexed_OP2: 3771 RC = &AArch64::FPR128RegClass; 3772 if (Pattern == MachineCombinerPattern::FMLSv2i64_indexed_OP2) { 3773 Opc = AArch64::FMLSv2i64_indexed; 3774 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3775 FMAInstKind::Indexed); 3776 } else { 3777 Opc = AArch64::FMLSv2f64; 3778 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3779 FMAInstKind::Accumulator); 3780 } 3781 break; 3782 3783 case MachineCombinerPattern::FMLSv4f32_OP2: 3784 case MachineCombinerPattern::FMLSv4i32_indexed_OP2: 3785 RC = &AArch64::FPR128RegClass; 3786 if (Pattern == MachineCombinerPattern::FMLSv4i32_indexed_OP2) { 3787 Opc = AArch64::FMLSv4i32_indexed; 3788 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3789 FMAInstKind::Indexed); 3790 } else { 3791 Opc = AArch64::FMLSv4f32; 3792 MUL = genFusedMultiply(MF, MRI, TII, Root, InsInstrs, 2, Opc, RC, 3793 FMAInstKind::Accumulator); 3794 } 3795 break; 3796 } 3797 } // end switch (Pattern) 3798 // Record MUL and ADD/SUB for deletion 3799 DelInstrs.push_back(MUL); 3800 DelInstrs.push_back(&Root); 3801 3802 return; 3803 } 3804 3805 /// \brief Replace csincr-branch sequence by simple conditional branch 3806 /// 3807 /// Examples: 3808 /// 1. 3809 /// csinc w9, wzr, wzr, <condition code> 3810 /// tbnz w9, #0, 0x44 3811 /// to 3812 /// b.<inverted condition code> 3813 /// 3814 /// 2. 3815 /// csinc w9, wzr, wzr, <condition code> 3816 /// tbz w9, #0, 0x44 3817 /// to 3818 /// b.<condition code> 3819 /// 3820 /// Replace compare and branch sequence by TBZ/TBNZ instruction when the 3821 /// compare's constant operand is power of 2. 3822 /// 3823 /// Examples: 3824 /// and w8, w8, #0x400 3825 /// cbnz w8, L1 3826 /// to 3827 /// tbnz w8, #10, L1 3828 /// 3829 /// \param MI Conditional Branch 3830 /// \return True when the simple conditional branch is generated 3831 /// 3832 bool AArch64InstrInfo::optimizeCondBranch(MachineInstr *MI) const { 3833 bool IsNegativeBranch = false; 3834 bool IsTestAndBranch = false; 3835 unsigned TargetBBInMI = 0; 3836 switch (MI->getOpcode()) { 3837 default: 3838 llvm_unreachable("Unknown branch instruction?"); 3839 case AArch64::Bcc: 3840 return false; 3841 case AArch64::CBZW: 3842 case AArch64::CBZX: 3843 TargetBBInMI = 1; 3844 break; 3845 case AArch64::CBNZW: 3846 case AArch64::CBNZX: 3847 TargetBBInMI = 1; 3848 IsNegativeBranch = true; 3849 break; 3850 case AArch64::TBZW: 3851 case AArch64::TBZX: 3852 TargetBBInMI = 2; 3853 IsTestAndBranch = true; 3854 break; 3855 case AArch64::TBNZW: 3856 case AArch64::TBNZX: 3857 TargetBBInMI = 2; 3858 IsNegativeBranch = true; 3859 IsTestAndBranch = true; 3860 break; 3861 } 3862 // So we increment a zero register and test for bits other 3863 // than bit 0? Conservatively bail out in case the verifier 3864 // missed this case. 3865 if (IsTestAndBranch && MI->getOperand(1).getImm()) 3866 return false; 3867 3868 // Find Definition. 3869 assert(MI->getParent() && "Incomplete machine instruciton\n"); 3870 MachineBasicBlock *MBB = MI->getParent(); 3871 MachineFunction *MF = MBB->getParent(); 3872 MachineRegisterInfo *MRI = &MF->getRegInfo(); 3873 unsigned VReg = MI->getOperand(0).getReg(); 3874 if (!TargetRegisterInfo::isVirtualRegister(VReg)) 3875 return false; 3876 3877 MachineInstr *DefMI = MRI->getVRegDef(VReg); 3878 3879 // Look through COPY instructions to find definition. 3880 while (DefMI->isCopy()) { 3881 unsigned CopyVReg = DefMI->getOperand(1).getReg(); 3882 if (!MRI->hasOneNonDBGUse(CopyVReg)) 3883 return false; 3884 if (!MRI->hasOneDef(CopyVReg)) 3885 return false; 3886 DefMI = MRI->getVRegDef(CopyVReg); 3887 } 3888 3889 switch (DefMI->getOpcode()) { 3890 default: 3891 return false; 3892 // Fold AND into a TBZ/TBNZ if constant operand is power of 2. 3893 case AArch64::ANDWri: 3894 case AArch64::ANDXri: { 3895 if (IsTestAndBranch) 3896 return false; 3897 if (DefMI->getParent() != MBB) 3898 return false; 3899 if (!MRI->hasOneNonDBGUse(VReg)) 3900 return false; 3901 3902 bool Is32Bit = (DefMI->getOpcode() == AArch64::ANDWri); 3903 uint64_t Mask = AArch64_AM::decodeLogicalImmediate( 3904 DefMI->getOperand(2).getImm(), Is32Bit ? 32 : 64); 3905 if (!isPowerOf2_64(Mask)) 3906 return false; 3907 3908 MachineOperand &MO = DefMI->getOperand(1); 3909 unsigned NewReg = MO.getReg(); 3910 if (!TargetRegisterInfo::isVirtualRegister(NewReg)) 3911 return false; 3912 3913 assert(!MRI->def_empty(NewReg) && "Register must be defined."); 3914 3915 MachineBasicBlock &RefToMBB = *MBB; 3916 MachineBasicBlock *TBB = MI->getOperand(1).getMBB(); 3917 DebugLoc DL = MI->getDebugLoc(); 3918 unsigned Imm = Log2_64(Mask); 3919 unsigned Opc = (Imm < 32) 3920 ? (IsNegativeBranch ? AArch64::TBNZW : AArch64::TBZW) 3921 : (IsNegativeBranch ? AArch64::TBNZX : AArch64::TBZX); 3922 MachineInstr *NewMI = BuildMI(RefToMBB, MI, DL, get(Opc)) 3923 .addReg(NewReg) 3924 .addImm(Imm) 3925 .addMBB(TBB); 3926 // Register lives on to the CBZ now. 3927 MO.setIsKill(false); 3928 3929 // For immediate smaller than 32, we need to use the 32-bit 3930 // variant (W) in all cases. Indeed the 64-bit variant does not 3931 // allow to encode them. 3932 // Therefore, if the input register is 64-bit, we need to take the 3933 // 32-bit sub-part. 3934 if (!Is32Bit && Imm < 32) 3935 NewMI->getOperand(0).setSubReg(AArch64::sub_32); 3936 MI->eraseFromParent(); 3937 return true; 3938 } 3939 // Look for CSINC 3940 case AArch64::CSINCWr: 3941 case AArch64::CSINCXr: { 3942 if (!(DefMI->getOperand(1).getReg() == AArch64::WZR && 3943 DefMI->getOperand(2).getReg() == AArch64::WZR) && 3944 !(DefMI->getOperand(1).getReg() == AArch64::XZR && 3945 DefMI->getOperand(2).getReg() == AArch64::XZR)) 3946 return false; 3947 3948 if (DefMI->findRegisterDefOperandIdx(AArch64::NZCV, true) != -1) 3949 return false; 3950 3951 AArch64CC::CondCode CC = (AArch64CC::CondCode)DefMI->getOperand(3).getImm(); 3952 // Convert only when the condition code is not modified between 3953 // the CSINC and the branch. The CC may be used by other 3954 // instructions in between. 3955 if (areCFlagsAccessedBetweenInstrs(DefMI, MI, &getRegisterInfo(), AK_Write)) 3956 return false; 3957 MachineBasicBlock &RefToMBB = *MBB; 3958 MachineBasicBlock *TBB = MI->getOperand(TargetBBInMI).getMBB(); 3959 DebugLoc DL = MI->getDebugLoc(); 3960 if (IsNegativeBranch) 3961 CC = AArch64CC::getInvertedCondCode(CC); 3962 BuildMI(RefToMBB, MI, DL, get(AArch64::Bcc)).addImm(CC).addMBB(TBB); 3963 MI->eraseFromParent(); 3964 return true; 3965 } 3966 } 3967 } 3968 3969 std::pair<unsigned, unsigned> 3970 AArch64InstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const { 3971 const unsigned Mask = AArch64II::MO_FRAGMENT; 3972 return std::make_pair(TF & Mask, TF & ~Mask); 3973 } 3974 3975 ArrayRef<std::pair<unsigned, const char *>> 3976 AArch64InstrInfo::getSerializableDirectMachineOperandTargetFlags() const { 3977 using namespace AArch64II; 3978 static const std::pair<unsigned, const char *> TargetFlags[] = { 3979 {MO_PAGE, "aarch64-page"}, 3980 {MO_PAGEOFF, "aarch64-pageoff"}, 3981 {MO_G3, "aarch64-g3"}, 3982 {MO_G2, "aarch64-g2"}, 3983 {MO_G1, "aarch64-g1"}, 3984 {MO_G0, "aarch64-g0"}, 3985 {MO_HI12, "aarch64-hi12"}}; 3986 return makeArrayRef(TargetFlags); 3987 } 3988 3989 ArrayRef<std::pair<unsigned, const char *>> 3990 AArch64InstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const { 3991 using namespace AArch64II; 3992 static const std::pair<unsigned, const char *> TargetFlags[] = { 3993 {MO_GOT, "aarch64-got"}, 3994 {MO_NC, "aarch64-nc"}, 3995 {MO_TLS, "aarch64-tls"}, 3996 {MO_CONSTPOOL, "aarch64-constant-pool"}}; 3997 return makeArrayRef(TargetFlags); 3998 } 3999