1 //===- AArch64InstructionSelector.cpp ----------------------------*- C++ -*-==// 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 /// \file 10 /// This file implements the targeting of the InstructionSelector class for 11 /// AArch64. 12 /// \todo This should be generated by TableGen. 13 //===----------------------------------------------------------------------===// 14 15 #include "AArch64InstrInfo.h" 16 #include "AArch64MachineFunctionInfo.h" 17 #include "AArch64RegisterBankInfo.h" 18 #include "AArch64RegisterInfo.h" 19 #include "AArch64Subtarget.h" 20 #include "AArch64TargetMachine.h" 21 #include "MCTargetDesc/AArch64AddressingModes.h" 22 #include "llvm/CodeGen/GlobalISel/InstructionSelector.h" 23 #include "llvm/CodeGen/GlobalISel/InstructionSelectorImpl.h" 24 #include "llvm/CodeGen/GlobalISel/Utils.h" 25 #include "llvm/CodeGen/MachineBasicBlock.h" 26 #include "llvm/CodeGen/MachineFunction.h" 27 #include "llvm/CodeGen/MachineInstr.h" 28 #include "llvm/CodeGen/MachineInstrBuilder.h" 29 #include "llvm/CodeGen/MachineOperand.h" 30 #include "llvm/CodeGen/MachineRegisterInfo.h" 31 #include "llvm/IR/Type.h" 32 #include "llvm/Support/Debug.h" 33 #include "llvm/Support/raw_ostream.h" 34 35 #define DEBUG_TYPE "aarch64-isel" 36 37 using namespace llvm; 38 39 namespace { 40 41 #define GET_GLOBALISEL_PREDICATE_BITSET 42 #include "AArch64GenGlobalISel.inc" 43 #undef GET_GLOBALISEL_PREDICATE_BITSET 44 45 class AArch64InstructionSelector : public InstructionSelector { 46 public: 47 AArch64InstructionSelector(const AArch64TargetMachine &TM, 48 const AArch64Subtarget &STI, 49 const AArch64RegisterBankInfo &RBI); 50 51 bool select(MachineInstr &I, CodeGenCoverage &CoverageInfo) const override; 52 static const char *getName() { return DEBUG_TYPE; } 53 54 private: 55 /// tblgen-erated 'select' implementation, used as the initial selector for 56 /// the patterns that don't require complex C++. 57 bool selectImpl(MachineInstr &I, CodeGenCoverage &CoverageInfo) const; 58 59 bool selectVaStartAAPCS(MachineInstr &I, MachineFunction &MF, 60 MachineRegisterInfo &MRI) const; 61 bool selectVaStartDarwin(MachineInstr &I, MachineFunction &MF, 62 MachineRegisterInfo &MRI) const; 63 64 bool selectCompareBranch(MachineInstr &I, MachineFunction &MF, 65 MachineRegisterInfo &MRI) const; 66 67 ComplexRendererFns selectArithImmed(MachineOperand &Root) const; 68 69 ComplexRendererFns selectAddrModeUnscaled(MachineOperand &Root, 70 unsigned Size) const; 71 72 ComplexRendererFns selectAddrModeUnscaled8(MachineOperand &Root) const { 73 return selectAddrModeUnscaled(Root, 1); 74 } 75 ComplexRendererFns selectAddrModeUnscaled16(MachineOperand &Root) const { 76 return selectAddrModeUnscaled(Root, 2); 77 } 78 ComplexRendererFns selectAddrModeUnscaled32(MachineOperand &Root) const { 79 return selectAddrModeUnscaled(Root, 4); 80 } 81 ComplexRendererFns selectAddrModeUnscaled64(MachineOperand &Root) const { 82 return selectAddrModeUnscaled(Root, 8); 83 } 84 ComplexRendererFns selectAddrModeUnscaled128(MachineOperand &Root) const { 85 return selectAddrModeUnscaled(Root, 16); 86 } 87 88 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root, 89 unsigned Size) const; 90 template <int Width> 91 ComplexRendererFns selectAddrModeIndexed(MachineOperand &Root) const { 92 return selectAddrModeIndexed(Root, Width / 8); 93 } 94 95 const AArch64TargetMachine &TM; 96 const AArch64Subtarget &STI; 97 const AArch64InstrInfo &TII; 98 const AArch64RegisterInfo &TRI; 99 const AArch64RegisterBankInfo &RBI; 100 101 #define GET_GLOBALISEL_PREDICATES_DECL 102 #include "AArch64GenGlobalISel.inc" 103 #undef GET_GLOBALISEL_PREDICATES_DECL 104 105 // We declare the temporaries used by selectImpl() in the class to minimize the 106 // cost of constructing placeholder values. 107 #define GET_GLOBALISEL_TEMPORARIES_DECL 108 #include "AArch64GenGlobalISel.inc" 109 #undef GET_GLOBALISEL_TEMPORARIES_DECL 110 }; 111 112 } // end anonymous namespace 113 114 #define GET_GLOBALISEL_IMPL 115 #include "AArch64GenGlobalISel.inc" 116 #undef GET_GLOBALISEL_IMPL 117 118 AArch64InstructionSelector::AArch64InstructionSelector( 119 const AArch64TargetMachine &TM, const AArch64Subtarget &STI, 120 const AArch64RegisterBankInfo &RBI) 121 : InstructionSelector(), TM(TM), STI(STI), TII(*STI.getInstrInfo()), 122 TRI(*STI.getRegisterInfo()), RBI(RBI), 123 #define GET_GLOBALISEL_PREDICATES_INIT 124 #include "AArch64GenGlobalISel.inc" 125 #undef GET_GLOBALISEL_PREDICATES_INIT 126 #define GET_GLOBALISEL_TEMPORARIES_INIT 127 #include "AArch64GenGlobalISel.inc" 128 #undef GET_GLOBALISEL_TEMPORARIES_INIT 129 { 130 } 131 132 // FIXME: This should be target-independent, inferred from the types declared 133 // for each class in the bank. 134 static const TargetRegisterClass * 135 getRegClassForTypeOnBank(LLT Ty, const RegisterBank &RB, 136 const RegisterBankInfo &RBI, 137 bool GetAllRegSet = false) { 138 if (RB.getID() == AArch64::GPRRegBankID) { 139 if (Ty.getSizeInBits() <= 32) 140 return GetAllRegSet ? &AArch64::GPR32allRegClass 141 : &AArch64::GPR32RegClass; 142 if (Ty.getSizeInBits() == 64) 143 return GetAllRegSet ? &AArch64::GPR64allRegClass 144 : &AArch64::GPR64RegClass; 145 return nullptr; 146 } 147 148 if (RB.getID() == AArch64::FPRRegBankID) { 149 if (Ty.getSizeInBits() <= 16) 150 return &AArch64::FPR16RegClass; 151 if (Ty.getSizeInBits() == 32) 152 return &AArch64::FPR32RegClass; 153 if (Ty.getSizeInBits() == 64) 154 return &AArch64::FPR64RegClass; 155 if (Ty.getSizeInBits() == 128) 156 return &AArch64::FPR128RegClass; 157 return nullptr; 158 } 159 160 return nullptr; 161 } 162 163 /// Check whether \p I is a currently unsupported binary operation: 164 /// - it has an unsized type 165 /// - an operand is not a vreg 166 /// - all operands are not in the same bank 167 /// These are checks that should someday live in the verifier, but right now, 168 /// these are mostly limitations of the aarch64 selector. 169 static bool unsupportedBinOp(const MachineInstr &I, 170 const AArch64RegisterBankInfo &RBI, 171 const MachineRegisterInfo &MRI, 172 const AArch64RegisterInfo &TRI) { 173 LLT Ty = MRI.getType(I.getOperand(0).getReg()); 174 if (!Ty.isValid()) { 175 DEBUG(dbgs() << "Generic binop register should be typed\n"); 176 return true; 177 } 178 179 const RegisterBank *PrevOpBank = nullptr; 180 for (auto &MO : I.operands()) { 181 // FIXME: Support non-register operands. 182 if (!MO.isReg()) { 183 DEBUG(dbgs() << "Generic inst non-reg operands are unsupported\n"); 184 return true; 185 } 186 187 // FIXME: Can generic operations have physical registers operands? If 188 // so, this will need to be taught about that, and we'll need to get the 189 // bank out of the minimal class for the register. 190 // Either way, this needs to be documented (and possibly verified). 191 if (!TargetRegisterInfo::isVirtualRegister(MO.getReg())) { 192 DEBUG(dbgs() << "Generic inst has physical register operand\n"); 193 return true; 194 } 195 196 const RegisterBank *OpBank = RBI.getRegBank(MO.getReg(), MRI, TRI); 197 if (!OpBank) { 198 DEBUG(dbgs() << "Generic register has no bank or class\n"); 199 return true; 200 } 201 202 if (PrevOpBank && OpBank != PrevOpBank) { 203 DEBUG(dbgs() << "Generic inst operands have different banks\n"); 204 return true; 205 } 206 PrevOpBank = OpBank; 207 } 208 return false; 209 } 210 211 /// Select the AArch64 opcode for the basic binary operation \p GenericOpc 212 /// (such as G_OR or G_SDIV), appropriate for the register bank \p RegBankID 213 /// and of size \p OpSize. 214 /// \returns \p GenericOpc if the combination is unsupported. 215 static unsigned selectBinaryOp(unsigned GenericOpc, unsigned RegBankID, 216 unsigned OpSize) { 217 switch (RegBankID) { 218 case AArch64::GPRRegBankID: 219 if (OpSize == 32) { 220 switch (GenericOpc) { 221 case TargetOpcode::G_SHL: 222 return AArch64::LSLVWr; 223 case TargetOpcode::G_LSHR: 224 return AArch64::LSRVWr; 225 case TargetOpcode::G_ASHR: 226 return AArch64::ASRVWr; 227 default: 228 return GenericOpc; 229 } 230 } else if (OpSize == 64) { 231 switch (GenericOpc) { 232 case TargetOpcode::G_GEP: 233 return AArch64::ADDXrr; 234 case TargetOpcode::G_SHL: 235 return AArch64::LSLVXr; 236 case TargetOpcode::G_LSHR: 237 return AArch64::LSRVXr; 238 case TargetOpcode::G_ASHR: 239 return AArch64::ASRVXr; 240 default: 241 return GenericOpc; 242 } 243 } 244 break; 245 case AArch64::FPRRegBankID: 246 switch (OpSize) { 247 case 32: 248 switch (GenericOpc) { 249 case TargetOpcode::G_FADD: 250 return AArch64::FADDSrr; 251 case TargetOpcode::G_FSUB: 252 return AArch64::FSUBSrr; 253 case TargetOpcode::G_FMUL: 254 return AArch64::FMULSrr; 255 case TargetOpcode::G_FDIV: 256 return AArch64::FDIVSrr; 257 default: 258 return GenericOpc; 259 } 260 case 64: 261 switch (GenericOpc) { 262 case TargetOpcode::G_FADD: 263 return AArch64::FADDDrr; 264 case TargetOpcode::G_FSUB: 265 return AArch64::FSUBDrr; 266 case TargetOpcode::G_FMUL: 267 return AArch64::FMULDrr; 268 case TargetOpcode::G_FDIV: 269 return AArch64::FDIVDrr; 270 case TargetOpcode::G_OR: 271 return AArch64::ORRv8i8; 272 default: 273 return GenericOpc; 274 } 275 } 276 break; 277 } 278 return GenericOpc; 279 } 280 281 /// Select the AArch64 opcode for the G_LOAD or G_STORE operation \p GenericOpc, 282 /// appropriate for the (value) register bank \p RegBankID and of memory access 283 /// size \p OpSize. This returns the variant with the base+unsigned-immediate 284 /// addressing mode (e.g., LDRXui). 285 /// \returns \p GenericOpc if the combination is unsupported. 286 static unsigned selectLoadStoreUIOp(unsigned GenericOpc, unsigned RegBankID, 287 unsigned OpSize) { 288 const bool isStore = GenericOpc == TargetOpcode::G_STORE; 289 switch (RegBankID) { 290 case AArch64::GPRRegBankID: 291 switch (OpSize) { 292 case 8: 293 return isStore ? AArch64::STRBBui : AArch64::LDRBBui; 294 case 16: 295 return isStore ? AArch64::STRHHui : AArch64::LDRHHui; 296 case 32: 297 return isStore ? AArch64::STRWui : AArch64::LDRWui; 298 case 64: 299 return isStore ? AArch64::STRXui : AArch64::LDRXui; 300 } 301 break; 302 case AArch64::FPRRegBankID: 303 switch (OpSize) { 304 case 8: 305 return isStore ? AArch64::STRBui : AArch64::LDRBui; 306 case 16: 307 return isStore ? AArch64::STRHui : AArch64::LDRHui; 308 case 32: 309 return isStore ? AArch64::STRSui : AArch64::LDRSui; 310 case 64: 311 return isStore ? AArch64::STRDui : AArch64::LDRDui; 312 } 313 break; 314 } 315 return GenericOpc; 316 } 317 318 static bool selectFP16CopyFromGPR32(MachineInstr &I, const TargetInstrInfo &TII, 319 MachineRegisterInfo &MRI, unsigned SrcReg) { 320 // Copies from gpr32 to fpr16 need to use a sub-register copy. 321 unsigned CopyReg = MRI.createVirtualRegister(&AArch64::FPR32RegClass); 322 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::COPY)) 323 .addDef(CopyReg) 324 .addUse(SrcReg); 325 unsigned SubRegCopy = MRI.createVirtualRegister(&AArch64::FPR16RegClass); 326 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(TargetOpcode::COPY)) 327 .addDef(SubRegCopy) 328 .addUse(CopyReg, 0, AArch64::hsub); 329 330 MachineOperand &RegOp = I.getOperand(1); 331 RegOp.setReg(SubRegCopy); 332 return true; 333 } 334 335 static bool selectCopy(MachineInstr &I, const TargetInstrInfo &TII, 336 MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, 337 const RegisterBankInfo &RBI) { 338 339 unsigned DstReg = I.getOperand(0).getReg(); 340 unsigned SrcReg = I.getOperand(1).getReg(); 341 342 if (TargetRegisterInfo::isPhysicalRegister(DstReg)) { 343 if (TRI.getRegClass(AArch64::FPR16RegClassID)->contains(DstReg) && 344 !TargetRegisterInfo::isPhysicalRegister(SrcReg)) { 345 const RegisterBank &RegBank = *RBI.getRegBank(SrcReg, MRI, TRI); 346 const TargetRegisterClass *SrcRC = getRegClassForTypeOnBank( 347 MRI.getType(SrcReg), RegBank, RBI, /* GetAllRegSet */ true); 348 if (SrcRC == &AArch64::GPR32allRegClass) 349 return selectFP16CopyFromGPR32(I, TII, MRI, SrcReg); 350 } 351 assert(I.isCopy() && "Generic operators do not allow physical registers"); 352 return true; 353 } 354 355 const RegisterBank &RegBank = *RBI.getRegBank(DstReg, MRI, TRI); 356 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); 357 (void)DstSize; 358 const unsigned SrcSize = RBI.getSizeInBits(SrcReg, MRI, TRI); 359 (void)SrcSize; 360 assert((!TargetRegisterInfo::isPhysicalRegister(SrcReg) || I.isCopy()) && 361 "No phys reg on generic operators"); 362 assert( 363 (DstSize == SrcSize || 364 // Copies are a mean to setup initial types, the number of 365 // bits may not exactly match. 366 (TargetRegisterInfo::isPhysicalRegister(SrcReg) && 367 DstSize <= RBI.getSizeInBits(SrcReg, MRI, TRI)) || 368 // Copies are a mean to copy bits around, as long as we are 369 // on the same register class, that's fine. Otherwise, that 370 // means we need some SUBREG_TO_REG or AND & co. 371 (((DstSize + 31) / 32 == (SrcSize + 31) / 32) && DstSize > SrcSize)) && 372 "Copy with different width?!"); 373 assert((DstSize <= 64 || RegBank.getID() == AArch64::FPRRegBankID) && 374 "GPRs cannot get more than 64-bit width values"); 375 376 const TargetRegisterClass *RC = getRegClassForTypeOnBank( 377 MRI.getType(DstReg), RegBank, RBI, /* GetAllRegSet */ true); 378 if (!RC) { 379 DEBUG(dbgs() << "Unexpected bitcast size " << DstSize << '\n'); 380 return false; 381 } 382 383 if (!TargetRegisterInfo::isPhysicalRegister(SrcReg)) { 384 const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(SrcReg); 385 const TargetRegisterClass *SrcRC = 386 RegClassOrBank.dyn_cast<const TargetRegisterClass *>(); 387 const RegisterBank *RB = nullptr; 388 if (!SrcRC) { 389 RB = RegClassOrBank.get<const RegisterBank *>(); 390 SrcRC = getRegClassForTypeOnBank(MRI.getType(SrcReg), *RB, RBI, true); 391 } 392 // Copies from fpr16 to gpr32 need to use SUBREG_TO_REG. 393 if (RC == &AArch64::GPR32allRegClass && SrcRC == &AArch64::FPR16RegClass) { 394 unsigned PromoteReg = MRI.createVirtualRegister(&AArch64::FPR32RegClass); 395 BuildMI(*I.getParent(), I, I.getDebugLoc(), 396 TII.get(AArch64::SUBREG_TO_REG)) 397 .addDef(PromoteReg) 398 .addImm(0) 399 .addUse(SrcReg) 400 .addImm(AArch64::hsub); 401 MachineOperand &RegOp = I.getOperand(1); 402 RegOp.setReg(PromoteReg); 403 } else if (RC == &AArch64::FPR16RegClass && 404 SrcRC == &AArch64::GPR32allRegClass) { 405 selectFP16CopyFromGPR32(I, TII, MRI, SrcReg); 406 } 407 } 408 409 // No need to constrain SrcReg. It will get constrained when 410 // we hit another of its use or its defs. 411 // Copies do not have constraints. 412 if (!RBI.constrainGenericRegister(DstReg, *RC, MRI)) { 413 DEBUG(dbgs() << "Failed to constrain " << TII.getName(I.getOpcode()) 414 << " operand\n"); 415 return false; 416 } 417 I.setDesc(TII.get(AArch64::COPY)); 418 return true; 419 } 420 421 static unsigned selectFPConvOpc(unsigned GenericOpc, LLT DstTy, LLT SrcTy) { 422 if (!DstTy.isScalar() || !SrcTy.isScalar()) 423 return GenericOpc; 424 425 const unsigned DstSize = DstTy.getSizeInBits(); 426 const unsigned SrcSize = SrcTy.getSizeInBits(); 427 428 switch (DstSize) { 429 case 32: 430 switch (SrcSize) { 431 case 32: 432 switch (GenericOpc) { 433 case TargetOpcode::G_SITOFP: 434 return AArch64::SCVTFUWSri; 435 case TargetOpcode::G_UITOFP: 436 return AArch64::UCVTFUWSri; 437 case TargetOpcode::G_FPTOSI: 438 return AArch64::FCVTZSUWSr; 439 case TargetOpcode::G_FPTOUI: 440 return AArch64::FCVTZUUWSr; 441 default: 442 return GenericOpc; 443 } 444 case 64: 445 switch (GenericOpc) { 446 case TargetOpcode::G_SITOFP: 447 return AArch64::SCVTFUXSri; 448 case TargetOpcode::G_UITOFP: 449 return AArch64::UCVTFUXSri; 450 case TargetOpcode::G_FPTOSI: 451 return AArch64::FCVTZSUWDr; 452 case TargetOpcode::G_FPTOUI: 453 return AArch64::FCVTZUUWDr; 454 default: 455 return GenericOpc; 456 } 457 default: 458 return GenericOpc; 459 } 460 case 64: 461 switch (SrcSize) { 462 case 32: 463 switch (GenericOpc) { 464 case TargetOpcode::G_SITOFP: 465 return AArch64::SCVTFUWDri; 466 case TargetOpcode::G_UITOFP: 467 return AArch64::UCVTFUWDri; 468 case TargetOpcode::G_FPTOSI: 469 return AArch64::FCVTZSUXSr; 470 case TargetOpcode::G_FPTOUI: 471 return AArch64::FCVTZUUXSr; 472 default: 473 return GenericOpc; 474 } 475 case 64: 476 switch (GenericOpc) { 477 case TargetOpcode::G_SITOFP: 478 return AArch64::SCVTFUXDri; 479 case TargetOpcode::G_UITOFP: 480 return AArch64::UCVTFUXDri; 481 case TargetOpcode::G_FPTOSI: 482 return AArch64::FCVTZSUXDr; 483 case TargetOpcode::G_FPTOUI: 484 return AArch64::FCVTZUUXDr; 485 default: 486 return GenericOpc; 487 } 488 default: 489 return GenericOpc; 490 } 491 default: 492 return GenericOpc; 493 }; 494 return GenericOpc; 495 } 496 497 static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) { 498 switch (P) { 499 default: 500 llvm_unreachable("Unknown condition code!"); 501 case CmpInst::ICMP_NE: 502 return AArch64CC::NE; 503 case CmpInst::ICMP_EQ: 504 return AArch64CC::EQ; 505 case CmpInst::ICMP_SGT: 506 return AArch64CC::GT; 507 case CmpInst::ICMP_SGE: 508 return AArch64CC::GE; 509 case CmpInst::ICMP_SLT: 510 return AArch64CC::LT; 511 case CmpInst::ICMP_SLE: 512 return AArch64CC::LE; 513 case CmpInst::ICMP_UGT: 514 return AArch64CC::HI; 515 case CmpInst::ICMP_UGE: 516 return AArch64CC::HS; 517 case CmpInst::ICMP_ULT: 518 return AArch64CC::LO; 519 case CmpInst::ICMP_ULE: 520 return AArch64CC::LS; 521 } 522 } 523 524 static void changeFCMPPredToAArch64CC(CmpInst::Predicate P, 525 AArch64CC::CondCode &CondCode, 526 AArch64CC::CondCode &CondCode2) { 527 CondCode2 = AArch64CC::AL; 528 switch (P) { 529 default: 530 llvm_unreachable("Unknown FP condition!"); 531 case CmpInst::FCMP_OEQ: 532 CondCode = AArch64CC::EQ; 533 break; 534 case CmpInst::FCMP_OGT: 535 CondCode = AArch64CC::GT; 536 break; 537 case CmpInst::FCMP_OGE: 538 CondCode = AArch64CC::GE; 539 break; 540 case CmpInst::FCMP_OLT: 541 CondCode = AArch64CC::MI; 542 break; 543 case CmpInst::FCMP_OLE: 544 CondCode = AArch64CC::LS; 545 break; 546 case CmpInst::FCMP_ONE: 547 CondCode = AArch64CC::MI; 548 CondCode2 = AArch64CC::GT; 549 break; 550 case CmpInst::FCMP_ORD: 551 CondCode = AArch64CC::VC; 552 break; 553 case CmpInst::FCMP_UNO: 554 CondCode = AArch64CC::VS; 555 break; 556 case CmpInst::FCMP_UEQ: 557 CondCode = AArch64CC::EQ; 558 CondCode2 = AArch64CC::VS; 559 break; 560 case CmpInst::FCMP_UGT: 561 CondCode = AArch64CC::HI; 562 break; 563 case CmpInst::FCMP_UGE: 564 CondCode = AArch64CC::PL; 565 break; 566 case CmpInst::FCMP_ULT: 567 CondCode = AArch64CC::LT; 568 break; 569 case CmpInst::FCMP_ULE: 570 CondCode = AArch64CC::LE; 571 break; 572 case CmpInst::FCMP_UNE: 573 CondCode = AArch64CC::NE; 574 break; 575 } 576 } 577 578 bool AArch64InstructionSelector::selectCompareBranch( 579 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const { 580 581 const unsigned CondReg = I.getOperand(0).getReg(); 582 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB(); 583 MachineInstr *CCMI = MRI.getVRegDef(CondReg); 584 if (CCMI->getOpcode() == TargetOpcode::G_TRUNC) 585 CCMI = MRI.getVRegDef(CCMI->getOperand(1).getReg()); 586 if (CCMI->getOpcode() != TargetOpcode::G_ICMP) 587 return false; 588 589 unsigned LHS = CCMI->getOperand(2).getReg(); 590 unsigned RHS = CCMI->getOperand(3).getReg(); 591 if (!getConstantVRegVal(RHS, MRI)) 592 std::swap(RHS, LHS); 593 594 const auto RHSImm = getConstantVRegVal(RHS, MRI); 595 if (!RHSImm || *RHSImm != 0) 596 return false; 597 598 const RegisterBank &RB = *RBI.getRegBank(LHS, MRI, TRI); 599 if (RB.getID() != AArch64::GPRRegBankID) 600 return false; 601 602 const auto Pred = (CmpInst::Predicate)CCMI->getOperand(1).getPredicate(); 603 if (Pred != CmpInst::ICMP_NE && Pred != CmpInst::ICMP_EQ) 604 return false; 605 606 const unsigned CmpWidth = MRI.getType(LHS).getSizeInBits(); 607 unsigned CBOpc = 0; 608 if (CmpWidth <= 32) 609 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZW : AArch64::CBNZW); 610 else if (CmpWidth == 64) 611 CBOpc = (Pred == CmpInst::ICMP_EQ ? AArch64::CBZX : AArch64::CBNZX); 612 else 613 return false; 614 615 auto MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(CBOpc)) 616 .addUse(LHS) 617 .addMBB(DestMBB); 618 619 constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI); 620 I.eraseFromParent(); 621 return true; 622 } 623 624 bool AArch64InstructionSelector::selectVaStartAAPCS( 625 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const { 626 return false; 627 } 628 629 bool AArch64InstructionSelector::selectVaStartDarwin( 630 MachineInstr &I, MachineFunction &MF, MachineRegisterInfo &MRI) const { 631 AArch64FunctionInfo *FuncInfo = MF.getInfo<AArch64FunctionInfo>(); 632 unsigned ListReg = I.getOperand(0).getReg(); 633 634 unsigned ArgsAddrReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass); 635 636 auto MIB = 637 BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::ADDXri)) 638 .addDef(ArgsAddrReg) 639 .addFrameIndex(FuncInfo->getVarArgsStackIndex()) 640 .addImm(0) 641 .addImm(0); 642 643 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); 644 645 MIB = BuildMI(*I.getParent(), I, I.getDebugLoc(), TII.get(AArch64::STRXui)) 646 .addUse(ArgsAddrReg) 647 .addUse(ListReg) 648 .addImm(0) 649 .addMemOperand(*I.memoperands_begin()); 650 651 constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI); 652 I.eraseFromParent(); 653 return true; 654 } 655 656 bool AArch64InstructionSelector::select(MachineInstr &I, 657 CodeGenCoverage &CoverageInfo) const { 658 assert(I.getParent() && "Instruction should be in a basic block!"); 659 assert(I.getParent()->getParent() && "Instruction should be in a function!"); 660 661 MachineBasicBlock &MBB = *I.getParent(); 662 MachineFunction &MF = *MBB.getParent(); 663 MachineRegisterInfo &MRI = MF.getRegInfo(); 664 665 unsigned Opcode = I.getOpcode(); 666 // G_PHI requires same handling as PHI 667 if (!isPreISelGenericOpcode(Opcode) || Opcode == TargetOpcode::G_PHI) { 668 // Certain non-generic instructions also need some special handling. 669 670 if (Opcode == TargetOpcode::LOAD_STACK_GUARD) 671 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 672 673 if (Opcode == TargetOpcode::PHI || Opcode == TargetOpcode::G_PHI) { 674 const unsigned DefReg = I.getOperand(0).getReg(); 675 const LLT DefTy = MRI.getType(DefReg); 676 677 const TargetRegisterClass *DefRC = nullptr; 678 if (TargetRegisterInfo::isPhysicalRegister(DefReg)) { 679 DefRC = TRI.getRegClass(DefReg); 680 } else { 681 const RegClassOrRegBank &RegClassOrBank = 682 MRI.getRegClassOrRegBank(DefReg); 683 684 DefRC = RegClassOrBank.dyn_cast<const TargetRegisterClass *>(); 685 if (!DefRC) { 686 if (!DefTy.isValid()) { 687 DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n"); 688 return false; 689 } 690 const RegisterBank &RB = *RegClassOrBank.get<const RegisterBank *>(); 691 DefRC = getRegClassForTypeOnBank(DefTy, RB, RBI); 692 if (!DefRC) { 693 DEBUG(dbgs() << "PHI operand has unexpected size/bank\n"); 694 return false; 695 } 696 } 697 } 698 I.setDesc(TII.get(TargetOpcode::PHI)); 699 700 return RBI.constrainGenericRegister(DefReg, *DefRC, MRI); 701 } 702 703 if (I.isCopy()) 704 return selectCopy(I, TII, MRI, TRI, RBI); 705 706 return true; 707 } 708 709 710 if (I.getNumOperands() != I.getNumExplicitOperands()) { 711 DEBUG(dbgs() << "Generic instruction has unexpected implicit operands\n"); 712 return false; 713 } 714 715 if (selectImpl(I, CoverageInfo)) 716 return true; 717 718 LLT Ty = 719 I.getOperand(0).isReg() ? MRI.getType(I.getOperand(0).getReg()) : LLT{}; 720 721 switch (Opcode) { 722 case TargetOpcode::G_BRCOND: { 723 if (Ty.getSizeInBits() > 32) { 724 // We shouldn't need this on AArch64, but it would be implemented as an 725 // EXTRACT_SUBREG followed by a TBNZW because TBNZX has no encoding if the 726 // bit being tested is < 32. 727 DEBUG(dbgs() << "G_BRCOND has type: " << Ty 728 << ", expected at most 32-bits"); 729 return false; 730 } 731 732 const unsigned CondReg = I.getOperand(0).getReg(); 733 MachineBasicBlock *DestMBB = I.getOperand(1).getMBB(); 734 735 if (selectCompareBranch(I, MF, MRI)) 736 return true; 737 738 auto MIB = BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::TBNZW)) 739 .addUse(CondReg) 740 .addImm(/*bit offset=*/0) 741 .addMBB(DestMBB); 742 743 I.eraseFromParent(); 744 return constrainSelectedInstRegOperands(*MIB.getInstr(), TII, TRI, RBI); 745 } 746 747 case TargetOpcode::G_BRINDIRECT: { 748 I.setDesc(TII.get(AArch64::BR)); 749 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 750 } 751 752 case TargetOpcode::G_FCONSTANT: 753 case TargetOpcode::G_CONSTANT: { 754 const bool isFP = Opcode == TargetOpcode::G_FCONSTANT; 755 756 const LLT s32 = LLT::scalar(32); 757 const LLT s64 = LLT::scalar(64); 758 const LLT p0 = LLT::pointer(0, 64); 759 760 const unsigned DefReg = I.getOperand(0).getReg(); 761 const LLT DefTy = MRI.getType(DefReg); 762 const unsigned DefSize = DefTy.getSizeInBits(); 763 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); 764 765 // FIXME: Redundant check, but even less readable when factored out. 766 if (isFP) { 767 if (Ty != s32 && Ty != s64) { 768 DEBUG(dbgs() << "Unable to materialize FP " << Ty 769 << " constant, expected: " << s32 << " or " << s64 770 << '\n'); 771 return false; 772 } 773 774 if (RB.getID() != AArch64::FPRRegBankID) { 775 DEBUG(dbgs() << "Unable to materialize FP " << Ty 776 << " constant on bank: " << RB << ", expected: FPR\n"); 777 return false; 778 } 779 780 // The case when we have 0.0 is covered by tablegen. Reject it here so we 781 // can be sure tablegen works correctly and isn't rescued by this code. 782 if (I.getOperand(1).getFPImm()->getValueAPF().isExactlyValue(0.0)) 783 return false; 784 } else { 785 // s32 and s64 are covered by tablegen. 786 if (Ty != p0) { 787 DEBUG(dbgs() << "Unable to materialize integer " << Ty 788 << " constant, expected: " << s32 << ", " << s64 << ", or " 789 << p0 << '\n'); 790 return false; 791 } 792 793 if (RB.getID() != AArch64::GPRRegBankID) { 794 DEBUG(dbgs() << "Unable to materialize integer " << Ty 795 << " constant on bank: " << RB << ", expected: GPR\n"); 796 return false; 797 } 798 } 799 800 const unsigned MovOpc = 801 DefSize == 32 ? AArch64::MOVi32imm : AArch64::MOVi64imm; 802 803 I.setDesc(TII.get(MovOpc)); 804 805 if (isFP) { 806 const TargetRegisterClass &GPRRC = 807 DefSize == 32 ? AArch64::GPR32RegClass : AArch64::GPR64RegClass; 808 const TargetRegisterClass &FPRRC = 809 DefSize == 32 ? AArch64::FPR32RegClass : AArch64::FPR64RegClass; 810 811 const unsigned DefGPRReg = MRI.createVirtualRegister(&GPRRC); 812 MachineOperand &RegOp = I.getOperand(0); 813 RegOp.setReg(DefGPRReg); 814 815 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(), 816 TII.get(AArch64::COPY)) 817 .addDef(DefReg) 818 .addUse(DefGPRReg); 819 820 if (!RBI.constrainGenericRegister(DefReg, FPRRC, MRI)) { 821 DEBUG(dbgs() << "Failed to constrain G_FCONSTANT def operand\n"); 822 return false; 823 } 824 825 MachineOperand &ImmOp = I.getOperand(1); 826 // FIXME: Is going through int64_t always correct? 827 ImmOp.ChangeToImmediate( 828 ImmOp.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue()); 829 } else if (I.getOperand(1).isCImm()) { 830 uint64_t Val = I.getOperand(1).getCImm()->getZExtValue(); 831 I.getOperand(1).ChangeToImmediate(Val); 832 } else if (I.getOperand(1).isImm()) { 833 uint64_t Val = I.getOperand(1).getImm(); 834 I.getOperand(1).ChangeToImmediate(Val); 835 } 836 837 constrainSelectedInstRegOperands(I, TII, TRI, RBI); 838 return true; 839 } 840 case TargetOpcode::G_EXTRACT: { 841 LLT SrcTy = MRI.getType(I.getOperand(1).getReg()); 842 LLT DstTy = MRI.getType(I.getOperand(0).getReg()); 843 unsigned SrcSize = SrcTy.getSizeInBits(); 844 // Larger extracts are vectors, same-size extracts should be something else 845 // by now (either split up or simplified to a COPY). 846 if (SrcTy.getSizeInBits() > 64 || Ty.getSizeInBits() > 32) 847 return false; 848 849 I.setDesc(TII.get(SrcSize == 64 ? AArch64::UBFMXri : AArch64::UBFMWri)); 850 MachineInstrBuilder(MF, I).addImm(I.getOperand(2).getImm() + 851 Ty.getSizeInBits() - 1); 852 853 if (SrcSize < 64) { 854 assert(SrcSize == 32 && DstTy.getSizeInBits() == 16 && 855 "unexpected G_EXTRACT types"); 856 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 857 } 858 859 unsigned DstReg = MRI.createGenericVirtualRegister(LLT::scalar(64)); 860 BuildMI(MBB, std::next(I.getIterator()), I.getDebugLoc(), 861 TII.get(AArch64::COPY)) 862 .addDef(I.getOperand(0).getReg()) 863 .addUse(DstReg, 0, AArch64::sub_32); 864 RBI.constrainGenericRegister(I.getOperand(0).getReg(), 865 AArch64::GPR32RegClass, MRI); 866 I.getOperand(0).setReg(DstReg); 867 868 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 869 } 870 871 case TargetOpcode::G_INSERT: { 872 LLT SrcTy = MRI.getType(I.getOperand(2).getReg()); 873 LLT DstTy = MRI.getType(I.getOperand(0).getReg()); 874 unsigned DstSize = DstTy.getSizeInBits(); 875 (void)DstSize; 876 // Larger inserts are vectors, same-size ones should be something else by 877 // now (split up or turned into COPYs). 878 if (Ty.getSizeInBits() > 64 || SrcTy.getSizeInBits() > 32) 879 return false; 880 881 I.setDesc(TII.get(DstSize == 64 ? AArch64::BFMXri : AArch64::BFMWri)); 882 unsigned LSB = I.getOperand(3).getImm(); 883 unsigned Width = MRI.getType(I.getOperand(2).getReg()).getSizeInBits(); 884 I.getOperand(3).setImm((DstSize - LSB) % DstSize); 885 MachineInstrBuilder(MF, I).addImm(Width - 1); 886 887 if (DstSize < 64) { 888 assert(DstSize == 32 && SrcTy.getSizeInBits() == 16 && 889 "unexpected G_INSERT types"); 890 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 891 } 892 893 unsigned SrcReg = MRI.createGenericVirtualRegister(LLT::scalar(64)); 894 BuildMI(MBB, I.getIterator(), I.getDebugLoc(), 895 TII.get(AArch64::SUBREG_TO_REG)) 896 .addDef(SrcReg) 897 .addImm(0) 898 .addUse(I.getOperand(2).getReg()) 899 .addImm(AArch64::sub_32); 900 RBI.constrainGenericRegister(I.getOperand(2).getReg(), 901 AArch64::GPR32RegClass, MRI); 902 I.getOperand(2).setReg(SrcReg); 903 904 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 905 } 906 case TargetOpcode::G_FRAME_INDEX: { 907 // allocas and G_FRAME_INDEX are only supported in addrspace(0). 908 if (Ty != LLT::pointer(0, 64)) { 909 DEBUG(dbgs() << "G_FRAME_INDEX pointer has type: " << Ty 910 << ", expected: " << LLT::pointer(0, 64) << '\n'); 911 return false; 912 } 913 I.setDesc(TII.get(AArch64::ADDXri)); 914 915 // MOs for a #0 shifted immediate. 916 I.addOperand(MachineOperand::CreateImm(0)); 917 I.addOperand(MachineOperand::CreateImm(0)); 918 919 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 920 } 921 922 case TargetOpcode::G_GLOBAL_VALUE: { 923 auto GV = I.getOperand(1).getGlobal(); 924 if (GV->isThreadLocal()) { 925 // FIXME: we don't support TLS yet. 926 return false; 927 } 928 unsigned char OpFlags = STI.ClassifyGlobalReference(GV, TM); 929 if (OpFlags & AArch64II::MO_GOT) { 930 I.setDesc(TII.get(AArch64::LOADgot)); 931 I.getOperand(1).setTargetFlags(OpFlags); 932 } else if (TM.getCodeModel() == CodeModel::Large) { 933 // Materialize the global using movz/movk instructions. 934 unsigned MovZDstReg = MRI.createVirtualRegister(&AArch64::GPR64RegClass); 935 auto InsertPt = std::next(I.getIterator()); 936 auto MovZ = 937 BuildMI(MBB, InsertPt, I.getDebugLoc(), TII.get(AArch64::MOVZXi)) 938 .addDef(MovZDstReg); 939 MovZ->addOperand(MF, I.getOperand(1)); 940 MovZ->getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_G0 | 941 AArch64II::MO_NC); 942 MovZ->addOperand(MF, MachineOperand::CreateImm(0)); 943 constrainSelectedInstRegOperands(*MovZ, TII, TRI, RBI); 944 945 auto BuildMovK = [&](unsigned SrcReg, unsigned char Flags, 946 unsigned Offset, unsigned ForceDstReg) { 947 unsigned DstReg = 948 ForceDstReg ? ForceDstReg 949 : MRI.createVirtualRegister(&AArch64::GPR64RegClass); 950 auto MovI = BuildMI(MBB, InsertPt, MovZ->getDebugLoc(), 951 TII.get(AArch64::MOVKXi)) 952 .addDef(DstReg) 953 .addReg(SrcReg); 954 MovI->addOperand(MF, MachineOperand::CreateGA( 955 GV, MovZ->getOperand(1).getOffset(), Flags)); 956 MovI->addOperand(MF, MachineOperand::CreateImm(Offset)); 957 constrainSelectedInstRegOperands(*MovI, TII, TRI, RBI); 958 return DstReg; 959 }; 960 unsigned DstReg = BuildMovK(MovZ->getOperand(0).getReg(), 961 AArch64II::MO_G1 | AArch64II::MO_NC, 16, 0); 962 DstReg = BuildMovK(DstReg, AArch64II::MO_G2 | AArch64II::MO_NC, 32, 0); 963 BuildMovK(DstReg, AArch64II::MO_G3, 48, I.getOperand(0).getReg()); 964 I.eraseFromParent(); 965 return true; 966 } else { 967 I.setDesc(TII.get(AArch64::MOVaddr)); 968 I.getOperand(1).setTargetFlags(OpFlags | AArch64II::MO_PAGE); 969 MachineInstrBuilder MIB(MF, I); 970 MIB.addGlobalAddress(GV, I.getOperand(1).getOffset(), 971 OpFlags | AArch64II::MO_PAGEOFF | AArch64II::MO_NC); 972 } 973 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 974 } 975 976 case TargetOpcode::G_LOAD: 977 case TargetOpcode::G_STORE: { 978 LLT MemTy = Ty; 979 LLT PtrTy = MRI.getType(I.getOperand(1).getReg()); 980 981 if (PtrTy != LLT::pointer(0, 64)) { 982 DEBUG(dbgs() << "Load/Store pointer has type: " << PtrTy 983 << ", expected: " << LLT::pointer(0, 64) << '\n'); 984 return false; 985 } 986 987 auto &MemOp = **I.memoperands_begin(); 988 if (MemOp.getOrdering() != AtomicOrdering::NotAtomic) { 989 DEBUG(dbgs() << "Atomic load/store not supported yet\n"); 990 return false; 991 } 992 993 // FIXME: PR36018: Volatile loads in some cases are incorrectly selected by 994 // folding with an extend. Until we have a G_SEXTLOAD solution bail out if 995 // we hit one. 996 if (Opcode == TargetOpcode::G_LOAD && MemOp.isVolatile()) 997 return false; 998 999 const unsigned PtrReg = I.getOperand(1).getReg(); 1000 #ifndef NDEBUG 1001 const RegisterBank &PtrRB = *RBI.getRegBank(PtrReg, MRI, TRI); 1002 // Sanity-check the pointer register. 1003 assert(PtrRB.getID() == AArch64::GPRRegBankID && 1004 "Load/Store pointer operand isn't a GPR"); 1005 assert(MRI.getType(PtrReg).isPointer() && 1006 "Load/Store pointer operand isn't a pointer"); 1007 #endif 1008 1009 const unsigned ValReg = I.getOperand(0).getReg(); 1010 const RegisterBank &RB = *RBI.getRegBank(ValReg, MRI, TRI); 1011 1012 const unsigned NewOpc = 1013 selectLoadStoreUIOp(I.getOpcode(), RB.getID(), MemTy.getSizeInBits()); 1014 if (NewOpc == I.getOpcode()) 1015 return false; 1016 1017 I.setDesc(TII.get(NewOpc)); 1018 1019 uint64_t Offset = 0; 1020 auto *PtrMI = MRI.getVRegDef(PtrReg); 1021 1022 // Try to fold a GEP into our unsigned immediate addressing mode. 1023 if (PtrMI->getOpcode() == TargetOpcode::G_GEP) { 1024 if (auto COff = getConstantVRegVal(PtrMI->getOperand(2).getReg(), MRI)) { 1025 int64_t Imm = *COff; 1026 const unsigned Size = MemTy.getSizeInBits() / 8; 1027 const unsigned Scale = Log2_32(Size); 1028 if ((Imm & (Size - 1)) == 0 && Imm >= 0 && Imm < (0x1000 << Scale)) { 1029 unsigned Ptr2Reg = PtrMI->getOperand(1).getReg(); 1030 I.getOperand(1).setReg(Ptr2Reg); 1031 PtrMI = MRI.getVRegDef(Ptr2Reg); 1032 Offset = Imm / Size; 1033 } 1034 } 1035 } 1036 1037 // If we haven't folded anything into our addressing mode yet, try to fold 1038 // a frame index into the base+offset. 1039 if (!Offset && PtrMI->getOpcode() == TargetOpcode::G_FRAME_INDEX) 1040 I.getOperand(1).ChangeToFrameIndex(PtrMI->getOperand(1).getIndex()); 1041 1042 I.addOperand(MachineOperand::CreateImm(Offset)); 1043 1044 // If we're storing a 0, use WZR/XZR. 1045 if (auto CVal = getConstantVRegVal(ValReg, MRI)) { 1046 if (*CVal == 0 && Opcode == TargetOpcode::G_STORE) { 1047 if (I.getOpcode() == AArch64::STRWui) 1048 I.getOperand(0).setReg(AArch64::WZR); 1049 else if (I.getOpcode() == AArch64::STRXui) 1050 I.getOperand(0).setReg(AArch64::XZR); 1051 } 1052 } 1053 1054 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1055 } 1056 1057 case TargetOpcode::G_SMULH: 1058 case TargetOpcode::G_UMULH: { 1059 // Reject the various things we don't support yet. 1060 if (unsupportedBinOp(I, RBI, MRI, TRI)) 1061 return false; 1062 1063 const unsigned DefReg = I.getOperand(0).getReg(); 1064 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); 1065 1066 if (RB.getID() != AArch64::GPRRegBankID) { 1067 DEBUG(dbgs() << "G_[SU]MULH on bank: " << RB << ", expected: GPR\n"); 1068 return false; 1069 } 1070 1071 if (Ty != LLT::scalar(64)) { 1072 DEBUG(dbgs() << "G_[SU]MULH has type: " << Ty 1073 << ", expected: " << LLT::scalar(64) << '\n'); 1074 return false; 1075 } 1076 1077 unsigned NewOpc = I.getOpcode() == TargetOpcode::G_SMULH ? AArch64::SMULHrr 1078 : AArch64::UMULHrr; 1079 I.setDesc(TII.get(NewOpc)); 1080 1081 // Now that we selected an opcode, we need to constrain the register 1082 // operands to use appropriate classes. 1083 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1084 } 1085 case TargetOpcode::G_FADD: 1086 case TargetOpcode::G_FSUB: 1087 case TargetOpcode::G_FMUL: 1088 case TargetOpcode::G_FDIV: 1089 1090 case TargetOpcode::G_OR: 1091 case TargetOpcode::G_SHL: 1092 case TargetOpcode::G_LSHR: 1093 case TargetOpcode::G_ASHR: 1094 case TargetOpcode::G_GEP: { 1095 // Reject the various things we don't support yet. 1096 if (unsupportedBinOp(I, RBI, MRI, TRI)) 1097 return false; 1098 1099 const unsigned OpSize = Ty.getSizeInBits(); 1100 1101 const unsigned DefReg = I.getOperand(0).getReg(); 1102 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); 1103 1104 const unsigned NewOpc = selectBinaryOp(I.getOpcode(), RB.getID(), OpSize); 1105 if (NewOpc == I.getOpcode()) 1106 return false; 1107 1108 I.setDesc(TII.get(NewOpc)); 1109 // FIXME: Should the type be always reset in setDesc? 1110 1111 // Now that we selected an opcode, we need to constrain the register 1112 // operands to use appropriate classes. 1113 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1114 } 1115 1116 case TargetOpcode::G_PTR_MASK: { 1117 uint64_t Align = I.getOperand(2).getImm(); 1118 if (Align >= 64 || Align == 0) 1119 return false; 1120 1121 uint64_t Mask = ~((1ULL << Align) - 1); 1122 I.setDesc(TII.get(AArch64::ANDXri)); 1123 I.getOperand(2).setImm(AArch64_AM::encodeLogicalImmediate(Mask, 64)); 1124 1125 return constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1126 } 1127 case TargetOpcode::G_PTRTOINT: 1128 case TargetOpcode::G_TRUNC: { 1129 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()); 1130 const LLT SrcTy = MRI.getType(I.getOperand(1).getReg()); 1131 1132 const unsigned DstReg = I.getOperand(0).getReg(); 1133 const unsigned SrcReg = I.getOperand(1).getReg(); 1134 1135 const RegisterBank &DstRB = *RBI.getRegBank(DstReg, MRI, TRI); 1136 const RegisterBank &SrcRB = *RBI.getRegBank(SrcReg, MRI, TRI); 1137 1138 if (DstRB.getID() != SrcRB.getID()) { 1139 DEBUG(dbgs() << "G_TRUNC/G_PTRTOINT input/output on different banks\n"); 1140 return false; 1141 } 1142 1143 if (DstRB.getID() == AArch64::GPRRegBankID) { 1144 const TargetRegisterClass *DstRC = 1145 getRegClassForTypeOnBank(DstTy, DstRB, RBI); 1146 if (!DstRC) 1147 return false; 1148 1149 const TargetRegisterClass *SrcRC = 1150 getRegClassForTypeOnBank(SrcTy, SrcRB, RBI); 1151 if (!SrcRC) 1152 return false; 1153 1154 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, MRI) || 1155 !RBI.constrainGenericRegister(DstReg, *DstRC, MRI)) { 1156 DEBUG(dbgs() << "Failed to constrain G_TRUNC/G_PTRTOINT\n"); 1157 return false; 1158 } 1159 1160 if (DstRC == SrcRC) { 1161 // Nothing to be done 1162 } else if (Opcode == TargetOpcode::G_TRUNC && DstTy == LLT::scalar(32) && 1163 SrcTy == LLT::scalar(64)) { 1164 llvm_unreachable("TableGen can import this case"); 1165 return false; 1166 } else if (DstRC == &AArch64::GPR32RegClass && 1167 SrcRC == &AArch64::GPR64RegClass) { 1168 I.getOperand(1).setSubReg(AArch64::sub_32); 1169 } else { 1170 DEBUG(dbgs() << "Unhandled mismatched classes in G_TRUNC/G_PTRTOINT\n"); 1171 return false; 1172 } 1173 1174 I.setDesc(TII.get(TargetOpcode::COPY)); 1175 return true; 1176 } else if (DstRB.getID() == AArch64::FPRRegBankID) { 1177 if (DstTy == LLT::vector(4, 16) && SrcTy == LLT::vector(4, 32)) { 1178 I.setDesc(TII.get(AArch64::XTNv4i16)); 1179 constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1180 return true; 1181 } 1182 } 1183 1184 return false; 1185 } 1186 1187 case TargetOpcode::G_ANYEXT: { 1188 const unsigned DstReg = I.getOperand(0).getReg(); 1189 const unsigned SrcReg = I.getOperand(1).getReg(); 1190 1191 const RegisterBank &RBDst = *RBI.getRegBank(DstReg, MRI, TRI); 1192 if (RBDst.getID() != AArch64::GPRRegBankID) { 1193 DEBUG(dbgs() << "G_ANYEXT on bank: " << RBDst << ", expected: GPR\n"); 1194 return false; 1195 } 1196 1197 const RegisterBank &RBSrc = *RBI.getRegBank(SrcReg, MRI, TRI); 1198 if (RBSrc.getID() != AArch64::GPRRegBankID) { 1199 DEBUG(dbgs() << "G_ANYEXT on bank: " << RBSrc << ", expected: GPR\n"); 1200 return false; 1201 } 1202 1203 const unsigned DstSize = MRI.getType(DstReg).getSizeInBits(); 1204 1205 if (DstSize == 0) { 1206 DEBUG(dbgs() << "G_ANYEXT operand has no size, not a gvreg?\n"); 1207 return false; 1208 } 1209 1210 if (DstSize != 64 && DstSize > 32) { 1211 DEBUG(dbgs() << "G_ANYEXT to size: " << DstSize 1212 << ", expected: 32 or 64\n"); 1213 return false; 1214 } 1215 // At this point G_ANYEXT is just like a plain COPY, but we need 1216 // to explicitly form the 64-bit value if any. 1217 if (DstSize > 32) { 1218 unsigned ExtSrc = MRI.createVirtualRegister(&AArch64::GPR64allRegClass); 1219 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG)) 1220 .addDef(ExtSrc) 1221 .addImm(0) 1222 .addUse(SrcReg) 1223 .addImm(AArch64::sub_32); 1224 I.getOperand(1).setReg(ExtSrc); 1225 } 1226 return selectCopy(I, TII, MRI, TRI, RBI); 1227 } 1228 1229 case TargetOpcode::G_ZEXT: 1230 case TargetOpcode::G_SEXT: { 1231 unsigned Opcode = I.getOpcode(); 1232 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()), 1233 SrcTy = MRI.getType(I.getOperand(1).getReg()); 1234 const bool isSigned = Opcode == TargetOpcode::G_SEXT; 1235 const unsigned DefReg = I.getOperand(0).getReg(); 1236 const unsigned SrcReg = I.getOperand(1).getReg(); 1237 const RegisterBank &RB = *RBI.getRegBank(DefReg, MRI, TRI); 1238 1239 if (RB.getID() != AArch64::GPRRegBankID) { 1240 DEBUG(dbgs() << TII.getName(I.getOpcode()) << " on bank: " << RB 1241 << ", expected: GPR\n"); 1242 return false; 1243 } 1244 1245 MachineInstr *ExtI; 1246 if (DstTy == LLT::scalar(64)) { 1247 // FIXME: Can we avoid manually doing this? 1248 if (!RBI.constrainGenericRegister(SrcReg, AArch64::GPR32RegClass, MRI)) { 1249 DEBUG(dbgs() << "Failed to constrain " << TII.getName(Opcode) 1250 << " operand\n"); 1251 return false; 1252 } 1253 1254 const unsigned SrcXReg = 1255 MRI.createVirtualRegister(&AArch64::GPR64RegClass); 1256 BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::SUBREG_TO_REG)) 1257 .addDef(SrcXReg) 1258 .addImm(0) 1259 .addUse(SrcReg) 1260 .addImm(AArch64::sub_32); 1261 1262 const unsigned NewOpc = isSigned ? AArch64::SBFMXri : AArch64::UBFMXri; 1263 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc)) 1264 .addDef(DefReg) 1265 .addUse(SrcXReg) 1266 .addImm(0) 1267 .addImm(SrcTy.getSizeInBits() - 1); 1268 } else if (DstTy.isScalar() && DstTy.getSizeInBits() <= 32) { 1269 const unsigned NewOpc = isSigned ? AArch64::SBFMWri : AArch64::UBFMWri; 1270 ExtI = BuildMI(MBB, I, I.getDebugLoc(), TII.get(NewOpc)) 1271 .addDef(DefReg) 1272 .addUse(SrcReg) 1273 .addImm(0) 1274 .addImm(SrcTy.getSizeInBits() - 1); 1275 } else { 1276 return false; 1277 } 1278 1279 constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI); 1280 1281 I.eraseFromParent(); 1282 return true; 1283 } 1284 1285 case TargetOpcode::G_SITOFP: 1286 case TargetOpcode::G_UITOFP: 1287 case TargetOpcode::G_FPTOSI: 1288 case TargetOpcode::G_FPTOUI: { 1289 const LLT DstTy = MRI.getType(I.getOperand(0).getReg()), 1290 SrcTy = MRI.getType(I.getOperand(1).getReg()); 1291 const unsigned NewOpc = selectFPConvOpc(Opcode, DstTy, SrcTy); 1292 if (NewOpc == Opcode) 1293 return false; 1294 1295 I.setDesc(TII.get(NewOpc)); 1296 constrainSelectedInstRegOperands(I, TII, TRI, RBI); 1297 1298 return true; 1299 } 1300 1301 1302 case TargetOpcode::G_INTTOPTR: 1303 // The importer is currently unable to import pointer types since they 1304 // didn't exist in SelectionDAG. 1305 return selectCopy(I, TII, MRI, TRI, RBI); 1306 1307 case TargetOpcode::G_BITCAST: 1308 // Imported SelectionDAG rules can handle every bitcast except those that 1309 // bitcast from a type to the same type. Ideally, these shouldn't occur 1310 // but we might not run an optimizer that deletes them. 1311 if (MRI.getType(I.getOperand(0).getReg()) == 1312 MRI.getType(I.getOperand(1).getReg())) 1313 return selectCopy(I, TII, MRI, TRI, RBI); 1314 return false; 1315 1316 case TargetOpcode::G_SELECT: { 1317 if (MRI.getType(I.getOperand(1).getReg()) != LLT::scalar(1)) { 1318 DEBUG(dbgs() << "G_SELECT cond has type: " << Ty 1319 << ", expected: " << LLT::scalar(1) << '\n'); 1320 return false; 1321 } 1322 1323 const unsigned CondReg = I.getOperand(1).getReg(); 1324 const unsigned TReg = I.getOperand(2).getReg(); 1325 const unsigned FReg = I.getOperand(3).getReg(); 1326 1327 unsigned CSelOpc = 0; 1328 1329 if (Ty == LLT::scalar(32)) { 1330 CSelOpc = AArch64::CSELWr; 1331 } else if (Ty == LLT::scalar(64) || Ty == LLT::pointer(0, 64)) { 1332 CSelOpc = AArch64::CSELXr; 1333 } else { 1334 return false; 1335 } 1336 1337 MachineInstr &TstMI = 1338 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ANDSWri)) 1339 .addDef(AArch64::WZR) 1340 .addUse(CondReg) 1341 .addImm(AArch64_AM::encodeLogicalImmediate(1, 32)); 1342 1343 MachineInstr &CSelMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CSelOpc)) 1344 .addDef(I.getOperand(0).getReg()) 1345 .addUse(TReg) 1346 .addUse(FReg) 1347 .addImm(AArch64CC::NE); 1348 1349 constrainSelectedInstRegOperands(TstMI, TII, TRI, RBI); 1350 constrainSelectedInstRegOperands(CSelMI, TII, TRI, RBI); 1351 1352 I.eraseFromParent(); 1353 return true; 1354 } 1355 case TargetOpcode::G_ICMP: { 1356 if (Ty != LLT::scalar(32)) { 1357 DEBUG(dbgs() << "G_ICMP result has type: " << Ty 1358 << ", expected: " << LLT::scalar(32) << '\n'); 1359 return false; 1360 } 1361 1362 unsigned CmpOpc = 0; 1363 unsigned ZReg = 0; 1364 1365 LLT CmpTy = MRI.getType(I.getOperand(2).getReg()); 1366 if (CmpTy == LLT::scalar(32)) { 1367 CmpOpc = AArch64::SUBSWrr; 1368 ZReg = AArch64::WZR; 1369 } else if (CmpTy == LLT::scalar(64) || CmpTy.isPointer()) { 1370 CmpOpc = AArch64::SUBSXrr; 1371 ZReg = AArch64::XZR; 1372 } else { 1373 return false; 1374 } 1375 1376 // CSINC increments the result by one when the condition code is false. 1377 // Therefore, we have to invert the predicate to get an increment by 1 when 1378 // the predicate is true. 1379 const AArch64CC::CondCode invCC = 1380 changeICMPPredToAArch64CC(CmpInst::getInversePredicate( 1381 (CmpInst::Predicate)I.getOperand(1).getPredicate())); 1382 1383 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc)) 1384 .addDef(ZReg) 1385 .addUse(I.getOperand(2).getReg()) 1386 .addUse(I.getOperand(3).getReg()); 1387 1388 MachineInstr &CSetMI = 1389 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr)) 1390 .addDef(I.getOperand(0).getReg()) 1391 .addUse(AArch64::WZR) 1392 .addUse(AArch64::WZR) 1393 .addImm(invCC); 1394 1395 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI); 1396 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI); 1397 1398 I.eraseFromParent(); 1399 return true; 1400 } 1401 1402 case TargetOpcode::G_FCMP: { 1403 if (Ty != LLT::scalar(32)) { 1404 DEBUG(dbgs() << "G_FCMP result has type: " << Ty 1405 << ", expected: " << LLT::scalar(32) << '\n'); 1406 return false; 1407 } 1408 1409 unsigned CmpOpc = 0; 1410 LLT CmpTy = MRI.getType(I.getOperand(2).getReg()); 1411 if (CmpTy == LLT::scalar(32)) { 1412 CmpOpc = AArch64::FCMPSrr; 1413 } else if (CmpTy == LLT::scalar(64)) { 1414 CmpOpc = AArch64::FCMPDrr; 1415 } else { 1416 return false; 1417 } 1418 1419 // FIXME: regbank 1420 1421 AArch64CC::CondCode CC1, CC2; 1422 changeFCMPPredToAArch64CC( 1423 (CmpInst::Predicate)I.getOperand(1).getPredicate(), CC1, CC2); 1424 1425 MachineInstr &CmpMI = *BuildMI(MBB, I, I.getDebugLoc(), TII.get(CmpOpc)) 1426 .addUse(I.getOperand(2).getReg()) 1427 .addUse(I.getOperand(3).getReg()); 1428 1429 const unsigned DefReg = I.getOperand(0).getReg(); 1430 unsigned Def1Reg = DefReg; 1431 if (CC2 != AArch64CC::AL) 1432 Def1Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass); 1433 1434 MachineInstr &CSetMI = 1435 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr)) 1436 .addDef(Def1Reg) 1437 .addUse(AArch64::WZR) 1438 .addUse(AArch64::WZR) 1439 .addImm(getInvertedCondCode(CC1)); 1440 1441 if (CC2 != AArch64CC::AL) { 1442 unsigned Def2Reg = MRI.createVirtualRegister(&AArch64::GPR32RegClass); 1443 MachineInstr &CSet2MI = 1444 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::CSINCWr)) 1445 .addDef(Def2Reg) 1446 .addUse(AArch64::WZR) 1447 .addUse(AArch64::WZR) 1448 .addImm(getInvertedCondCode(CC2)); 1449 MachineInstr &OrMI = 1450 *BuildMI(MBB, I, I.getDebugLoc(), TII.get(AArch64::ORRWrr)) 1451 .addDef(DefReg) 1452 .addUse(Def1Reg) 1453 .addUse(Def2Reg); 1454 constrainSelectedInstRegOperands(OrMI, TII, TRI, RBI); 1455 constrainSelectedInstRegOperands(CSet2MI, TII, TRI, RBI); 1456 } 1457 1458 constrainSelectedInstRegOperands(CmpMI, TII, TRI, RBI); 1459 constrainSelectedInstRegOperands(CSetMI, TII, TRI, RBI); 1460 1461 I.eraseFromParent(); 1462 return true; 1463 } 1464 case TargetOpcode::G_VASTART: 1465 return STI.isTargetDarwin() ? selectVaStartDarwin(I, MF, MRI) 1466 : selectVaStartAAPCS(I, MF, MRI); 1467 case TargetOpcode::G_IMPLICIT_DEF: 1468 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF)); 1469 return true; 1470 } 1471 1472 return false; 1473 } 1474 1475 /// SelectArithImmed - Select an immediate value that can be represented as 1476 /// a 12-bit value shifted left by either 0 or 12. If so, return true with 1477 /// Val set to the 12-bit value and Shift set to the shifter operand. 1478 InstructionSelector::ComplexRendererFns 1479 AArch64InstructionSelector::selectArithImmed(MachineOperand &Root) const { 1480 MachineInstr &MI = *Root.getParent(); 1481 MachineBasicBlock &MBB = *MI.getParent(); 1482 MachineFunction &MF = *MBB.getParent(); 1483 MachineRegisterInfo &MRI = MF.getRegInfo(); 1484 1485 // This function is called from the addsub_shifted_imm ComplexPattern, 1486 // which lists [imm] as the list of opcode it's interested in, however 1487 // we still need to check whether the operand is actually an immediate 1488 // here because the ComplexPattern opcode list is only used in 1489 // root-level opcode matching. 1490 uint64_t Immed; 1491 if (Root.isImm()) 1492 Immed = Root.getImm(); 1493 else if (Root.isCImm()) 1494 Immed = Root.getCImm()->getZExtValue(); 1495 else if (Root.isReg()) { 1496 MachineInstr *Def = MRI.getVRegDef(Root.getReg()); 1497 if (Def->getOpcode() != TargetOpcode::G_CONSTANT) 1498 return None; 1499 MachineOperand &Op1 = Def->getOperand(1); 1500 if (!Op1.isCImm() || Op1.getCImm()->getBitWidth() > 64) 1501 return None; 1502 Immed = Op1.getCImm()->getZExtValue(); 1503 } else 1504 return None; 1505 1506 unsigned ShiftAmt; 1507 1508 if (Immed >> 12 == 0) { 1509 ShiftAmt = 0; 1510 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) { 1511 ShiftAmt = 12; 1512 Immed = Immed >> 12; 1513 } else 1514 return None; 1515 1516 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt); 1517 return {{ 1518 [=](MachineInstrBuilder &MIB) { MIB.addImm(Immed); }, 1519 [=](MachineInstrBuilder &MIB) { MIB.addImm(ShVal); }, 1520 }}; 1521 } 1522 1523 /// Select a "register plus unscaled signed 9-bit immediate" address. This 1524 /// should only match when there is an offset that is not valid for a scaled 1525 /// immediate addressing mode. The "Size" argument is the size in bytes of the 1526 /// memory reference, which is needed here to know what is valid for a scaled 1527 /// immediate. 1528 InstructionSelector::ComplexRendererFns 1529 AArch64InstructionSelector::selectAddrModeUnscaled(MachineOperand &Root, 1530 unsigned Size) const { 1531 MachineRegisterInfo &MRI = 1532 Root.getParent()->getParent()->getParent()->getRegInfo(); 1533 1534 if (!Root.isReg()) 1535 return None; 1536 1537 if (!isBaseWithConstantOffset(Root, MRI)) 1538 return None; 1539 1540 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg()); 1541 if (!RootDef) 1542 return None; 1543 1544 MachineOperand &OffImm = RootDef->getOperand(2); 1545 if (!OffImm.isReg()) 1546 return None; 1547 MachineInstr *RHS = MRI.getVRegDef(OffImm.getReg()); 1548 if (!RHS || RHS->getOpcode() != TargetOpcode::G_CONSTANT) 1549 return None; 1550 int64_t RHSC; 1551 MachineOperand &RHSOp1 = RHS->getOperand(1); 1552 if (!RHSOp1.isCImm() || RHSOp1.getCImm()->getBitWidth() > 64) 1553 return None; 1554 RHSC = RHSOp1.getCImm()->getSExtValue(); 1555 1556 // If the offset is valid as a scaled immediate, don't match here. 1557 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Log2_32(Size))) 1558 return None; 1559 if (RHSC >= -256 && RHSC < 256) { 1560 MachineOperand &Base = RootDef->getOperand(1); 1561 return {{ 1562 [=](MachineInstrBuilder &MIB) { MIB.add(Base); }, 1563 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC); }, 1564 }}; 1565 } 1566 return None; 1567 } 1568 1569 /// Select a "register plus scaled unsigned 12-bit immediate" address. The 1570 /// "Size" argument is the size in bytes of the memory reference, which 1571 /// determines the scale. 1572 InstructionSelector::ComplexRendererFns 1573 AArch64InstructionSelector::selectAddrModeIndexed(MachineOperand &Root, 1574 unsigned Size) const { 1575 MachineRegisterInfo &MRI = 1576 Root.getParent()->getParent()->getParent()->getRegInfo(); 1577 1578 if (!Root.isReg()) 1579 return None; 1580 1581 MachineInstr *RootDef = MRI.getVRegDef(Root.getReg()); 1582 if (!RootDef) 1583 return None; 1584 1585 if (RootDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) { 1586 return {{ 1587 [=](MachineInstrBuilder &MIB) { MIB.add(RootDef->getOperand(1)); }, 1588 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, 1589 }}; 1590 } 1591 1592 if (isBaseWithConstantOffset(Root, MRI)) { 1593 MachineOperand &LHS = RootDef->getOperand(1); 1594 MachineOperand &RHS = RootDef->getOperand(2); 1595 MachineInstr *LHSDef = MRI.getVRegDef(LHS.getReg()); 1596 MachineInstr *RHSDef = MRI.getVRegDef(RHS.getReg()); 1597 if (LHSDef && RHSDef) { 1598 int64_t RHSC = (int64_t)RHSDef->getOperand(1).getCImm()->getZExtValue(); 1599 unsigned Scale = Log2_32(Size); 1600 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) { 1601 if (LHSDef->getOpcode() == TargetOpcode::G_FRAME_INDEX) 1602 return {{ 1603 [=](MachineInstrBuilder &MIB) { MIB.add(LHSDef->getOperand(1)); }, 1604 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); }, 1605 }}; 1606 1607 return {{ 1608 [=](MachineInstrBuilder &MIB) { MIB.add(LHS); }, 1609 [=](MachineInstrBuilder &MIB) { MIB.addImm(RHSC >> Scale); }, 1610 }}; 1611 } 1612 } 1613 } 1614 1615 // Before falling back to our general case, check if the unscaled 1616 // instructions can handle this. If so, that's preferable. 1617 if (selectAddrModeUnscaled(Root, Size).hasValue()) 1618 return None; 1619 1620 return {{ 1621 [=](MachineInstrBuilder &MIB) { MIB.add(Root); }, 1622 [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, 1623 }}; 1624 } 1625 1626 namespace llvm { 1627 InstructionSelector * 1628 createAArch64InstructionSelector(const AArch64TargetMachine &TM, 1629 AArch64Subtarget &Subtarget, 1630 AArch64RegisterBankInfo &RBI) { 1631 return new AArch64InstructionSelector(TM, Subtarget, RBI); 1632 } 1633 } 1634