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