1 //===-- AArch64ISelDAGToDAG.cpp - A dag to dag inst selector for AArch64 --===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines an instruction selector for the AArch64 target. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "AArch64MachineFunctionInfo.h" 14 #include "AArch64TargetMachine.h" 15 #include "MCTargetDesc/AArch64AddressingModes.h" 16 #include "llvm/ADT/APSInt.h" 17 #include "llvm/CodeGen/SelectionDAGISel.h" 18 #include "llvm/IR/Function.h" // To access function attributes. 19 #include "llvm/IR/GlobalValue.h" 20 #include "llvm/IR/Intrinsics.h" 21 #include "llvm/IR/IntrinsicsAArch64.h" 22 #include "llvm/Support/Debug.h" 23 #include "llvm/Support/ErrorHandling.h" 24 #include "llvm/Support/KnownBits.h" 25 #include "llvm/Support/MathExtras.h" 26 #include "llvm/Support/raw_ostream.h" 27 28 using namespace llvm; 29 30 #define DEBUG_TYPE "aarch64-isel" 31 32 //===--------------------------------------------------------------------===// 33 /// AArch64DAGToDAGISel - AArch64 specific code to select AArch64 machine 34 /// instructions for SelectionDAG operations. 35 /// 36 namespace { 37 38 class AArch64DAGToDAGISel : public SelectionDAGISel { 39 40 /// Subtarget - Keep a pointer to the AArch64Subtarget around so that we can 41 /// make the right decision when generating code for different targets. 42 const AArch64Subtarget *Subtarget; 43 44 public: 45 explicit AArch64DAGToDAGISel(AArch64TargetMachine &tm, 46 CodeGenOpt::Level OptLevel) 47 : SelectionDAGISel(tm, OptLevel), Subtarget(nullptr) {} 48 49 StringRef getPassName() const override { 50 return "AArch64 Instruction Selection"; 51 } 52 53 bool runOnMachineFunction(MachineFunction &MF) override { 54 Subtarget = &MF.getSubtarget<AArch64Subtarget>(); 55 return SelectionDAGISel::runOnMachineFunction(MF); 56 } 57 58 void Select(SDNode *Node) override; 59 60 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 61 /// inline asm expressions. 62 bool SelectInlineAsmMemoryOperand(const SDValue &Op, 63 unsigned ConstraintID, 64 std::vector<SDValue> &OutOps) override; 65 66 template <signed Low, signed High, signed Scale> 67 bool SelectRDVLImm(SDValue N, SDValue &Imm); 68 69 bool tryMLAV64LaneV128(SDNode *N); 70 bool tryMULLV64LaneV128(unsigned IntNo, SDNode *N); 71 bool SelectArithExtendedRegister(SDValue N, SDValue &Reg, SDValue &Shift); 72 bool SelectArithImmed(SDValue N, SDValue &Val, SDValue &Shift); 73 bool SelectNegArithImmed(SDValue N, SDValue &Val, SDValue &Shift); 74 bool SelectArithShiftedRegister(SDValue N, SDValue &Reg, SDValue &Shift) { 75 return SelectShiftedRegister(N, false, Reg, Shift); 76 } 77 bool SelectLogicalShiftedRegister(SDValue N, SDValue &Reg, SDValue &Shift) { 78 return SelectShiftedRegister(N, true, Reg, Shift); 79 } 80 bool SelectAddrModeIndexed7S8(SDValue N, SDValue &Base, SDValue &OffImm) { 81 return SelectAddrModeIndexed7S(N, 1, Base, OffImm); 82 } 83 bool SelectAddrModeIndexed7S16(SDValue N, SDValue &Base, SDValue &OffImm) { 84 return SelectAddrModeIndexed7S(N, 2, Base, OffImm); 85 } 86 bool SelectAddrModeIndexed7S32(SDValue N, SDValue &Base, SDValue &OffImm) { 87 return SelectAddrModeIndexed7S(N, 4, Base, OffImm); 88 } 89 bool SelectAddrModeIndexed7S64(SDValue N, SDValue &Base, SDValue &OffImm) { 90 return SelectAddrModeIndexed7S(N, 8, Base, OffImm); 91 } 92 bool SelectAddrModeIndexed7S128(SDValue N, SDValue &Base, SDValue &OffImm) { 93 return SelectAddrModeIndexed7S(N, 16, Base, OffImm); 94 } 95 bool SelectAddrModeIndexedS9S128(SDValue N, SDValue &Base, SDValue &OffImm) { 96 return SelectAddrModeIndexedBitWidth(N, true, 9, 16, Base, OffImm); 97 } 98 bool SelectAddrModeIndexedU6S128(SDValue N, SDValue &Base, SDValue &OffImm) { 99 return SelectAddrModeIndexedBitWidth(N, false, 6, 16, Base, OffImm); 100 } 101 bool SelectAddrModeIndexed8(SDValue N, SDValue &Base, SDValue &OffImm) { 102 return SelectAddrModeIndexed(N, 1, Base, OffImm); 103 } 104 bool SelectAddrModeIndexed16(SDValue N, SDValue &Base, SDValue &OffImm) { 105 return SelectAddrModeIndexed(N, 2, Base, OffImm); 106 } 107 bool SelectAddrModeIndexed32(SDValue N, SDValue &Base, SDValue &OffImm) { 108 return SelectAddrModeIndexed(N, 4, Base, OffImm); 109 } 110 bool SelectAddrModeIndexed64(SDValue N, SDValue &Base, SDValue &OffImm) { 111 return SelectAddrModeIndexed(N, 8, Base, OffImm); 112 } 113 bool SelectAddrModeIndexed128(SDValue N, SDValue &Base, SDValue &OffImm) { 114 return SelectAddrModeIndexed(N, 16, Base, OffImm); 115 } 116 bool SelectAddrModeUnscaled8(SDValue N, SDValue &Base, SDValue &OffImm) { 117 return SelectAddrModeUnscaled(N, 1, Base, OffImm); 118 } 119 bool SelectAddrModeUnscaled16(SDValue N, SDValue &Base, SDValue &OffImm) { 120 return SelectAddrModeUnscaled(N, 2, Base, OffImm); 121 } 122 bool SelectAddrModeUnscaled32(SDValue N, SDValue &Base, SDValue &OffImm) { 123 return SelectAddrModeUnscaled(N, 4, Base, OffImm); 124 } 125 bool SelectAddrModeUnscaled64(SDValue N, SDValue &Base, SDValue &OffImm) { 126 return SelectAddrModeUnscaled(N, 8, Base, OffImm); 127 } 128 bool SelectAddrModeUnscaled128(SDValue N, SDValue &Base, SDValue &OffImm) { 129 return SelectAddrModeUnscaled(N, 16, Base, OffImm); 130 } 131 template <unsigned Size, unsigned Max> 132 bool SelectAddrModeIndexedUImm(SDValue N, SDValue &Base, SDValue &OffImm) { 133 // Test if there is an appropriate addressing mode and check if the 134 // immediate fits. 135 bool Found = SelectAddrModeIndexed(N, Size, Base, OffImm); 136 if (Found) { 137 if (auto *CI = dyn_cast<ConstantSDNode>(OffImm)) { 138 int64_t C = CI->getSExtValue(); 139 if (C <= Max) 140 return true; 141 } 142 } 143 144 // Otherwise, base only, materialize address in register. 145 Base = N; 146 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i64); 147 return true; 148 } 149 150 template<int Width> 151 bool SelectAddrModeWRO(SDValue N, SDValue &Base, SDValue &Offset, 152 SDValue &SignExtend, SDValue &DoShift) { 153 return SelectAddrModeWRO(N, Width / 8, Base, Offset, SignExtend, DoShift); 154 } 155 156 template<int Width> 157 bool SelectAddrModeXRO(SDValue N, SDValue &Base, SDValue &Offset, 158 SDValue &SignExtend, SDValue &DoShift) { 159 return SelectAddrModeXRO(N, Width / 8, Base, Offset, SignExtend, DoShift); 160 } 161 162 bool SelectExtractHigh(SDValue N, SDValue &Res) { 163 if (Subtarget->isLittleEndian() && N->getOpcode() == ISD::BITCAST) 164 N = N->getOperand(0); 165 if (N->getOpcode() != ISD::EXTRACT_SUBVECTOR || 166 !isa<ConstantSDNode>(N->getOperand(1))) 167 return false; 168 EVT VT = N->getValueType(0); 169 EVT LVT = N->getOperand(0).getValueType(); 170 unsigned Index = N->getConstantOperandVal(1); 171 if (!VT.is64BitVector() || !LVT.is128BitVector() || 172 Index != VT.getVectorNumElements()) 173 return false; 174 Res = N->getOperand(0); 175 return true; 176 } 177 178 bool SelectDupZeroOrUndef(SDValue N) { 179 switch(N->getOpcode()) { 180 case ISD::UNDEF: 181 return true; 182 case AArch64ISD::DUP: 183 case ISD::SPLAT_VECTOR: { 184 auto Opnd0 = N->getOperand(0); 185 if (auto CN = dyn_cast<ConstantSDNode>(Opnd0)) 186 if (CN->isZero()) 187 return true; 188 if (auto CN = dyn_cast<ConstantFPSDNode>(Opnd0)) 189 if (CN->isZero()) 190 return true; 191 break; 192 } 193 default: 194 break; 195 } 196 197 return false; 198 } 199 200 bool SelectDupZero(SDValue N) { 201 switch(N->getOpcode()) { 202 case AArch64ISD::DUP: 203 case ISD::SPLAT_VECTOR: { 204 auto Opnd0 = N->getOperand(0); 205 if (auto CN = dyn_cast<ConstantSDNode>(Opnd0)) 206 if (CN->isZero()) 207 return true; 208 if (auto CN = dyn_cast<ConstantFPSDNode>(Opnd0)) 209 if (CN->isZero()) 210 return true; 211 break; 212 } 213 } 214 215 return false; 216 } 217 218 template<MVT::SimpleValueType VT> 219 bool SelectSVEAddSubImm(SDValue N, SDValue &Imm, SDValue &Shift) { 220 return SelectSVEAddSubImm(N, VT, Imm, Shift); 221 } 222 223 template <MVT::SimpleValueType VT> 224 bool SelectSVECpyDupImm(SDValue N, SDValue &Imm, SDValue &Shift) { 225 return SelectSVECpyDupImm(N, VT, Imm, Shift); 226 } 227 228 template <MVT::SimpleValueType VT, bool Invert = false> 229 bool SelectSVELogicalImm(SDValue N, SDValue &Imm) { 230 return SelectSVELogicalImm(N, VT, Imm, Invert); 231 } 232 233 template <MVT::SimpleValueType VT> 234 bool SelectSVEArithImm(SDValue N, SDValue &Imm) { 235 return SelectSVEArithImm(N, VT, Imm); 236 } 237 238 template <unsigned Low, unsigned High, bool AllowSaturation = false> 239 bool SelectSVEShiftImm(SDValue N, SDValue &Imm) { 240 return SelectSVEShiftImm(N, Low, High, AllowSaturation, Imm); 241 } 242 243 // Returns a suitable CNT/INC/DEC/RDVL multiplier to calculate VSCALE*N. 244 template<signed Min, signed Max, signed Scale, bool Shift> 245 bool SelectCntImm(SDValue N, SDValue &Imm) { 246 if (!isa<ConstantSDNode>(N)) 247 return false; 248 249 int64_t MulImm = cast<ConstantSDNode>(N)->getSExtValue(); 250 if (Shift) 251 MulImm = 1LL << MulImm; 252 253 if ((MulImm % std::abs(Scale)) != 0) 254 return false; 255 256 MulImm /= Scale; 257 if ((MulImm >= Min) && (MulImm <= Max)) { 258 Imm = CurDAG->getTargetConstant(MulImm, SDLoc(N), MVT::i32); 259 return true; 260 } 261 262 return false; 263 } 264 265 template <signed Max, signed Scale> 266 bool SelectEXTImm(SDValue N, SDValue &Imm) { 267 if (!isa<ConstantSDNode>(N)) 268 return false; 269 270 int64_t MulImm = cast<ConstantSDNode>(N)->getSExtValue(); 271 272 if (MulImm >= 0 && MulImm <= Max) { 273 MulImm *= Scale; 274 Imm = CurDAG->getTargetConstant(MulImm, SDLoc(N), MVT::i32); 275 return true; 276 } 277 278 return false; 279 } 280 281 /// Form sequences of consecutive 64/128-bit registers for use in NEON 282 /// instructions making use of a vector-list (e.g. ldN, tbl). Vecs must have 283 /// between 1 and 4 elements. If it contains a single element that is returned 284 /// unchanged; otherwise a REG_SEQUENCE value is returned. 285 SDValue createDTuple(ArrayRef<SDValue> Vecs); 286 SDValue createQTuple(ArrayRef<SDValue> Vecs); 287 // Form a sequence of SVE registers for instructions using list of vectors, 288 // e.g. structured loads and stores (ldN, stN). 289 SDValue createZTuple(ArrayRef<SDValue> Vecs); 290 291 /// Generic helper for the createDTuple/createQTuple 292 /// functions. Those should almost always be called instead. 293 SDValue createTuple(ArrayRef<SDValue> Vecs, const unsigned RegClassIDs[], 294 const unsigned SubRegs[]); 295 296 void SelectTable(SDNode *N, unsigned NumVecs, unsigned Opc, bool isExt); 297 298 bool tryIndexedLoad(SDNode *N); 299 300 bool trySelectStackSlotTagP(SDNode *N); 301 void SelectTagP(SDNode *N); 302 303 void SelectLoad(SDNode *N, unsigned NumVecs, unsigned Opc, 304 unsigned SubRegIdx); 305 void SelectPostLoad(SDNode *N, unsigned NumVecs, unsigned Opc, 306 unsigned SubRegIdx); 307 void SelectLoadLane(SDNode *N, unsigned NumVecs, unsigned Opc); 308 void SelectPostLoadLane(SDNode *N, unsigned NumVecs, unsigned Opc); 309 void SelectPredicatedLoad(SDNode *N, unsigned NumVecs, unsigned Scale, 310 unsigned Opc_rr, unsigned Opc_ri, 311 bool IsIntr = false); 312 313 bool SelectAddrModeFrameIndexSVE(SDValue N, SDValue &Base, SDValue &OffImm); 314 /// SVE Reg+Imm addressing mode. 315 template <int64_t Min, int64_t Max> 316 bool SelectAddrModeIndexedSVE(SDNode *Root, SDValue N, SDValue &Base, 317 SDValue &OffImm); 318 /// SVE Reg+Reg address mode. 319 template <unsigned Scale> 320 bool SelectSVERegRegAddrMode(SDValue N, SDValue &Base, SDValue &Offset) { 321 return SelectSVERegRegAddrMode(N, Scale, Base, Offset); 322 } 323 324 void SelectStore(SDNode *N, unsigned NumVecs, unsigned Opc); 325 void SelectPostStore(SDNode *N, unsigned NumVecs, unsigned Opc); 326 void SelectStoreLane(SDNode *N, unsigned NumVecs, unsigned Opc); 327 void SelectPostStoreLane(SDNode *N, unsigned NumVecs, unsigned Opc); 328 void SelectPredicatedStore(SDNode *N, unsigned NumVecs, unsigned Scale, 329 unsigned Opc_rr, unsigned Opc_ri); 330 std::tuple<unsigned, SDValue, SDValue> 331 findAddrModeSVELoadStore(SDNode *N, unsigned Opc_rr, unsigned Opc_ri, 332 const SDValue &OldBase, const SDValue &OldOffset, 333 unsigned Scale); 334 335 bool tryBitfieldExtractOp(SDNode *N); 336 bool tryBitfieldExtractOpFromSExt(SDNode *N); 337 bool tryBitfieldInsertOp(SDNode *N); 338 bool tryBitfieldInsertInZeroOp(SDNode *N); 339 bool tryShiftAmountMod(SDNode *N); 340 bool tryHighFPExt(SDNode *N); 341 342 bool tryReadRegister(SDNode *N); 343 bool tryWriteRegister(SDNode *N); 344 345 // Include the pieces autogenerated from the target description. 346 #include "AArch64GenDAGISel.inc" 347 348 private: 349 bool SelectShiftedRegister(SDValue N, bool AllowROR, SDValue &Reg, 350 SDValue &Shift); 351 bool SelectAddrModeIndexed7S(SDValue N, unsigned Size, SDValue &Base, 352 SDValue &OffImm) { 353 return SelectAddrModeIndexedBitWidth(N, true, 7, Size, Base, OffImm); 354 } 355 bool SelectAddrModeIndexedBitWidth(SDValue N, bool IsSignedImm, unsigned BW, 356 unsigned Size, SDValue &Base, 357 SDValue &OffImm); 358 bool SelectAddrModeIndexed(SDValue N, unsigned Size, SDValue &Base, 359 SDValue &OffImm); 360 bool SelectAddrModeUnscaled(SDValue N, unsigned Size, SDValue &Base, 361 SDValue &OffImm); 362 bool SelectAddrModeWRO(SDValue N, unsigned Size, SDValue &Base, 363 SDValue &Offset, SDValue &SignExtend, 364 SDValue &DoShift); 365 bool SelectAddrModeXRO(SDValue N, unsigned Size, SDValue &Base, 366 SDValue &Offset, SDValue &SignExtend, 367 SDValue &DoShift); 368 bool isWorthFolding(SDValue V) const; 369 bool SelectExtendedSHL(SDValue N, unsigned Size, bool WantExtend, 370 SDValue &Offset, SDValue &SignExtend); 371 372 template<unsigned RegWidth> 373 bool SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos) { 374 return SelectCVTFixedPosOperand(N, FixedPos, RegWidth); 375 } 376 377 bool SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos, unsigned Width); 378 379 bool SelectCMP_SWAP(SDNode *N); 380 381 bool SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm, SDValue &Shift); 382 bool SelectSVECpyDupImm(SDValue N, MVT VT, SDValue &Imm, SDValue &Shift); 383 bool SelectSVELogicalImm(SDValue N, MVT VT, SDValue &Imm, bool Invert); 384 385 bool SelectSVESignedArithImm(SDValue N, SDValue &Imm); 386 bool SelectSVEShiftImm(SDValue N, uint64_t Low, uint64_t High, 387 bool AllowSaturation, SDValue &Imm); 388 389 bool SelectSVEArithImm(SDValue N, MVT VT, SDValue &Imm); 390 bool SelectSVERegRegAddrMode(SDValue N, unsigned Scale, SDValue &Base, 391 SDValue &Offset); 392 393 bool SelectAllActivePredicate(SDValue N); 394 }; 395 } // end anonymous namespace 396 397 /// isIntImmediate - This method tests to see if the node is a constant 398 /// operand. If so Imm will receive the 32-bit value. 399 static bool isIntImmediate(const SDNode *N, uint64_t &Imm) { 400 if (const ConstantSDNode *C = dyn_cast<const ConstantSDNode>(N)) { 401 Imm = C->getZExtValue(); 402 return true; 403 } 404 return false; 405 } 406 407 // isIntImmediate - This method tests to see if a constant operand. 408 // If so Imm will receive the value. 409 static bool isIntImmediate(SDValue N, uint64_t &Imm) { 410 return isIntImmediate(N.getNode(), Imm); 411 } 412 413 // isOpcWithIntImmediate - This method tests to see if the node is a specific 414 // opcode and that it has a immediate integer right operand. 415 // If so Imm will receive the 32 bit value. 416 static bool isOpcWithIntImmediate(const SDNode *N, unsigned Opc, 417 uint64_t &Imm) { 418 return N->getOpcode() == Opc && 419 isIntImmediate(N->getOperand(1).getNode(), Imm); 420 } 421 422 bool AArch64DAGToDAGISel::SelectInlineAsmMemoryOperand( 423 const SDValue &Op, unsigned ConstraintID, std::vector<SDValue> &OutOps) { 424 switch(ConstraintID) { 425 default: 426 llvm_unreachable("Unexpected asm memory constraint"); 427 case InlineAsm::Constraint_m: 428 case InlineAsm::Constraint_o: 429 case InlineAsm::Constraint_Q: 430 // We need to make sure that this one operand does not end up in XZR, thus 431 // require the address to be in a PointerRegClass register. 432 const TargetRegisterInfo *TRI = Subtarget->getRegisterInfo(); 433 const TargetRegisterClass *TRC = TRI->getPointerRegClass(*MF); 434 SDLoc dl(Op); 435 SDValue RC = CurDAG->getTargetConstant(TRC->getID(), dl, MVT::i64); 436 SDValue NewOp = 437 SDValue(CurDAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, 438 dl, Op.getValueType(), 439 Op, RC), 0); 440 OutOps.push_back(NewOp); 441 return false; 442 } 443 return true; 444 } 445 446 /// SelectArithImmed - Select an immediate value that can be represented as 447 /// a 12-bit value shifted left by either 0 or 12. If so, return true with 448 /// Val set to the 12-bit value and Shift set to the shifter operand. 449 bool AArch64DAGToDAGISel::SelectArithImmed(SDValue N, SDValue &Val, 450 SDValue &Shift) { 451 // This function is called from the addsub_shifted_imm ComplexPattern, 452 // which lists [imm] as the list of opcode it's interested in, however 453 // we still need to check whether the operand is actually an immediate 454 // here because the ComplexPattern opcode list is only used in 455 // root-level opcode matching. 456 if (!isa<ConstantSDNode>(N.getNode())) 457 return false; 458 459 uint64_t Immed = cast<ConstantSDNode>(N.getNode())->getZExtValue(); 460 unsigned ShiftAmt; 461 462 if (Immed >> 12 == 0) { 463 ShiftAmt = 0; 464 } else if ((Immed & 0xfff) == 0 && Immed >> 24 == 0) { 465 ShiftAmt = 12; 466 Immed = Immed >> 12; 467 } else 468 return false; 469 470 unsigned ShVal = AArch64_AM::getShifterImm(AArch64_AM::LSL, ShiftAmt); 471 SDLoc dl(N); 472 Val = CurDAG->getTargetConstant(Immed, dl, MVT::i32); 473 Shift = CurDAG->getTargetConstant(ShVal, dl, MVT::i32); 474 return true; 475 } 476 477 /// SelectNegArithImmed - As above, but negates the value before trying to 478 /// select it. 479 bool AArch64DAGToDAGISel::SelectNegArithImmed(SDValue N, SDValue &Val, 480 SDValue &Shift) { 481 // This function is called from the addsub_shifted_imm ComplexPattern, 482 // which lists [imm] as the list of opcode it's interested in, however 483 // we still need to check whether the operand is actually an immediate 484 // here because the ComplexPattern opcode list is only used in 485 // root-level opcode matching. 486 if (!isa<ConstantSDNode>(N.getNode())) 487 return false; 488 489 // The immediate operand must be a 24-bit zero-extended immediate. 490 uint64_t Immed = cast<ConstantSDNode>(N.getNode())->getZExtValue(); 491 492 // This negation is almost always valid, but "cmp wN, #0" and "cmn wN, #0" 493 // have the opposite effect on the C flag, so this pattern mustn't match under 494 // those circumstances. 495 if (Immed == 0) 496 return false; 497 498 if (N.getValueType() == MVT::i32) 499 Immed = ~((uint32_t)Immed) + 1; 500 else 501 Immed = ~Immed + 1ULL; 502 if (Immed & 0xFFFFFFFFFF000000ULL) 503 return false; 504 505 Immed &= 0xFFFFFFULL; 506 return SelectArithImmed(CurDAG->getConstant(Immed, SDLoc(N), MVT::i32), Val, 507 Shift); 508 } 509 510 /// getShiftTypeForNode - Translate a shift node to the corresponding 511 /// ShiftType value. 512 static AArch64_AM::ShiftExtendType getShiftTypeForNode(SDValue N) { 513 switch (N.getOpcode()) { 514 default: 515 return AArch64_AM::InvalidShiftExtend; 516 case ISD::SHL: 517 return AArch64_AM::LSL; 518 case ISD::SRL: 519 return AArch64_AM::LSR; 520 case ISD::SRA: 521 return AArch64_AM::ASR; 522 case ISD::ROTR: 523 return AArch64_AM::ROR; 524 } 525 } 526 527 /// Determine whether it is worth it to fold SHL into the addressing 528 /// mode. 529 static bool isWorthFoldingSHL(SDValue V) { 530 assert(V.getOpcode() == ISD::SHL && "invalid opcode"); 531 // It is worth folding logical shift of up to three places. 532 auto *CSD = dyn_cast<ConstantSDNode>(V.getOperand(1)); 533 if (!CSD) 534 return false; 535 unsigned ShiftVal = CSD->getZExtValue(); 536 if (ShiftVal > 3) 537 return false; 538 539 // Check if this particular node is reused in any non-memory related 540 // operation. If yes, do not try to fold this node into the address 541 // computation, since the computation will be kept. 542 const SDNode *Node = V.getNode(); 543 for (SDNode *UI : Node->uses()) 544 if (!isa<MemSDNode>(*UI)) 545 for (SDNode *UII : UI->uses()) 546 if (!isa<MemSDNode>(*UII)) 547 return false; 548 return true; 549 } 550 551 /// Determine whether it is worth to fold V into an extended register. 552 bool AArch64DAGToDAGISel::isWorthFolding(SDValue V) const { 553 // Trivial if we are optimizing for code size or if there is only 554 // one use of the value. 555 if (CurDAG->shouldOptForSize() || V.hasOneUse()) 556 return true; 557 // If a subtarget has a fastpath LSL we can fold a logical shift into 558 // the addressing mode and save a cycle. 559 if (Subtarget->hasLSLFast() && V.getOpcode() == ISD::SHL && 560 isWorthFoldingSHL(V)) 561 return true; 562 if (Subtarget->hasLSLFast() && V.getOpcode() == ISD::ADD) { 563 const SDValue LHS = V.getOperand(0); 564 const SDValue RHS = V.getOperand(1); 565 if (LHS.getOpcode() == ISD::SHL && isWorthFoldingSHL(LHS)) 566 return true; 567 if (RHS.getOpcode() == ISD::SHL && isWorthFoldingSHL(RHS)) 568 return true; 569 } 570 571 // It hurts otherwise, since the value will be reused. 572 return false; 573 } 574 575 /// SelectShiftedRegister - Select a "shifted register" operand. If the value 576 /// is not shifted, set the Shift operand to default of "LSL 0". The logical 577 /// instructions allow the shifted register to be rotated, but the arithmetic 578 /// instructions do not. The AllowROR parameter specifies whether ROR is 579 /// supported. 580 bool AArch64DAGToDAGISel::SelectShiftedRegister(SDValue N, bool AllowROR, 581 SDValue &Reg, SDValue &Shift) { 582 AArch64_AM::ShiftExtendType ShType = getShiftTypeForNode(N); 583 if (ShType == AArch64_AM::InvalidShiftExtend) 584 return false; 585 if (!AllowROR && ShType == AArch64_AM::ROR) 586 return false; 587 588 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 589 unsigned BitSize = N.getValueSizeInBits(); 590 unsigned Val = RHS->getZExtValue() & (BitSize - 1); 591 unsigned ShVal = AArch64_AM::getShifterImm(ShType, Val); 592 593 Reg = N.getOperand(0); 594 Shift = CurDAG->getTargetConstant(ShVal, SDLoc(N), MVT::i32); 595 return isWorthFolding(N); 596 } 597 598 return false; 599 } 600 601 /// getExtendTypeForNode - Translate an extend node to the corresponding 602 /// ExtendType value. 603 static AArch64_AM::ShiftExtendType 604 getExtendTypeForNode(SDValue N, bool IsLoadStore = false) { 605 if (N.getOpcode() == ISD::SIGN_EXTEND || 606 N.getOpcode() == ISD::SIGN_EXTEND_INREG) { 607 EVT SrcVT; 608 if (N.getOpcode() == ISD::SIGN_EXTEND_INREG) 609 SrcVT = cast<VTSDNode>(N.getOperand(1))->getVT(); 610 else 611 SrcVT = N.getOperand(0).getValueType(); 612 613 if (!IsLoadStore && SrcVT == MVT::i8) 614 return AArch64_AM::SXTB; 615 else if (!IsLoadStore && SrcVT == MVT::i16) 616 return AArch64_AM::SXTH; 617 else if (SrcVT == MVT::i32) 618 return AArch64_AM::SXTW; 619 assert(SrcVT != MVT::i64 && "extend from 64-bits?"); 620 621 return AArch64_AM::InvalidShiftExtend; 622 } else if (N.getOpcode() == ISD::ZERO_EXTEND || 623 N.getOpcode() == ISD::ANY_EXTEND) { 624 EVT SrcVT = N.getOperand(0).getValueType(); 625 if (!IsLoadStore && SrcVT == MVT::i8) 626 return AArch64_AM::UXTB; 627 else if (!IsLoadStore && SrcVT == MVT::i16) 628 return AArch64_AM::UXTH; 629 else if (SrcVT == MVT::i32) 630 return AArch64_AM::UXTW; 631 assert(SrcVT != MVT::i64 && "extend from 64-bits?"); 632 633 return AArch64_AM::InvalidShiftExtend; 634 } else if (N.getOpcode() == ISD::AND) { 635 ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(N.getOperand(1)); 636 if (!CSD) 637 return AArch64_AM::InvalidShiftExtend; 638 uint64_t AndMask = CSD->getZExtValue(); 639 640 switch (AndMask) { 641 default: 642 return AArch64_AM::InvalidShiftExtend; 643 case 0xFF: 644 return !IsLoadStore ? AArch64_AM::UXTB : AArch64_AM::InvalidShiftExtend; 645 case 0xFFFF: 646 return !IsLoadStore ? AArch64_AM::UXTH : AArch64_AM::InvalidShiftExtend; 647 case 0xFFFFFFFF: 648 return AArch64_AM::UXTW; 649 } 650 } 651 652 return AArch64_AM::InvalidShiftExtend; 653 } 654 655 // Helper for SelectMLAV64LaneV128 - Recognize high lane extracts. 656 static bool checkHighLaneIndex(SDNode *DL, SDValue &LaneOp, int &LaneIdx) { 657 if (DL->getOpcode() != AArch64ISD::DUPLANE16 && 658 DL->getOpcode() != AArch64ISD::DUPLANE32) 659 return false; 660 661 SDValue SV = DL->getOperand(0); 662 if (SV.getOpcode() != ISD::INSERT_SUBVECTOR) 663 return false; 664 665 SDValue EV = SV.getOperand(1); 666 if (EV.getOpcode() != ISD::EXTRACT_SUBVECTOR) 667 return false; 668 669 ConstantSDNode *DLidx = cast<ConstantSDNode>(DL->getOperand(1).getNode()); 670 ConstantSDNode *EVidx = cast<ConstantSDNode>(EV.getOperand(1).getNode()); 671 LaneIdx = DLidx->getSExtValue() + EVidx->getSExtValue(); 672 LaneOp = EV.getOperand(0); 673 674 return true; 675 } 676 677 // Helper for SelectOpcV64LaneV128 - Recognize operations where one operand is a 678 // high lane extract. 679 static bool checkV64LaneV128(SDValue Op0, SDValue Op1, SDValue &StdOp, 680 SDValue &LaneOp, int &LaneIdx) { 681 682 if (!checkHighLaneIndex(Op0.getNode(), LaneOp, LaneIdx)) { 683 std::swap(Op0, Op1); 684 if (!checkHighLaneIndex(Op0.getNode(), LaneOp, LaneIdx)) 685 return false; 686 } 687 StdOp = Op1; 688 return true; 689 } 690 691 /// SelectMLAV64LaneV128 - AArch64 supports vector MLAs where one multiplicand 692 /// is a lane in the upper half of a 128-bit vector. Recognize and select this 693 /// so that we don't emit unnecessary lane extracts. 694 bool AArch64DAGToDAGISel::tryMLAV64LaneV128(SDNode *N) { 695 SDLoc dl(N); 696 SDValue Op0 = N->getOperand(0); 697 SDValue Op1 = N->getOperand(1); 698 SDValue MLAOp1; // Will hold ordinary multiplicand for MLA. 699 SDValue MLAOp2; // Will hold lane-accessed multiplicand for MLA. 700 int LaneIdx = -1; // Will hold the lane index. 701 702 if (Op1.getOpcode() != ISD::MUL || 703 !checkV64LaneV128(Op1.getOperand(0), Op1.getOperand(1), MLAOp1, MLAOp2, 704 LaneIdx)) { 705 std::swap(Op0, Op1); 706 if (Op1.getOpcode() != ISD::MUL || 707 !checkV64LaneV128(Op1.getOperand(0), Op1.getOperand(1), MLAOp1, MLAOp2, 708 LaneIdx)) 709 return false; 710 } 711 712 SDValue LaneIdxVal = CurDAG->getTargetConstant(LaneIdx, dl, MVT::i64); 713 714 SDValue Ops[] = { Op0, MLAOp1, MLAOp2, LaneIdxVal }; 715 716 unsigned MLAOpc = ~0U; 717 718 switch (N->getSimpleValueType(0).SimpleTy) { 719 default: 720 llvm_unreachable("Unrecognized MLA."); 721 case MVT::v4i16: 722 MLAOpc = AArch64::MLAv4i16_indexed; 723 break; 724 case MVT::v8i16: 725 MLAOpc = AArch64::MLAv8i16_indexed; 726 break; 727 case MVT::v2i32: 728 MLAOpc = AArch64::MLAv2i32_indexed; 729 break; 730 case MVT::v4i32: 731 MLAOpc = AArch64::MLAv4i32_indexed; 732 break; 733 } 734 735 ReplaceNode(N, CurDAG->getMachineNode(MLAOpc, dl, N->getValueType(0), Ops)); 736 return true; 737 } 738 739 bool AArch64DAGToDAGISel::tryMULLV64LaneV128(unsigned IntNo, SDNode *N) { 740 SDLoc dl(N); 741 SDValue SMULLOp0; 742 SDValue SMULLOp1; 743 int LaneIdx; 744 745 if (!checkV64LaneV128(N->getOperand(1), N->getOperand(2), SMULLOp0, SMULLOp1, 746 LaneIdx)) 747 return false; 748 749 SDValue LaneIdxVal = CurDAG->getTargetConstant(LaneIdx, dl, MVT::i64); 750 751 SDValue Ops[] = { SMULLOp0, SMULLOp1, LaneIdxVal }; 752 753 unsigned SMULLOpc = ~0U; 754 755 if (IntNo == Intrinsic::aarch64_neon_smull) { 756 switch (N->getSimpleValueType(0).SimpleTy) { 757 default: 758 llvm_unreachable("Unrecognized SMULL."); 759 case MVT::v4i32: 760 SMULLOpc = AArch64::SMULLv4i16_indexed; 761 break; 762 case MVT::v2i64: 763 SMULLOpc = AArch64::SMULLv2i32_indexed; 764 break; 765 } 766 } else if (IntNo == Intrinsic::aarch64_neon_umull) { 767 switch (N->getSimpleValueType(0).SimpleTy) { 768 default: 769 llvm_unreachable("Unrecognized SMULL."); 770 case MVT::v4i32: 771 SMULLOpc = AArch64::UMULLv4i16_indexed; 772 break; 773 case MVT::v2i64: 774 SMULLOpc = AArch64::UMULLv2i32_indexed; 775 break; 776 } 777 } else 778 llvm_unreachable("Unrecognized intrinsic."); 779 780 ReplaceNode(N, CurDAG->getMachineNode(SMULLOpc, dl, N->getValueType(0), Ops)); 781 return true; 782 } 783 784 /// Instructions that accept extend modifiers like UXTW expect the register 785 /// being extended to be a GPR32, but the incoming DAG might be acting on a 786 /// GPR64 (either via SEXT_INREG or AND). Extract the appropriate low bits if 787 /// this is the case. 788 static SDValue narrowIfNeeded(SelectionDAG *CurDAG, SDValue N) { 789 if (N.getValueType() == MVT::i32) 790 return N; 791 792 SDLoc dl(N); 793 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32); 794 MachineSDNode *Node = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 795 dl, MVT::i32, N, SubReg); 796 return SDValue(Node, 0); 797 } 798 799 // Returns a suitable CNT/INC/DEC/RDVL multiplier to calculate VSCALE*N. 800 template<signed Low, signed High, signed Scale> 801 bool AArch64DAGToDAGISel::SelectRDVLImm(SDValue N, SDValue &Imm) { 802 if (!isa<ConstantSDNode>(N)) 803 return false; 804 805 int64_t MulImm = cast<ConstantSDNode>(N)->getSExtValue(); 806 if ((MulImm % std::abs(Scale)) == 0) { 807 int64_t RDVLImm = MulImm / Scale; 808 if ((RDVLImm >= Low) && (RDVLImm <= High)) { 809 Imm = CurDAG->getTargetConstant(RDVLImm, SDLoc(N), MVT::i32); 810 return true; 811 } 812 } 813 814 return false; 815 } 816 817 /// SelectArithExtendedRegister - Select a "extended register" operand. This 818 /// operand folds in an extend followed by an optional left shift. 819 bool AArch64DAGToDAGISel::SelectArithExtendedRegister(SDValue N, SDValue &Reg, 820 SDValue &Shift) { 821 unsigned ShiftVal = 0; 822 AArch64_AM::ShiftExtendType Ext; 823 824 if (N.getOpcode() == ISD::SHL) { 825 ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(N.getOperand(1)); 826 if (!CSD) 827 return false; 828 ShiftVal = CSD->getZExtValue(); 829 if (ShiftVal > 4) 830 return false; 831 832 Ext = getExtendTypeForNode(N.getOperand(0)); 833 if (Ext == AArch64_AM::InvalidShiftExtend) 834 return false; 835 836 Reg = N.getOperand(0).getOperand(0); 837 } else { 838 Ext = getExtendTypeForNode(N); 839 if (Ext == AArch64_AM::InvalidShiftExtend) 840 return false; 841 842 Reg = N.getOperand(0); 843 844 // Don't match if free 32-bit -> 64-bit zext can be used instead. Use the 845 // isDef32 as a heuristic for when the operand is likely to be a 32bit def. 846 auto isDef32 = [](SDValue N) { 847 unsigned Opc = N.getOpcode(); 848 return Opc != ISD::TRUNCATE && Opc != TargetOpcode::EXTRACT_SUBREG && 849 Opc != ISD::CopyFromReg && Opc != ISD::AssertSext && 850 Opc != ISD::AssertZext && Opc != ISD::AssertAlign && 851 Opc != ISD::FREEZE; 852 }; 853 if (Ext == AArch64_AM::UXTW && Reg->getValueType(0).getSizeInBits() == 32 && 854 isDef32(Reg)) 855 return false; 856 } 857 858 // AArch64 mandates that the RHS of the operation must use the smallest 859 // register class that could contain the size being extended from. Thus, 860 // if we're folding a (sext i8), we need the RHS to be a GPR32, even though 861 // there might not be an actual 32-bit value in the program. We can 862 // (harmlessly) synthesize one by injected an EXTRACT_SUBREG here. 863 assert(Ext != AArch64_AM::UXTX && Ext != AArch64_AM::SXTX); 864 Reg = narrowIfNeeded(CurDAG, Reg); 865 Shift = CurDAG->getTargetConstant(getArithExtendImm(Ext, ShiftVal), SDLoc(N), 866 MVT::i32); 867 return isWorthFolding(N); 868 } 869 870 /// If there's a use of this ADDlow that's not itself a load/store then we'll 871 /// need to create a real ADD instruction from it anyway and there's no point in 872 /// folding it into the mem op. Theoretically, it shouldn't matter, but there's 873 /// a single pseudo-instruction for an ADRP/ADD pair so over-aggressive folding 874 /// leads to duplicated ADRP instructions. 875 static bool isWorthFoldingADDlow(SDValue N) { 876 for (auto Use : N->uses()) { 877 if (Use->getOpcode() != ISD::LOAD && Use->getOpcode() != ISD::STORE && 878 Use->getOpcode() != ISD::ATOMIC_LOAD && 879 Use->getOpcode() != ISD::ATOMIC_STORE) 880 return false; 881 882 // ldar and stlr have much more restrictive addressing modes (just a 883 // register). 884 if (isStrongerThanMonotonic(cast<MemSDNode>(Use)->getSuccessOrdering())) 885 return false; 886 } 887 888 return true; 889 } 890 891 /// SelectAddrModeIndexedBitWidth - Select a "register plus scaled (un)signed BW-bit 892 /// immediate" address. The "Size" argument is the size in bytes of the memory 893 /// reference, which determines the scale. 894 bool AArch64DAGToDAGISel::SelectAddrModeIndexedBitWidth(SDValue N, bool IsSignedImm, 895 unsigned BW, unsigned Size, 896 SDValue &Base, 897 SDValue &OffImm) { 898 SDLoc dl(N); 899 const DataLayout &DL = CurDAG->getDataLayout(); 900 const TargetLowering *TLI = getTargetLowering(); 901 if (N.getOpcode() == ISD::FrameIndex) { 902 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 903 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL)); 904 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64); 905 return true; 906 } 907 908 // As opposed to the (12-bit) Indexed addressing mode below, the 7/9-bit signed 909 // selected here doesn't support labels/immediates, only base+offset. 910 if (CurDAG->isBaseWithConstantOffset(N)) { 911 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 912 if (IsSignedImm) { 913 int64_t RHSC = RHS->getSExtValue(); 914 unsigned Scale = Log2_32(Size); 915 int64_t Range = 0x1LL << (BW - 1); 916 917 if ((RHSC & (Size - 1)) == 0 && RHSC >= -(Range << Scale) && 918 RHSC < (Range << Scale)) { 919 Base = N.getOperand(0); 920 if (Base.getOpcode() == ISD::FrameIndex) { 921 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 922 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL)); 923 } 924 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64); 925 return true; 926 } 927 } else { 928 // unsigned Immediate 929 uint64_t RHSC = RHS->getZExtValue(); 930 unsigned Scale = Log2_32(Size); 931 uint64_t Range = 0x1ULL << BW; 932 933 if ((RHSC & (Size - 1)) == 0 && RHSC < (Range << Scale)) { 934 Base = N.getOperand(0); 935 if (Base.getOpcode() == ISD::FrameIndex) { 936 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 937 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL)); 938 } 939 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64); 940 return true; 941 } 942 } 943 } 944 } 945 // Base only. The address will be materialized into a register before 946 // the memory is accessed. 947 // add x0, Xbase, #offset 948 // stp x1, x2, [x0] 949 Base = N; 950 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64); 951 return true; 952 } 953 954 /// SelectAddrModeIndexed - Select a "register plus scaled unsigned 12-bit 955 /// immediate" address. The "Size" argument is the size in bytes of the memory 956 /// reference, which determines the scale. 957 bool AArch64DAGToDAGISel::SelectAddrModeIndexed(SDValue N, unsigned Size, 958 SDValue &Base, SDValue &OffImm) { 959 SDLoc dl(N); 960 const DataLayout &DL = CurDAG->getDataLayout(); 961 const TargetLowering *TLI = getTargetLowering(); 962 if (N.getOpcode() == ISD::FrameIndex) { 963 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 964 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL)); 965 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64); 966 return true; 967 } 968 969 if (N.getOpcode() == AArch64ISD::ADDlow && isWorthFoldingADDlow(N)) { 970 GlobalAddressSDNode *GAN = 971 dyn_cast<GlobalAddressSDNode>(N.getOperand(1).getNode()); 972 Base = N.getOperand(0); 973 OffImm = N.getOperand(1); 974 if (!GAN) 975 return true; 976 977 if (GAN->getOffset() % Size == 0 && 978 GAN->getGlobal()->getPointerAlignment(DL) >= Size) 979 return true; 980 } 981 982 if (CurDAG->isBaseWithConstantOffset(N)) { 983 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 984 int64_t RHSC = (int64_t)RHS->getZExtValue(); 985 unsigned Scale = Log2_32(Size); 986 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && RHSC < (0x1000 << Scale)) { 987 Base = N.getOperand(0); 988 if (Base.getOpcode() == ISD::FrameIndex) { 989 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 990 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL)); 991 } 992 OffImm = CurDAG->getTargetConstant(RHSC >> Scale, dl, MVT::i64); 993 return true; 994 } 995 } 996 } 997 998 // Before falling back to our general case, check if the unscaled 999 // instructions can handle this. If so, that's preferable. 1000 if (SelectAddrModeUnscaled(N, Size, Base, OffImm)) 1001 return false; 1002 1003 // Base only. The address will be materialized into a register before 1004 // the memory is accessed. 1005 // add x0, Xbase, #offset 1006 // ldr x0, [x0] 1007 Base = N; 1008 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64); 1009 return true; 1010 } 1011 1012 /// SelectAddrModeUnscaled - Select a "register plus unscaled signed 9-bit 1013 /// immediate" address. This should only match when there is an offset that 1014 /// is not valid for a scaled immediate addressing mode. The "Size" argument 1015 /// is the size in bytes of the memory reference, which is needed here to know 1016 /// what is valid for a scaled immediate. 1017 bool AArch64DAGToDAGISel::SelectAddrModeUnscaled(SDValue N, unsigned Size, 1018 SDValue &Base, 1019 SDValue &OffImm) { 1020 if (!CurDAG->isBaseWithConstantOffset(N)) 1021 return false; 1022 if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 1023 int64_t RHSC = RHS->getSExtValue(); 1024 // If the offset is valid as a scaled immediate, don't match here. 1025 if ((RHSC & (Size - 1)) == 0 && RHSC >= 0 && 1026 RHSC < (0x1000 << Log2_32(Size))) 1027 return false; 1028 if (RHSC >= -256 && RHSC < 256) { 1029 Base = N.getOperand(0); 1030 if (Base.getOpcode() == ISD::FrameIndex) { 1031 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 1032 const TargetLowering *TLI = getTargetLowering(); 1033 Base = CurDAG->getTargetFrameIndex( 1034 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 1035 } 1036 OffImm = CurDAG->getTargetConstant(RHSC, SDLoc(N), MVT::i64); 1037 return true; 1038 } 1039 } 1040 return false; 1041 } 1042 1043 static SDValue Widen(SelectionDAG *CurDAG, SDValue N) { 1044 SDLoc dl(N); 1045 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32); 1046 SDValue ImpDef = SDValue( 1047 CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, dl, MVT::i64), 0); 1048 MachineSDNode *Node = CurDAG->getMachineNode( 1049 TargetOpcode::INSERT_SUBREG, dl, MVT::i64, ImpDef, N, SubReg); 1050 return SDValue(Node, 0); 1051 } 1052 1053 /// Check if the given SHL node (\p N), can be used to form an 1054 /// extended register for an addressing mode. 1055 bool AArch64DAGToDAGISel::SelectExtendedSHL(SDValue N, unsigned Size, 1056 bool WantExtend, SDValue &Offset, 1057 SDValue &SignExtend) { 1058 assert(N.getOpcode() == ISD::SHL && "Invalid opcode."); 1059 ConstantSDNode *CSD = dyn_cast<ConstantSDNode>(N.getOperand(1)); 1060 if (!CSD || (CSD->getZExtValue() & 0x7) != CSD->getZExtValue()) 1061 return false; 1062 1063 SDLoc dl(N); 1064 if (WantExtend) { 1065 AArch64_AM::ShiftExtendType Ext = 1066 getExtendTypeForNode(N.getOperand(0), true); 1067 if (Ext == AArch64_AM::InvalidShiftExtend) 1068 return false; 1069 1070 Offset = narrowIfNeeded(CurDAG, N.getOperand(0).getOperand(0)); 1071 SignExtend = CurDAG->getTargetConstant(Ext == AArch64_AM::SXTW, dl, 1072 MVT::i32); 1073 } else { 1074 Offset = N.getOperand(0); 1075 SignExtend = CurDAG->getTargetConstant(0, dl, MVT::i32); 1076 } 1077 1078 unsigned LegalShiftVal = Log2_32(Size); 1079 unsigned ShiftVal = CSD->getZExtValue(); 1080 1081 if (ShiftVal != 0 && ShiftVal != LegalShiftVal) 1082 return false; 1083 1084 return isWorthFolding(N); 1085 } 1086 1087 bool AArch64DAGToDAGISel::SelectAddrModeWRO(SDValue N, unsigned Size, 1088 SDValue &Base, SDValue &Offset, 1089 SDValue &SignExtend, 1090 SDValue &DoShift) { 1091 if (N.getOpcode() != ISD::ADD) 1092 return false; 1093 SDValue LHS = N.getOperand(0); 1094 SDValue RHS = N.getOperand(1); 1095 SDLoc dl(N); 1096 1097 // We don't want to match immediate adds here, because they are better lowered 1098 // to the register-immediate addressing modes. 1099 if (isa<ConstantSDNode>(LHS) || isa<ConstantSDNode>(RHS)) 1100 return false; 1101 1102 // Check if this particular node is reused in any non-memory related 1103 // operation. If yes, do not try to fold this node into the address 1104 // computation, since the computation will be kept. 1105 const SDNode *Node = N.getNode(); 1106 for (SDNode *UI : Node->uses()) { 1107 if (!isa<MemSDNode>(*UI)) 1108 return false; 1109 } 1110 1111 // Remember if it is worth folding N when it produces extended register. 1112 bool IsExtendedRegisterWorthFolding = isWorthFolding(N); 1113 1114 // Try to match a shifted extend on the RHS. 1115 if (IsExtendedRegisterWorthFolding && RHS.getOpcode() == ISD::SHL && 1116 SelectExtendedSHL(RHS, Size, true, Offset, SignExtend)) { 1117 Base = LHS; 1118 DoShift = CurDAG->getTargetConstant(true, dl, MVT::i32); 1119 return true; 1120 } 1121 1122 // Try to match a shifted extend on the LHS. 1123 if (IsExtendedRegisterWorthFolding && LHS.getOpcode() == ISD::SHL && 1124 SelectExtendedSHL(LHS, Size, true, Offset, SignExtend)) { 1125 Base = RHS; 1126 DoShift = CurDAG->getTargetConstant(true, dl, MVT::i32); 1127 return true; 1128 } 1129 1130 // There was no shift, whatever else we find. 1131 DoShift = CurDAG->getTargetConstant(false, dl, MVT::i32); 1132 1133 AArch64_AM::ShiftExtendType Ext = AArch64_AM::InvalidShiftExtend; 1134 // Try to match an unshifted extend on the LHS. 1135 if (IsExtendedRegisterWorthFolding && 1136 (Ext = getExtendTypeForNode(LHS, true)) != 1137 AArch64_AM::InvalidShiftExtend) { 1138 Base = RHS; 1139 Offset = narrowIfNeeded(CurDAG, LHS.getOperand(0)); 1140 SignExtend = CurDAG->getTargetConstant(Ext == AArch64_AM::SXTW, dl, 1141 MVT::i32); 1142 if (isWorthFolding(LHS)) 1143 return true; 1144 } 1145 1146 // Try to match an unshifted extend on the RHS. 1147 if (IsExtendedRegisterWorthFolding && 1148 (Ext = getExtendTypeForNode(RHS, true)) != 1149 AArch64_AM::InvalidShiftExtend) { 1150 Base = LHS; 1151 Offset = narrowIfNeeded(CurDAG, RHS.getOperand(0)); 1152 SignExtend = CurDAG->getTargetConstant(Ext == AArch64_AM::SXTW, dl, 1153 MVT::i32); 1154 if (isWorthFolding(RHS)) 1155 return true; 1156 } 1157 1158 return false; 1159 } 1160 1161 // Check if the given immediate is preferred by ADD. If an immediate can be 1162 // encoded in an ADD, or it can be encoded in an "ADD LSL #12" and can not be 1163 // encoded by one MOVZ, return true. 1164 static bool isPreferredADD(int64_t ImmOff) { 1165 // Constant in [0x0, 0xfff] can be encoded in ADD. 1166 if ((ImmOff & 0xfffffffffffff000LL) == 0x0LL) 1167 return true; 1168 // Check if it can be encoded in an "ADD LSL #12". 1169 if ((ImmOff & 0xffffffffff000fffLL) == 0x0LL) 1170 // As a single MOVZ is faster than a "ADD of LSL #12", ignore such constant. 1171 return (ImmOff & 0xffffffffff00ffffLL) != 0x0LL && 1172 (ImmOff & 0xffffffffffff0fffLL) != 0x0LL; 1173 return false; 1174 } 1175 1176 bool AArch64DAGToDAGISel::SelectAddrModeXRO(SDValue N, unsigned Size, 1177 SDValue &Base, SDValue &Offset, 1178 SDValue &SignExtend, 1179 SDValue &DoShift) { 1180 if (N.getOpcode() != ISD::ADD) 1181 return false; 1182 SDValue LHS = N.getOperand(0); 1183 SDValue RHS = N.getOperand(1); 1184 SDLoc DL(N); 1185 1186 // Check if this particular node is reused in any non-memory related 1187 // operation. If yes, do not try to fold this node into the address 1188 // computation, since the computation will be kept. 1189 const SDNode *Node = N.getNode(); 1190 for (SDNode *UI : Node->uses()) { 1191 if (!isa<MemSDNode>(*UI)) 1192 return false; 1193 } 1194 1195 // Watch out if RHS is a wide immediate, it can not be selected into 1196 // [BaseReg+Imm] addressing mode. Also it may not be able to be encoded into 1197 // ADD/SUB. Instead it will use [BaseReg + 0] address mode and generate 1198 // instructions like: 1199 // MOV X0, WideImmediate 1200 // ADD X1, BaseReg, X0 1201 // LDR X2, [X1, 0] 1202 // For such situation, using [BaseReg, XReg] addressing mode can save one 1203 // ADD/SUB: 1204 // MOV X0, WideImmediate 1205 // LDR X2, [BaseReg, X0] 1206 if (isa<ConstantSDNode>(RHS)) { 1207 int64_t ImmOff = (int64_t)cast<ConstantSDNode>(RHS)->getZExtValue(); 1208 unsigned Scale = Log2_32(Size); 1209 // Skip the immediate can be selected by load/store addressing mode. 1210 // Also skip the immediate can be encoded by a single ADD (SUB is also 1211 // checked by using -ImmOff). 1212 if ((ImmOff % Size == 0 && ImmOff >= 0 && ImmOff < (0x1000 << Scale)) || 1213 isPreferredADD(ImmOff) || isPreferredADD(-ImmOff)) 1214 return false; 1215 1216 SDValue Ops[] = { RHS }; 1217 SDNode *MOVI = 1218 CurDAG->getMachineNode(AArch64::MOVi64imm, DL, MVT::i64, Ops); 1219 SDValue MOVIV = SDValue(MOVI, 0); 1220 // This ADD of two X register will be selected into [Reg+Reg] mode. 1221 N = CurDAG->getNode(ISD::ADD, DL, MVT::i64, LHS, MOVIV); 1222 } 1223 1224 // Remember if it is worth folding N when it produces extended register. 1225 bool IsExtendedRegisterWorthFolding = isWorthFolding(N); 1226 1227 // Try to match a shifted extend on the RHS. 1228 if (IsExtendedRegisterWorthFolding && RHS.getOpcode() == ISD::SHL && 1229 SelectExtendedSHL(RHS, Size, false, Offset, SignExtend)) { 1230 Base = LHS; 1231 DoShift = CurDAG->getTargetConstant(true, DL, MVT::i32); 1232 return true; 1233 } 1234 1235 // Try to match a shifted extend on the LHS. 1236 if (IsExtendedRegisterWorthFolding && LHS.getOpcode() == ISD::SHL && 1237 SelectExtendedSHL(LHS, Size, false, Offset, SignExtend)) { 1238 Base = RHS; 1239 DoShift = CurDAG->getTargetConstant(true, DL, MVT::i32); 1240 return true; 1241 } 1242 1243 // Match any non-shifted, non-extend, non-immediate add expression. 1244 Base = LHS; 1245 Offset = RHS; 1246 SignExtend = CurDAG->getTargetConstant(false, DL, MVT::i32); 1247 DoShift = CurDAG->getTargetConstant(false, DL, MVT::i32); 1248 // Reg1 + Reg2 is free: no check needed. 1249 return true; 1250 } 1251 1252 SDValue AArch64DAGToDAGISel::createDTuple(ArrayRef<SDValue> Regs) { 1253 static const unsigned RegClassIDs[] = { 1254 AArch64::DDRegClassID, AArch64::DDDRegClassID, AArch64::DDDDRegClassID}; 1255 static const unsigned SubRegs[] = {AArch64::dsub0, AArch64::dsub1, 1256 AArch64::dsub2, AArch64::dsub3}; 1257 1258 return createTuple(Regs, RegClassIDs, SubRegs); 1259 } 1260 1261 SDValue AArch64DAGToDAGISel::createQTuple(ArrayRef<SDValue> Regs) { 1262 static const unsigned RegClassIDs[] = { 1263 AArch64::QQRegClassID, AArch64::QQQRegClassID, AArch64::QQQQRegClassID}; 1264 static const unsigned SubRegs[] = {AArch64::qsub0, AArch64::qsub1, 1265 AArch64::qsub2, AArch64::qsub3}; 1266 1267 return createTuple(Regs, RegClassIDs, SubRegs); 1268 } 1269 1270 SDValue AArch64DAGToDAGISel::createZTuple(ArrayRef<SDValue> Regs) { 1271 static const unsigned RegClassIDs[] = {AArch64::ZPR2RegClassID, 1272 AArch64::ZPR3RegClassID, 1273 AArch64::ZPR4RegClassID}; 1274 static const unsigned SubRegs[] = {AArch64::zsub0, AArch64::zsub1, 1275 AArch64::zsub2, AArch64::zsub3}; 1276 1277 return createTuple(Regs, RegClassIDs, SubRegs); 1278 } 1279 1280 SDValue AArch64DAGToDAGISel::createTuple(ArrayRef<SDValue> Regs, 1281 const unsigned RegClassIDs[], 1282 const unsigned SubRegs[]) { 1283 // There's no special register-class for a vector-list of 1 element: it's just 1284 // a vector. 1285 if (Regs.size() == 1) 1286 return Regs[0]; 1287 1288 assert(Regs.size() >= 2 && Regs.size() <= 4); 1289 1290 SDLoc DL(Regs[0]); 1291 1292 SmallVector<SDValue, 4> Ops; 1293 1294 // First operand of REG_SEQUENCE is the desired RegClass. 1295 Ops.push_back( 1296 CurDAG->getTargetConstant(RegClassIDs[Regs.size() - 2], DL, MVT::i32)); 1297 1298 // Then we get pairs of source & subregister-position for the components. 1299 for (unsigned i = 0; i < Regs.size(); ++i) { 1300 Ops.push_back(Regs[i]); 1301 Ops.push_back(CurDAG->getTargetConstant(SubRegs[i], DL, MVT::i32)); 1302 } 1303 1304 SDNode *N = 1305 CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, MVT::Untyped, Ops); 1306 return SDValue(N, 0); 1307 } 1308 1309 void AArch64DAGToDAGISel::SelectTable(SDNode *N, unsigned NumVecs, unsigned Opc, 1310 bool isExt) { 1311 SDLoc dl(N); 1312 EVT VT = N->getValueType(0); 1313 1314 unsigned ExtOff = isExt; 1315 1316 // Form a REG_SEQUENCE to force register allocation. 1317 unsigned Vec0Off = ExtOff + 1; 1318 SmallVector<SDValue, 4> Regs(N->op_begin() + Vec0Off, 1319 N->op_begin() + Vec0Off + NumVecs); 1320 SDValue RegSeq = createQTuple(Regs); 1321 1322 SmallVector<SDValue, 6> Ops; 1323 if (isExt) 1324 Ops.push_back(N->getOperand(1)); 1325 Ops.push_back(RegSeq); 1326 Ops.push_back(N->getOperand(NumVecs + ExtOff + 1)); 1327 ReplaceNode(N, CurDAG->getMachineNode(Opc, dl, VT, Ops)); 1328 } 1329 1330 bool AArch64DAGToDAGISel::tryIndexedLoad(SDNode *N) { 1331 LoadSDNode *LD = cast<LoadSDNode>(N); 1332 if (LD->isUnindexed()) 1333 return false; 1334 EVT VT = LD->getMemoryVT(); 1335 EVT DstVT = N->getValueType(0); 1336 ISD::MemIndexedMode AM = LD->getAddressingMode(); 1337 bool IsPre = AM == ISD::PRE_INC || AM == ISD::PRE_DEC; 1338 1339 // We're not doing validity checking here. That was done when checking 1340 // if we should mark the load as indexed or not. We're just selecting 1341 // the right instruction. 1342 unsigned Opcode = 0; 1343 1344 ISD::LoadExtType ExtType = LD->getExtensionType(); 1345 bool InsertTo64 = false; 1346 if (VT == MVT::i64) 1347 Opcode = IsPre ? AArch64::LDRXpre : AArch64::LDRXpost; 1348 else if (VT == MVT::i32) { 1349 if (ExtType == ISD::NON_EXTLOAD) 1350 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost; 1351 else if (ExtType == ISD::SEXTLOAD) 1352 Opcode = IsPre ? AArch64::LDRSWpre : AArch64::LDRSWpost; 1353 else { 1354 Opcode = IsPre ? AArch64::LDRWpre : AArch64::LDRWpost; 1355 InsertTo64 = true; 1356 // The result of the load is only i32. It's the subreg_to_reg that makes 1357 // it into an i64. 1358 DstVT = MVT::i32; 1359 } 1360 } else if (VT == MVT::i16) { 1361 if (ExtType == ISD::SEXTLOAD) { 1362 if (DstVT == MVT::i64) 1363 Opcode = IsPre ? AArch64::LDRSHXpre : AArch64::LDRSHXpost; 1364 else 1365 Opcode = IsPre ? AArch64::LDRSHWpre : AArch64::LDRSHWpost; 1366 } else { 1367 Opcode = IsPre ? AArch64::LDRHHpre : AArch64::LDRHHpost; 1368 InsertTo64 = DstVT == MVT::i64; 1369 // The result of the load is only i32. It's the subreg_to_reg that makes 1370 // it into an i64. 1371 DstVT = MVT::i32; 1372 } 1373 } else if (VT == MVT::i8) { 1374 if (ExtType == ISD::SEXTLOAD) { 1375 if (DstVT == MVT::i64) 1376 Opcode = IsPre ? AArch64::LDRSBXpre : AArch64::LDRSBXpost; 1377 else 1378 Opcode = IsPre ? AArch64::LDRSBWpre : AArch64::LDRSBWpost; 1379 } else { 1380 Opcode = IsPre ? AArch64::LDRBBpre : AArch64::LDRBBpost; 1381 InsertTo64 = DstVT == MVT::i64; 1382 // The result of the load is only i32. It's the subreg_to_reg that makes 1383 // it into an i64. 1384 DstVT = MVT::i32; 1385 } 1386 } else if (VT == MVT::f16) { 1387 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost; 1388 } else if (VT == MVT::bf16) { 1389 Opcode = IsPre ? AArch64::LDRHpre : AArch64::LDRHpost; 1390 } else if (VT == MVT::f32) { 1391 Opcode = IsPre ? AArch64::LDRSpre : AArch64::LDRSpost; 1392 } else if (VT == MVT::f64 || VT.is64BitVector()) { 1393 Opcode = IsPre ? AArch64::LDRDpre : AArch64::LDRDpost; 1394 } else if (VT.is128BitVector()) { 1395 Opcode = IsPre ? AArch64::LDRQpre : AArch64::LDRQpost; 1396 } else 1397 return false; 1398 SDValue Chain = LD->getChain(); 1399 SDValue Base = LD->getBasePtr(); 1400 ConstantSDNode *OffsetOp = cast<ConstantSDNode>(LD->getOffset()); 1401 int OffsetVal = (int)OffsetOp->getZExtValue(); 1402 SDLoc dl(N); 1403 SDValue Offset = CurDAG->getTargetConstant(OffsetVal, dl, MVT::i64); 1404 SDValue Ops[] = { Base, Offset, Chain }; 1405 SDNode *Res = CurDAG->getMachineNode(Opcode, dl, MVT::i64, DstVT, 1406 MVT::Other, Ops); 1407 1408 // Transfer memoperands. 1409 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand(); 1410 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Res), {MemOp}); 1411 1412 // Either way, we're replacing the node, so tell the caller that. 1413 SDValue LoadedVal = SDValue(Res, 1); 1414 if (InsertTo64) { 1415 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32); 1416 LoadedVal = 1417 SDValue(CurDAG->getMachineNode( 1418 AArch64::SUBREG_TO_REG, dl, MVT::i64, 1419 CurDAG->getTargetConstant(0, dl, MVT::i64), LoadedVal, 1420 SubReg), 1421 0); 1422 } 1423 1424 ReplaceUses(SDValue(N, 0), LoadedVal); 1425 ReplaceUses(SDValue(N, 1), SDValue(Res, 0)); 1426 ReplaceUses(SDValue(N, 2), SDValue(Res, 2)); 1427 CurDAG->RemoveDeadNode(N); 1428 return true; 1429 } 1430 1431 void AArch64DAGToDAGISel::SelectLoad(SDNode *N, unsigned NumVecs, unsigned Opc, 1432 unsigned SubRegIdx) { 1433 SDLoc dl(N); 1434 EVT VT = N->getValueType(0); 1435 SDValue Chain = N->getOperand(0); 1436 1437 SDValue Ops[] = {N->getOperand(2), // Mem operand; 1438 Chain}; 1439 1440 const EVT ResTys[] = {MVT::Untyped, MVT::Other}; 1441 1442 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 1443 SDValue SuperReg = SDValue(Ld, 0); 1444 for (unsigned i = 0; i < NumVecs; ++i) 1445 ReplaceUses(SDValue(N, i), 1446 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg)); 1447 1448 ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 1)); 1449 1450 // Transfer memoperands. In the case of AArch64::LD64B, there won't be one, 1451 // because it's too simple to have needed special treatment during lowering. 1452 if (auto *MemIntr = dyn_cast<MemIntrinsicSDNode>(N)) { 1453 MachineMemOperand *MemOp = MemIntr->getMemOperand(); 1454 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp}); 1455 } 1456 1457 CurDAG->RemoveDeadNode(N); 1458 } 1459 1460 void AArch64DAGToDAGISel::SelectPostLoad(SDNode *N, unsigned NumVecs, 1461 unsigned Opc, unsigned SubRegIdx) { 1462 SDLoc dl(N); 1463 EVT VT = N->getValueType(0); 1464 SDValue Chain = N->getOperand(0); 1465 1466 SDValue Ops[] = {N->getOperand(1), // Mem operand 1467 N->getOperand(2), // Incremental 1468 Chain}; 1469 1470 const EVT ResTys[] = {MVT::i64, // Type of the write back register 1471 MVT::Untyped, MVT::Other}; 1472 1473 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 1474 1475 // Update uses of write back register 1476 ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 0)); 1477 1478 // Update uses of vector list 1479 SDValue SuperReg = SDValue(Ld, 1); 1480 if (NumVecs == 1) 1481 ReplaceUses(SDValue(N, 0), SuperReg); 1482 else 1483 for (unsigned i = 0; i < NumVecs; ++i) 1484 ReplaceUses(SDValue(N, i), 1485 CurDAG->getTargetExtractSubreg(SubRegIdx + i, dl, VT, SuperReg)); 1486 1487 // Update the chain 1488 ReplaceUses(SDValue(N, NumVecs + 1), SDValue(Ld, 2)); 1489 CurDAG->RemoveDeadNode(N); 1490 } 1491 1492 /// Optimize \param OldBase and \param OldOffset selecting the best addressing 1493 /// mode. Returns a tuple consisting of an Opcode, an SDValue representing the 1494 /// new Base and an SDValue representing the new offset. 1495 std::tuple<unsigned, SDValue, SDValue> 1496 AArch64DAGToDAGISel::findAddrModeSVELoadStore(SDNode *N, unsigned Opc_rr, 1497 unsigned Opc_ri, 1498 const SDValue &OldBase, 1499 const SDValue &OldOffset, 1500 unsigned Scale) { 1501 SDValue NewBase = OldBase; 1502 SDValue NewOffset = OldOffset; 1503 // Detect a possible Reg+Imm addressing mode. 1504 const bool IsRegImm = SelectAddrModeIndexedSVE</*Min=*/-8, /*Max=*/7>( 1505 N, OldBase, NewBase, NewOffset); 1506 1507 // Detect a possible reg+reg addressing mode, but only if we haven't already 1508 // detected a Reg+Imm one. 1509 const bool IsRegReg = 1510 !IsRegImm && SelectSVERegRegAddrMode(OldBase, Scale, NewBase, NewOffset); 1511 1512 // Select the instruction. 1513 return std::make_tuple(IsRegReg ? Opc_rr : Opc_ri, NewBase, NewOffset); 1514 } 1515 1516 void AArch64DAGToDAGISel::SelectPredicatedLoad(SDNode *N, unsigned NumVecs, 1517 unsigned Scale, unsigned Opc_ri, 1518 unsigned Opc_rr, bool IsIntr) { 1519 assert(Scale < 4 && "Invalid scaling value."); 1520 SDLoc DL(N); 1521 EVT VT = N->getValueType(0); 1522 SDValue Chain = N->getOperand(0); 1523 1524 // Optimize addressing mode. 1525 SDValue Base, Offset; 1526 unsigned Opc; 1527 std::tie(Opc, Base, Offset) = findAddrModeSVELoadStore( 1528 N, Opc_rr, Opc_ri, N->getOperand(IsIntr ? 3 : 2), 1529 CurDAG->getTargetConstant(0, DL, MVT::i64), Scale); 1530 1531 SDValue Ops[] = {N->getOperand(IsIntr ? 2 : 1), // Predicate 1532 Base, // Memory operand 1533 Offset, Chain}; 1534 1535 const EVT ResTys[] = {MVT::Untyped, MVT::Other}; 1536 1537 SDNode *Load = CurDAG->getMachineNode(Opc, DL, ResTys, Ops); 1538 SDValue SuperReg = SDValue(Load, 0); 1539 for (unsigned i = 0; i < NumVecs; ++i) 1540 ReplaceUses(SDValue(N, i), CurDAG->getTargetExtractSubreg( 1541 AArch64::zsub0 + i, DL, VT, SuperReg)); 1542 1543 // Copy chain 1544 unsigned ChainIdx = NumVecs; 1545 ReplaceUses(SDValue(N, ChainIdx), SDValue(Load, 1)); 1546 CurDAG->RemoveDeadNode(N); 1547 } 1548 1549 void AArch64DAGToDAGISel::SelectStore(SDNode *N, unsigned NumVecs, 1550 unsigned Opc) { 1551 SDLoc dl(N); 1552 EVT VT = N->getOperand(2)->getValueType(0); 1553 1554 // Form a REG_SEQUENCE to force register allocation. 1555 bool Is128Bit = VT.getSizeInBits() == 128; 1556 SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs); 1557 SDValue RegSeq = Is128Bit ? createQTuple(Regs) : createDTuple(Regs); 1558 1559 SDValue Ops[] = {RegSeq, N->getOperand(NumVecs + 2), N->getOperand(0)}; 1560 SDNode *St = CurDAG->getMachineNode(Opc, dl, N->getValueType(0), Ops); 1561 1562 // Transfer memoperands. 1563 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 1564 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp}); 1565 1566 ReplaceNode(N, St); 1567 } 1568 1569 void AArch64DAGToDAGISel::SelectPredicatedStore(SDNode *N, unsigned NumVecs, 1570 unsigned Scale, unsigned Opc_rr, 1571 unsigned Opc_ri) { 1572 SDLoc dl(N); 1573 1574 // Form a REG_SEQUENCE to force register allocation. 1575 SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs); 1576 SDValue RegSeq = createZTuple(Regs); 1577 1578 // Optimize addressing mode. 1579 unsigned Opc; 1580 SDValue Offset, Base; 1581 std::tie(Opc, Base, Offset) = findAddrModeSVELoadStore( 1582 N, Opc_rr, Opc_ri, N->getOperand(NumVecs + 3), 1583 CurDAG->getTargetConstant(0, dl, MVT::i64), Scale); 1584 1585 SDValue Ops[] = {RegSeq, N->getOperand(NumVecs + 2), // predicate 1586 Base, // address 1587 Offset, // offset 1588 N->getOperand(0)}; // chain 1589 SDNode *St = CurDAG->getMachineNode(Opc, dl, N->getValueType(0), Ops); 1590 1591 ReplaceNode(N, St); 1592 } 1593 1594 bool AArch64DAGToDAGISel::SelectAddrModeFrameIndexSVE(SDValue N, SDValue &Base, 1595 SDValue &OffImm) { 1596 SDLoc dl(N); 1597 const DataLayout &DL = CurDAG->getDataLayout(); 1598 const TargetLowering *TLI = getTargetLowering(); 1599 1600 // Try to match it for the frame address 1601 if (auto FINode = dyn_cast<FrameIndexSDNode>(N)) { 1602 int FI = FINode->getIndex(); 1603 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL)); 1604 OffImm = CurDAG->getTargetConstant(0, dl, MVT::i64); 1605 return true; 1606 } 1607 1608 return false; 1609 } 1610 1611 void AArch64DAGToDAGISel::SelectPostStore(SDNode *N, unsigned NumVecs, 1612 unsigned Opc) { 1613 SDLoc dl(N); 1614 EVT VT = N->getOperand(2)->getValueType(0); 1615 const EVT ResTys[] = {MVT::i64, // Type of the write back register 1616 MVT::Other}; // Type for the Chain 1617 1618 // Form a REG_SEQUENCE to force register allocation. 1619 bool Is128Bit = VT.getSizeInBits() == 128; 1620 SmallVector<SDValue, 4> Regs(N->op_begin() + 1, N->op_begin() + 1 + NumVecs); 1621 SDValue RegSeq = Is128Bit ? createQTuple(Regs) : createDTuple(Regs); 1622 1623 SDValue Ops[] = {RegSeq, 1624 N->getOperand(NumVecs + 1), // base register 1625 N->getOperand(NumVecs + 2), // Incremental 1626 N->getOperand(0)}; // Chain 1627 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 1628 1629 ReplaceNode(N, St); 1630 } 1631 1632 namespace { 1633 /// WidenVector - Given a value in the V64 register class, produce the 1634 /// equivalent value in the V128 register class. 1635 class WidenVector { 1636 SelectionDAG &DAG; 1637 1638 public: 1639 WidenVector(SelectionDAG &DAG) : DAG(DAG) {} 1640 1641 SDValue operator()(SDValue V64Reg) { 1642 EVT VT = V64Reg.getValueType(); 1643 unsigned NarrowSize = VT.getVectorNumElements(); 1644 MVT EltTy = VT.getVectorElementType().getSimpleVT(); 1645 MVT WideTy = MVT::getVectorVT(EltTy, 2 * NarrowSize); 1646 SDLoc DL(V64Reg); 1647 1648 SDValue Undef = 1649 SDValue(DAG.getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, WideTy), 0); 1650 return DAG.getTargetInsertSubreg(AArch64::dsub, DL, WideTy, Undef, V64Reg); 1651 } 1652 }; 1653 } // namespace 1654 1655 /// NarrowVector - Given a value in the V128 register class, produce the 1656 /// equivalent value in the V64 register class. 1657 static SDValue NarrowVector(SDValue V128Reg, SelectionDAG &DAG) { 1658 EVT VT = V128Reg.getValueType(); 1659 unsigned WideSize = VT.getVectorNumElements(); 1660 MVT EltTy = VT.getVectorElementType().getSimpleVT(); 1661 MVT NarrowTy = MVT::getVectorVT(EltTy, WideSize / 2); 1662 1663 return DAG.getTargetExtractSubreg(AArch64::dsub, SDLoc(V128Reg), NarrowTy, 1664 V128Reg); 1665 } 1666 1667 void AArch64DAGToDAGISel::SelectLoadLane(SDNode *N, unsigned NumVecs, 1668 unsigned Opc) { 1669 SDLoc dl(N); 1670 EVT VT = N->getValueType(0); 1671 bool Narrow = VT.getSizeInBits() == 64; 1672 1673 // Form a REG_SEQUENCE to force register allocation. 1674 SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs); 1675 1676 if (Narrow) 1677 transform(Regs, Regs.begin(), 1678 WidenVector(*CurDAG)); 1679 1680 SDValue RegSeq = createQTuple(Regs); 1681 1682 const EVT ResTys[] = {MVT::Untyped, MVT::Other}; 1683 1684 unsigned LaneNo = 1685 cast<ConstantSDNode>(N->getOperand(NumVecs + 2))->getZExtValue(); 1686 1687 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64), 1688 N->getOperand(NumVecs + 3), N->getOperand(0)}; 1689 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 1690 SDValue SuperReg = SDValue(Ld, 0); 1691 1692 EVT WideVT = RegSeq.getOperand(1)->getValueType(0); 1693 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1, 1694 AArch64::qsub2, AArch64::qsub3 }; 1695 for (unsigned i = 0; i < NumVecs; ++i) { 1696 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, SuperReg); 1697 if (Narrow) 1698 NV = NarrowVector(NV, *CurDAG); 1699 ReplaceUses(SDValue(N, i), NV); 1700 } 1701 1702 ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 1)); 1703 CurDAG->RemoveDeadNode(N); 1704 } 1705 1706 void AArch64DAGToDAGISel::SelectPostLoadLane(SDNode *N, unsigned NumVecs, 1707 unsigned Opc) { 1708 SDLoc dl(N); 1709 EVT VT = N->getValueType(0); 1710 bool Narrow = VT.getSizeInBits() == 64; 1711 1712 // Form a REG_SEQUENCE to force register allocation. 1713 SmallVector<SDValue, 4> Regs(N->op_begin() + 1, N->op_begin() + 1 + NumVecs); 1714 1715 if (Narrow) 1716 transform(Regs, Regs.begin(), 1717 WidenVector(*CurDAG)); 1718 1719 SDValue RegSeq = createQTuple(Regs); 1720 1721 const EVT ResTys[] = {MVT::i64, // Type of the write back register 1722 RegSeq->getValueType(0), MVT::Other}; 1723 1724 unsigned LaneNo = 1725 cast<ConstantSDNode>(N->getOperand(NumVecs + 1))->getZExtValue(); 1726 1727 SDValue Ops[] = {RegSeq, 1728 CurDAG->getTargetConstant(LaneNo, dl, 1729 MVT::i64), // Lane Number 1730 N->getOperand(NumVecs + 2), // Base register 1731 N->getOperand(NumVecs + 3), // Incremental 1732 N->getOperand(0)}; 1733 SDNode *Ld = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 1734 1735 // Update uses of the write back register 1736 ReplaceUses(SDValue(N, NumVecs), SDValue(Ld, 0)); 1737 1738 // Update uses of the vector list 1739 SDValue SuperReg = SDValue(Ld, 1); 1740 if (NumVecs == 1) { 1741 ReplaceUses(SDValue(N, 0), 1742 Narrow ? NarrowVector(SuperReg, *CurDAG) : SuperReg); 1743 } else { 1744 EVT WideVT = RegSeq.getOperand(1)->getValueType(0); 1745 static const unsigned QSubs[] = { AArch64::qsub0, AArch64::qsub1, 1746 AArch64::qsub2, AArch64::qsub3 }; 1747 for (unsigned i = 0; i < NumVecs; ++i) { 1748 SDValue NV = CurDAG->getTargetExtractSubreg(QSubs[i], dl, WideVT, 1749 SuperReg); 1750 if (Narrow) 1751 NV = NarrowVector(NV, *CurDAG); 1752 ReplaceUses(SDValue(N, i), NV); 1753 } 1754 } 1755 1756 // Update the Chain 1757 ReplaceUses(SDValue(N, NumVecs + 1), SDValue(Ld, 2)); 1758 CurDAG->RemoveDeadNode(N); 1759 } 1760 1761 void AArch64DAGToDAGISel::SelectStoreLane(SDNode *N, unsigned NumVecs, 1762 unsigned Opc) { 1763 SDLoc dl(N); 1764 EVT VT = N->getOperand(2)->getValueType(0); 1765 bool Narrow = VT.getSizeInBits() == 64; 1766 1767 // Form a REG_SEQUENCE to force register allocation. 1768 SmallVector<SDValue, 4> Regs(N->op_begin() + 2, N->op_begin() + 2 + NumVecs); 1769 1770 if (Narrow) 1771 transform(Regs, Regs.begin(), 1772 WidenVector(*CurDAG)); 1773 1774 SDValue RegSeq = createQTuple(Regs); 1775 1776 unsigned LaneNo = 1777 cast<ConstantSDNode>(N->getOperand(NumVecs + 2))->getZExtValue(); 1778 1779 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64), 1780 N->getOperand(NumVecs + 3), N->getOperand(0)}; 1781 SDNode *St = CurDAG->getMachineNode(Opc, dl, MVT::Other, Ops); 1782 1783 // Transfer memoperands. 1784 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 1785 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp}); 1786 1787 ReplaceNode(N, St); 1788 } 1789 1790 void AArch64DAGToDAGISel::SelectPostStoreLane(SDNode *N, unsigned NumVecs, 1791 unsigned Opc) { 1792 SDLoc dl(N); 1793 EVT VT = N->getOperand(2)->getValueType(0); 1794 bool Narrow = VT.getSizeInBits() == 64; 1795 1796 // Form a REG_SEQUENCE to force register allocation. 1797 SmallVector<SDValue, 4> Regs(N->op_begin() + 1, N->op_begin() + 1 + NumVecs); 1798 1799 if (Narrow) 1800 transform(Regs, Regs.begin(), 1801 WidenVector(*CurDAG)); 1802 1803 SDValue RegSeq = createQTuple(Regs); 1804 1805 const EVT ResTys[] = {MVT::i64, // Type of the write back register 1806 MVT::Other}; 1807 1808 unsigned LaneNo = 1809 cast<ConstantSDNode>(N->getOperand(NumVecs + 1))->getZExtValue(); 1810 1811 SDValue Ops[] = {RegSeq, CurDAG->getTargetConstant(LaneNo, dl, MVT::i64), 1812 N->getOperand(NumVecs + 2), // Base Register 1813 N->getOperand(NumVecs + 3), // Incremental 1814 N->getOperand(0)}; 1815 SDNode *St = CurDAG->getMachineNode(Opc, dl, ResTys, Ops); 1816 1817 // Transfer memoperands. 1818 MachineMemOperand *MemOp = cast<MemIntrinsicSDNode>(N)->getMemOperand(); 1819 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp}); 1820 1821 ReplaceNode(N, St); 1822 } 1823 1824 static bool isBitfieldExtractOpFromAnd(SelectionDAG *CurDAG, SDNode *N, 1825 unsigned &Opc, SDValue &Opd0, 1826 unsigned &LSB, unsigned &MSB, 1827 unsigned NumberOfIgnoredLowBits, 1828 bool BiggerPattern) { 1829 assert(N->getOpcode() == ISD::AND && 1830 "N must be a AND operation to call this function"); 1831 1832 EVT VT = N->getValueType(0); 1833 1834 // Here we can test the type of VT and return false when the type does not 1835 // match, but since it is done prior to that call in the current context 1836 // we turned that into an assert to avoid redundant code. 1837 assert((VT == MVT::i32 || VT == MVT::i64) && 1838 "Type checking must have been done before calling this function"); 1839 1840 // FIXME: simplify-demanded-bits in DAGCombine will probably have 1841 // changed the AND node to a 32-bit mask operation. We'll have to 1842 // undo that as part of the transform here if we want to catch all 1843 // the opportunities. 1844 // Currently the NumberOfIgnoredLowBits argument helps to recover 1845 // form these situations when matching bigger pattern (bitfield insert). 1846 1847 // For unsigned extracts, check for a shift right and mask 1848 uint64_t AndImm = 0; 1849 if (!isOpcWithIntImmediate(N, ISD::AND, AndImm)) 1850 return false; 1851 1852 const SDNode *Op0 = N->getOperand(0).getNode(); 1853 1854 // Because of simplify-demanded-bits in DAGCombine, the mask may have been 1855 // simplified. Try to undo that 1856 AndImm |= maskTrailingOnes<uint64_t>(NumberOfIgnoredLowBits); 1857 1858 // The immediate is a mask of the low bits iff imm & (imm+1) == 0 1859 if (AndImm & (AndImm + 1)) 1860 return false; 1861 1862 bool ClampMSB = false; 1863 uint64_t SrlImm = 0; 1864 // Handle the SRL + ANY_EXTEND case. 1865 if (VT == MVT::i64 && Op0->getOpcode() == ISD::ANY_EXTEND && 1866 isOpcWithIntImmediate(Op0->getOperand(0).getNode(), ISD::SRL, SrlImm)) { 1867 // Extend the incoming operand of the SRL to 64-bit. 1868 Opd0 = Widen(CurDAG, Op0->getOperand(0).getOperand(0)); 1869 // Make sure to clamp the MSB so that we preserve the semantics of the 1870 // original operations. 1871 ClampMSB = true; 1872 } else if (VT == MVT::i32 && Op0->getOpcode() == ISD::TRUNCATE && 1873 isOpcWithIntImmediate(Op0->getOperand(0).getNode(), ISD::SRL, 1874 SrlImm)) { 1875 // If the shift result was truncated, we can still combine them. 1876 Opd0 = Op0->getOperand(0).getOperand(0); 1877 1878 // Use the type of SRL node. 1879 VT = Opd0->getValueType(0); 1880 } else if (isOpcWithIntImmediate(Op0, ISD::SRL, SrlImm)) { 1881 Opd0 = Op0->getOperand(0); 1882 ClampMSB = (VT == MVT::i32); 1883 } else if (BiggerPattern) { 1884 // Let's pretend a 0 shift right has been performed. 1885 // The resulting code will be at least as good as the original one 1886 // plus it may expose more opportunities for bitfield insert pattern. 1887 // FIXME: Currently we limit this to the bigger pattern, because 1888 // some optimizations expect AND and not UBFM. 1889 Opd0 = N->getOperand(0); 1890 } else 1891 return false; 1892 1893 // Bail out on large immediates. This happens when no proper 1894 // combining/constant folding was performed. 1895 if (!BiggerPattern && (SrlImm <= 0 || SrlImm >= VT.getSizeInBits())) { 1896 LLVM_DEBUG( 1897 (dbgs() << N 1898 << ": Found large shift immediate, this should not happen\n")); 1899 return false; 1900 } 1901 1902 LSB = SrlImm; 1903 MSB = SrlImm + (VT == MVT::i32 ? countTrailingOnes<uint32_t>(AndImm) 1904 : countTrailingOnes<uint64_t>(AndImm)) - 1905 1; 1906 if (ClampMSB) 1907 // Since we're moving the extend before the right shift operation, we need 1908 // to clamp the MSB to make sure we don't shift in undefined bits instead of 1909 // the zeros which would get shifted in with the original right shift 1910 // operation. 1911 MSB = MSB > 31 ? 31 : MSB; 1912 1913 Opc = VT == MVT::i32 ? AArch64::UBFMWri : AArch64::UBFMXri; 1914 return true; 1915 } 1916 1917 static bool isBitfieldExtractOpFromSExtInReg(SDNode *N, unsigned &Opc, 1918 SDValue &Opd0, unsigned &Immr, 1919 unsigned &Imms) { 1920 assert(N->getOpcode() == ISD::SIGN_EXTEND_INREG); 1921 1922 EVT VT = N->getValueType(0); 1923 unsigned BitWidth = VT.getSizeInBits(); 1924 assert((VT == MVT::i32 || VT == MVT::i64) && 1925 "Type checking must have been done before calling this function"); 1926 1927 SDValue Op = N->getOperand(0); 1928 if (Op->getOpcode() == ISD::TRUNCATE) { 1929 Op = Op->getOperand(0); 1930 VT = Op->getValueType(0); 1931 BitWidth = VT.getSizeInBits(); 1932 } 1933 1934 uint64_t ShiftImm; 1935 if (!isOpcWithIntImmediate(Op.getNode(), ISD::SRL, ShiftImm) && 1936 !isOpcWithIntImmediate(Op.getNode(), ISD::SRA, ShiftImm)) 1937 return false; 1938 1939 unsigned Width = cast<VTSDNode>(N->getOperand(1))->getVT().getSizeInBits(); 1940 if (ShiftImm + Width > BitWidth) 1941 return false; 1942 1943 Opc = (VT == MVT::i32) ? AArch64::SBFMWri : AArch64::SBFMXri; 1944 Opd0 = Op.getOperand(0); 1945 Immr = ShiftImm; 1946 Imms = ShiftImm + Width - 1; 1947 return true; 1948 } 1949 1950 static bool isSeveralBitsExtractOpFromShr(SDNode *N, unsigned &Opc, 1951 SDValue &Opd0, unsigned &LSB, 1952 unsigned &MSB) { 1953 // We are looking for the following pattern which basically extracts several 1954 // continuous bits from the source value and places it from the LSB of the 1955 // destination value, all other bits of the destination value or set to zero: 1956 // 1957 // Value2 = AND Value, MaskImm 1958 // SRL Value2, ShiftImm 1959 // 1960 // with MaskImm >> ShiftImm to search for the bit width. 1961 // 1962 // This gets selected into a single UBFM: 1963 // 1964 // UBFM Value, ShiftImm, BitWide + SrlImm -1 1965 // 1966 1967 if (N->getOpcode() != ISD::SRL) 1968 return false; 1969 1970 uint64_t AndMask = 0; 1971 if (!isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::AND, AndMask)) 1972 return false; 1973 1974 Opd0 = N->getOperand(0).getOperand(0); 1975 1976 uint64_t SrlImm = 0; 1977 if (!isIntImmediate(N->getOperand(1), SrlImm)) 1978 return false; 1979 1980 // Check whether we really have several bits extract here. 1981 unsigned BitWide = 64 - countLeadingOnes(~(AndMask >> SrlImm)); 1982 if (BitWide && isMask_64(AndMask >> SrlImm)) { 1983 if (N->getValueType(0) == MVT::i32) 1984 Opc = AArch64::UBFMWri; 1985 else 1986 Opc = AArch64::UBFMXri; 1987 1988 LSB = SrlImm; 1989 MSB = BitWide + SrlImm - 1; 1990 return true; 1991 } 1992 1993 return false; 1994 } 1995 1996 static bool isBitfieldExtractOpFromShr(SDNode *N, unsigned &Opc, SDValue &Opd0, 1997 unsigned &Immr, unsigned &Imms, 1998 bool BiggerPattern) { 1999 assert((N->getOpcode() == ISD::SRA || N->getOpcode() == ISD::SRL) && 2000 "N must be a SHR/SRA operation to call this function"); 2001 2002 EVT VT = N->getValueType(0); 2003 2004 // Here we can test the type of VT and return false when the type does not 2005 // match, but since it is done prior to that call in the current context 2006 // we turned that into an assert to avoid redundant code. 2007 assert((VT == MVT::i32 || VT == MVT::i64) && 2008 "Type checking must have been done before calling this function"); 2009 2010 // Check for AND + SRL doing several bits extract. 2011 if (isSeveralBitsExtractOpFromShr(N, Opc, Opd0, Immr, Imms)) 2012 return true; 2013 2014 // We're looking for a shift of a shift. 2015 uint64_t ShlImm = 0; 2016 uint64_t TruncBits = 0; 2017 if (isOpcWithIntImmediate(N->getOperand(0).getNode(), ISD::SHL, ShlImm)) { 2018 Opd0 = N->getOperand(0).getOperand(0); 2019 } else if (VT == MVT::i32 && N->getOpcode() == ISD::SRL && 2020 N->getOperand(0).getNode()->getOpcode() == ISD::TRUNCATE) { 2021 // We are looking for a shift of truncate. Truncate from i64 to i32 could 2022 // be considered as setting high 32 bits as zero. Our strategy here is to 2023 // always generate 64bit UBFM. This consistency will help the CSE pass 2024 // later find more redundancy. 2025 Opd0 = N->getOperand(0).getOperand(0); 2026 TruncBits = Opd0->getValueType(0).getSizeInBits() - VT.getSizeInBits(); 2027 VT = Opd0.getValueType(); 2028 assert(VT == MVT::i64 && "the promoted type should be i64"); 2029 } else if (BiggerPattern) { 2030 // Let's pretend a 0 shift left has been performed. 2031 // FIXME: Currently we limit this to the bigger pattern case, 2032 // because some optimizations expect AND and not UBFM 2033 Opd0 = N->getOperand(0); 2034 } else 2035 return false; 2036 2037 // Missing combines/constant folding may have left us with strange 2038 // constants. 2039 if (ShlImm >= VT.getSizeInBits()) { 2040 LLVM_DEBUG( 2041 (dbgs() << N 2042 << ": Found large shift immediate, this should not happen\n")); 2043 return false; 2044 } 2045 2046 uint64_t SrlImm = 0; 2047 if (!isIntImmediate(N->getOperand(1), SrlImm)) 2048 return false; 2049 2050 assert(SrlImm > 0 && SrlImm < VT.getSizeInBits() && 2051 "bad amount in shift node!"); 2052 int immr = SrlImm - ShlImm; 2053 Immr = immr < 0 ? immr + VT.getSizeInBits() : immr; 2054 Imms = VT.getSizeInBits() - ShlImm - TruncBits - 1; 2055 // SRA requires a signed extraction 2056 if (VT == MVT::i32) 2057 Opc = N->getOpcode() == ISD::SRA ? AArch64::SBFMWri : AArch64::UBFMWri; 2058 else 2059 Opc = N->getOpcode() == ISD::SRA ? AArch64::SBFMXri : AArch64::UBFMXri; 2060 return true; 2061 } 2062 2063 bool AArch64DAGToDAGISel::tryBitfieldExtractOpFromSExt(SDNode *N) { 2064 assert(N->getOpcode() == ISD::SIGN_EXTEND); 2065 2066 EVT VT = N->getValueType(0); 2067 EVT NarrowVT = N->getOperand(0)->getValueType(0); 2068 if (VT != MVT::i64 || NarrowVT != MVT::i32) 2069 return false; 2070 2071 uint64_t ShiftImm; 2072 SDValue Op = N->getOperand(0); 2073 if (!isOpcWithIntImmediate(Op.getNode(), ISD::SRA, ShiftImm)) 2074 return false; 2075 2076 SDLoc dl(N); 2077 // Extend the incoming operand of the shift to 64-bits. 2078 SDValue Opd0 = Widen(CurDAG, Op.getOperand(0)); 2079 unsigned Immr = ShiftImm; 2080 unsigned Imms = NarrowVT.getSizeInBits() - 1; 2081 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT), 2082 CurDAG->getTargetConstant(Imms, dl, VT)}; 2083 CurDAG->SelectNodeTo(N, AArch64::SBFMXri, VT, Ops); 2084 return true; 2085 } 2086 2087 /// Try to form fcvtl2 instructions from a floating-point extend of a high-half 2088 /// extract of a subvector. 2089 bool AArch64DAGToDAGISel::tryHighFPExt(SDNode *N) { 2090 assert(N->getOpcode() == ISD::FP_EXTEND); 2091 2092 // There are 2 forms of fcvtl2 - extend to double or extend to float. 2093 SDValue Extract = N->getOperand(0); 2094 EVT VT = N->getValueType(0); 2095 EVT NarrowVT = Extract.getValueType(); 2096 if ((VT != MVT::v2f64 || NarrowVT != MVT::v2f32) && 2097 (VT != MVT::v4f32 || NarrowVT != MVT::v4f16)) 2098 return false; 2099 2100 // Optionally look past a bitcast. 2101 Extract = peekThroughBitcasts(Extract); 2102 if (Extract.getOpcode() != ISD::EXTRACT_SUBVECTOR) 2103 return false; 2104 2105 // Match extract from start of high half index. 2106 // Example: v8i16 -> v4i16 means the extract must begin at index 4. 2107 unsigned ExtractIndex = Extract.getConstantOperandVal(1); 2108 if (ExtractIndex != Extract.getValueType().getVectorNumElements()) 2109 return false; 2110 2111 auto Opcode = VT == MVT::v2f64 ? AArch64::FCVTLv4i32 : AArch64::FCVTLv8i16; 2112 CurDAG->SelectNodeTo(N, Opcode, VT, Extract.getOperand(0)); 2113 return true; 2114 } 2115 2116 static bool isBitfieldExtractOp(SelectionDAG *CurDAG, SDNode *N, unsigned &Opc, 2117 SDValue &Opd0, unsigned &Immr, unsigned &Imms, 2118 unsigned NumberOfIgnoredLowBits = 0, 2119 bool BiggerPattern = false) { 2120 if (N->getValueType(0) != MVT::i32 && N->getValueType(0) != MVT::i64) 2121 return false; 2122 2123 switch (N->getOpcode()) { 2124 default: 2125 if (!N->isMachineOpcode()) 2126 return false; 2127 break; 2128 case ISD::AND: 2129 return isBitfieldExtractOpFromAnd(CurDAG, N, Opc, Opd0, Immr, Imms, 2130 NumberOfIgnoredLowBits, BiggerPattern); 2131 case ISD::SRL: 2132 case ISD::SRA: 2133 return isBitfieldExtractOpFromShr(N, Opc, Opd0, Immr, Imms, BiggerPattern); 2134 2135 case ISD::SIGN_EXTEND_INREG: 2136 return isBitfieldExtractOpFromSExtInReg(N, Opc, Opd0, Immr, Imms); 2137 } 2138 2139 unsigned NOpc = N->getMachineOpcode(); 2140 switch (NOpc) { 2141 default: 2142 return false; 2143 case AArch64::SBFMWri: 2144 case AArch64::UBFMWri: 2145 case AArch64::SBFMXri: 2146 case AArch64::UBFMXri: 2147 Opc = NOpc; 2148 Opd0 = N->getOperand(0); 2149 Immr = cast<ConstantSDNode>(N->getOperand(1).getNode())->getZExtValue(); 2150 Imms = cast<ConstantSDNode>(N->getOperand(2).getNode())->getZExtValue(); 2151 return true; 2152 } 2153 // Unreachable 2154 return false; 2155 } 2156 2157 bool AArch64DAGToDAGISel::tryBitfieldExtractOp(SDNode *N) { 2158 unsigned Opc, Immr, Imms; 2159 SDValue Opd0; 2160 if (!isBitfieldExtractOp(CurDAG, N, Opc, Opd0, Immr, Imms)) 2161 return false; 2162 2163 EVT VT = N->getValueType(0); 2164 SDLoc dl(N); 2165 2166 // If the bit extract operation is 64bit but the original type is 32bit, we 2167 // need to add one EXTRACT_SUBREG. 2168 if ((Opc == AArch64::SBFMXri || Opc == AArch64::UBFMXri) && VT == MVT::i32) { 2169 SDValue Ops64[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, MVT::i64), 2170 CurDAG->getTargetConstant(Imms, dl, MVT::i64)}; 2171 2172 SDNode *BFM = CurDAG->getMachineNode(Opc, dl, MVT::i64, Ops64); 2173 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, dl, MVT::i32); 2174 ReplaceNode(N, CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, dl, 2175 MVT::i32, SDValue(BFM, 0), SubReg)); 2176 return true; 2177 } 2178 2179 SDValue Ops[] = {Opd0, CurDAG->getTargetConstant(Immr, dl, VT), 2180 CurDAG->getTargetConstant(Imms, dl, VT)}; 2181 CurDAG->SelectNodeTo(N, Opc, VT, Ops); 2182 return true; 2183 } 2184 2185 /// Does DstMask form a complementary pair with the mask provided by 2186 /// BitsToBeInserted, suitable for use in a BFI instruction. Roughly speaking, 2187 /// this asks whether DstMask zeroes precisely those bits that will be set by 2188 /// the other half. 2189 static bool isBitfieldDstMask(uint64_t DstMask, const APInt &BitsToBeInserted, 2190 unsigned NumberOfIgnoredHighBits, EVT VT) { 2191 assert((VT == MVT::i32 || VT == MVT::i64) && 2192 "i32 or i64 mask type expected!"); 2193 unsigned BitWidth = VT.getSizeInBits() - NumberOfIgnoredHighBits; 2194 2195 APInt SignificantDstMask = APInt(BitWidth, DstMask); 2196 APInt SignificantBitsToBeInserted = BitsToBeInserted.zextOrTrunc(BitWidth); 2197 2198 return (SignificantDstMask & SignificantBitsToBeInserted) == 0 && 2199 (SignificantDstMask | SignificantBitsToBeInserted).isAllOnes(); 2200 } 2201 2202 // Look for bits that will be useful for later uses. 2203 // A bit is consider useless as soon as it is dropped and never used 2204 // before it as been dropped. 2205 // E.g., looking for useful bit of x 2206 // 1. y = x & 0x7 2207 // 2. z = y >> 2 2208 // After #1, x useful bits are 0x7, then the useful bits of x, live through 2209 // y. 2210 // After #2, the useful bits of x are 0x4. 2211 // However, if x is used on an unpredicatable instruction, then all its bits 2212 // are useful. 2213 // E.g. 2214 // 1. y = x & 0x7 2215 // 2. z = y >> 2 2216 // 3. str x, [@x] 2217 static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth = 0); 2218 2219 static void getUsefulBitsFromAndWithImmediate(SDValue Op, APInt &UsefulBits, 2220 unsigned Depth) { 2221 uint64_t Imm = 2222 cast<const ConstantSDNode>(Op.getOperand(1).getNode())->getZExtValue(); 2223 Imm = AArch64_AM::decodeLogicalImmediate(Imm, UsefulBits.getBitWidth()); 2224 UsefulBits &= APInt(UsefulBits.getBitWidth(), Imm); 2225 getUsefulBits(Op, UsefulBits, Depth + 1); 2226 } 2227 2228 static void getUsefulBitsFromBitfieldMoveOpd(SDValue Op, APInt &UsefulBits, 2229 uint64_t Imm, uint64_t MSB, 2230 unsigned Depth) { 2231 // inherit the bitwidth value 2232 APInt OpUsefulBits(UsefulBits); 2233 OpUsefulBits = 1; 2234 2235 if (MSB >= Imm) { 2236 OpUsefulBits <<= MSB - Imm + 1; 2237 --OpUsefulBits; 2238 // The interesting part will be in the lower part of the result 2239 getUsefulBits(Op, OpUsefulBits, Depth + 1); 2240 // The interesting part was starting at Imm in the argument 2241 OpUsefulBits <<= Imm; 2242 } else { 2243 OpUsefulBits <<= MSB + 1; 2244 --OpUsefulBits; 2245 // The interesting part will be shifted in the result 2246 OpUsefulBits <<= OpUsefulBits.getBitWidth() - Imm; 2247 getUsefulBits(Op, OpUsefulBits, Depth + 1); 2248 // The interesting part was at zero in the argument 2249 OpUsefulBits.lshrInPlace(OpUsefulBits.getBitWidth() - Imm); 2250 } 2251 2252 UsefulBits &= OpUsefulBits; 2253 } 2254 2255 static void getUsefulBitsFromUBFM(SDValue Op, APInt &UsefulBits, 2256 unsigned Depth) { 2257 uint64_t Imm = 2258 cast<const ConstantSDNode>(Op.getOperand(1).getNode())->getZExtValue(); 2259 uint64_t MSB = 2260 cast<const ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue(); 2261 2262 getUsefulBitsFromBitfieldMoveOpd(Op, UsefulBits, Imm, MSB, Depth); 2263 } 2264 2265 static void getUsefulBitsFromOrWithShiftedReg(SDValue Op, APInt &UsefulBits, 2266 unsigned Depth) { 2267 uint64_t ShiftTypeAndValue = 2268 cast<const ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue(); 2269 APInt Mask(UsefulBits); 2270 Mask.clearAllBits(); 2271 Mask.flipAllBits(); 2272 2273 if (AArch64_AM::getShiftType(ShiftTypeAndValue) == AArch64_AM::LSL) { 2274 // Shift Left 2275 uint64_t ShiftAmt = AArch64_AM::getShiftValue(ShiftTypeAndValue); 2276 Mask <<= ShiftAmt; 2277 getUsefulBits(Op, Mask, Depth + 1); 2278 Mask.lshrInPlace(ShiftAmt); 2279 } else if (AArch64_AM::getShiftType(ShiftTypeAndValue) == AArch64_AM::LSR) { 2280 // Shift Right 2281 // We do not handle AArch64_AM::ASR, because the sign will change the 2282 // number of useful bits 2283 uint64_t ShiftAmt = AArch64_AM::getShiftValue(ShiftTypeAndValue); 2284 Mask.lshrInPlace(ShiftAmt); 2285 getUsefulBits(Op, Mask, Depth + 1); 2286 Mask <<= ShiftAmt; 2287 } else 2288 return; 2289 2290 UsefulBits &= Mask; 2291 } 2292 2293 static void getUsefulBitsFromBFM(SDValue Op, SDValue Orig, APInt &UsefulBits, 2294 unsigned Depth) { 2295 uint64_t Imm = 2296 cast<const ConstantSDNode>(Op.getOperand(2).getNode())->getZExtValue(); 2297 uint64_t MSB = 2298 cast<const ConstantSDNode>(Op.getOperand(3).getNode())->getZExtValue(); 2299 2300 APInt OpUsefulBits(UsefulBits); 2301 OpUsefulBits = 1; 2302 2303 APInt ResultUsefulBits(UsefulBits.getBitWidth(), 0); 2304 ResultUsefulBits.flipAllBits(); 2305 APInt Mask(UsefulBits.getBitWidth(), 0); 2306 2307 getUsefulBits(Op, ResultUsefulBits, Depth + 1); 2308 2309 if (MSB >= Imm) { 2310 // The instruction is a BFXIL. 2311 uint64_t Width = MSB - Imm + 1; 2312 uint64_t LSB = Imm; 2313 2314 OpUsefulBits <<= Width; 2315 --OpUsefulBits; 2316 2317 if (Op.getOperand(1) == Orig) { 2318 // Copy the low bits from the result to bits starting from LSB. 2319 Mask = ResultUsefulBits & OpUsefulBits; 2320 Mask <<= LSB; 2321 } 2322 2323 if (Op.getOperand(0) == Orig) 2324 // Bits starting from LSB in the input contribute to the result. 2325 Mask |= (ResultUsefulBits & ~OpUsefulBits); 2326 } else { 2327 // The instruction is a BFI. 2328 uint64_t Width = MSB + 1; 2329 uint64_t LSB = UsefulBits.getBitWidth() - Imm; 2330 2331 OpUsefulBits <<= Width; 2332 --OpUsefulBits; 2333 OpUsefulBits <<= LSB; 2334 2335 if (Op.getOperand(1) == Orig) { 2336 // Copy the bits from the result to the zero bits. 2337 Mask = ResultUsefulBits & OpUsefulBits; 2338 Mask.lshrInPlace(LSB); 2339 } 2340 2341 if (Op.getOperand(0) == Orig) 2342 Mask |= (ResultUsefulBits & ~OpUsefulBits); 2343 } 2344 2345 UsefulBits &= Mask; 2346 } 2347 2348 static void getUsefulBitsForUse(SDNode *UserNode, APInt &UsefulBits, 2349 SDValue Orig, unsigned Depth) { 2350 2351 // Users of this node should have already been instruction selected 2352 // FIXME: Can we turn that into an assert? 2353 if (!UserNode->isMachineOpcode()) 2354 return; 2355 2356 switch (UserNode->getMachineOpcode()) { 2357 default: 2358 return; 2359 case AArch64::ANDSWri: 2360 case AArch64::ANDSXri: 2361 case AArch64::ANDWri: 2362 case AArch64::ANDXri: 2363 // We increment Depth only when we call the getUsefulBits 2364 return getUsefulBitsFromAndWithImmediate(SDValue(UserNode, 0), UsefulBits, 2365 Depth); 2366 case AArch64::UBFMWri: 2367 case AArch64::UBFMXri: 2368 return getUsefulBitsFromUBFM(SDValue(UserNode, 0), UsefulBits, Depth); 2369 2370 case AArch64::ORRWrs: 2371 case AArch64::ORRXrs: 2372 if (UserNode->getOperand(0) != Orig && UserNode->getOperand(1) == Orig) 2373 getUsefulBitsFromOrWithShiftedReg(SDValue(UserNode, 0), UsefulBits, 2374 Depth); 2375 return; 2376 case AArch64::BFMWri: 2377 case AArch64::BFMXri: 2378 return getUsefulBitsFromBFM(SDValue(UserNode, 0), Orig, UsefulBits, Depth); 2379 2380 case AArch64::STRBBui: 2381 case AArch64::STURBBi: 2382 if (UserNode->getOperand(0) != Orig) 2383 return; 2384 UsefulBits &= APInt(UsefulBits.getBitWidth(), 0xff); 2385 return; 2386 2387 case AArch64::STRHHui: 2388 case AArch64::STURHHi: 2389 if (UserNode->getOperand(0) != Orig) 2390 return; 2391 UsefulBits &= APInt(UsefulBits.getBitWidth(), 0xffff); 2392 return; 2393 } 2394 } 2395 2396 static void getUsefulBits(SDValue Op, APInt &UsefulBits, unsigned Depth) { 2397 if (Depth >= SelectionDAG::MaxRecursionDepth) 2398 return; 2399 // Initialize UsefulBits 2400 if (!Depth) { 2401 unsigned Bitwidth = Op.getScalarValueSizeInBits(); 2402 // At the beginning, assume every produced bits is useful 2403 UsefulBits = APInt(Bitwidth, 0); 2404 UsefulBits.flipAllBits(); 2405 } 2406 APInt UsersUsefulBits(UsefulBits.getBitWidth(), 0); 2407 2408 for (SDNode *Node : Op.getNode()->uses()) { 2409 // A use cannot produce useful bits 2410 APInt UsefulBitsForUse = APInt(UsefulBits); 2411 getUsefulBitsForUse(Node, UsefulBitsForUse, Op, Depth); 2412 UsersUsefulBits |= UsefulBitsForUse; 2413 } 2414 // UsefulBits contains the produced bits that are meaningful for the 2415 // current definition, thus a user cannot make a bit meaningful at 2416 // this point 2417 UsefulBits &= UsersUsefulBits; 2418 } 2419 2420 /// Create a machine node performing a notional SHL of Op by ShlAmount. If 2421 /// ShlAmount is negative, do a (logical) right-shift instead. If ShlAmount is 2422 /// 0, return Op unchanged. 2423 static SDValue getLeftShift(SelectionDAG *CurDAG, SDValue Op, int ShlAmount) { 2424 if (ShlAmount == 0) 2425 return Op; 2426 2427 EVT VT = Op.getValueType(); 2428 SDLoc dl(Op); 2429 unsigned BitWidth = VT.getSizeInBits(); 2430 unsigned UBFMOpc = BitWidth == 32 ? AArch64::UBFMWri : AArch64::UBFMXri; 2431 2432 SDNode *ShiftNode; 2433 if (ShlAmount > 0) { 2434 // LSL wD, wN, #Amt == UBFM wD, wN, #32-Amt, #31-Amt 2435 ShiftNode = CurDAG->getMachineNode( 2436 UBFMOpc, dl, VT, Op, 2437 CurDAG->getTargetConstant(BitWidth - ShlAmount, dl, VT), 2438 CurDAG->getTargetConstant(BitWidth - 1 - ShlAmount, dl, VT)); 2439 } else { 2440 // LSR wD, wN, #Amt == UBFM wD, wN, #Amt, #32-1 2441 assert(ShlAmount < 0 && "expected right shift"); 2442 int ShrAmount = -ShlAmount; 2443 ShiftNode = CurDAG->getMachineNode( 2444 UBFMOpc, dl, VT, Op, CurDAG->getTargetConstant(ShrAmount, dl, VT), 2445 CurDAG->getTargetConstant(BitWidth - 1, dl, VT)); 2446 } 2447 2448 return SDValue(ShiftNode, 0); 2449 } 2450 2451 /// Does this tree qualify as an attempt to move a bitfield into position, 2452 /// essentially "(and (shl VAL, N), Mask)". 2453 static bool isBitfieldPositioningOp(SelectionDAG *CurDAG, SDValue Op, 2454 bool BiggerPattern, 2455 SDValue &Src, int &ShiftAmount, 2456 int &MaskWidth) { 2457 EVT VT = Op.getValueType(); 2458 unsigned BitWidth = VT.getSizeInBits(); 2459 (void)BitWidth; 2460 assert(BitWidth == 32 || BitWidth == 64); 2461 2462 KnownBits Known = CurDAG->computeKnownBits(Op); 2463 2464 // Non-zero in the sense that they're not provably zero, which is the key 2465 // point if we want to use this value 2466 uint64_t NonZeroBits = (~Known.Zero).getZExtValue(); 2467 2468 // Discard a constant AND mask if present. It's safe because the node will 2469 // already have been factored into the computeKnownBits calculation above. 2470 uint64_t AndImm; 2471 if (isOpcWithIntImmediate(Op.getNode(), ISD::AND, AndImm)) { 2472 assert((~APInt(BitWidth, AndImm) & ~Known.Zero) == 0); 2473 Op = Op.getOperand(0); 2474 } 2475 2476 // Don't match if the SHL has more than one use, since then we'll end up 2477 // generating SHL+UBFIZ instead of just keeping SHL+AND. 2478 if (!BiggerPattern && !Op.hasOneUse()) 2479 return false; 2480 2481 uint64_t ShlImm; 2482 if (!isOpcWithIntImmediate(Op.getNode(), ISD::SHL, ShlImm)) 2483 return false; 2484 Op = Op.getOperand(0); 2485 2486 if (!isShiftedMask_64(NonZeroBits)) 2487 return false; 2488 2489 ShiftAmount = countTrailingZeros(NonZeroBits); 2490 MaskWidth = countTrailingOnes(NonZeroBits >> ShiftAmount); 2491 2492 // BFI encompasses sufficiently many nodes that it's worth inserting an extra 2493 // LSL/LSR if the mask in NonZeroBits doesn't quite match up with the ISD::SHL 2494 // amount. BiggerPattern is true when this pattern is being matched for BFI, 2495 // BiggerPattern is false when this pattern is being matched for UBFIZ, in 2496 // which case it is not profitable to insert an extra shift. 2497 if (ShlImm - ShiftAmount != 0 && !BiggerPattern) 2498 return false; 2499 Src = getLeftShift(CurDAG, Op, ShlImm - ShiftAmount); 2500 2501 return true; 2502 } 2503 2504 static bool isShiftedMask(uint64_t Mask, EVT VT) { 2505 assert(VT == MVT::i32 || VT == MVT::i64); 2506 if (VT == MVT::i32) 2507 return isShiftedMask_32(Mask); 2508 return isShiftedMask_64(Mask); 2509 } 2510 2511 // Generate a BFI/BFXIL from 'or (and X, MaskImm), OrImm' iff the value being 2512 // inserted only sets known zero bits. 2513 static bool tryBitfieldInsertOpFromOrAndImm(SDNode *N, SelectionDAG *CurDAG) { 2514 assert(N->getOpcode() == ISD::OR && "Expect a OR operation"); 2515 2516 EVT VT = N->getValueType(0); 2517 if (VT != MVT::i32 && VT != MVT::i64) 2518 return false; 2519 2520 unsigned BitWidth = VT.getSizeInBits(); 2521 2522 uint64_t OrImm; 2523 if (!isOpcWithIntImmediate(N, ISD::OR, OrImm)) 2524 return false; 2525 2526 // Skip this transformation if the ORR immediate can be encoded in the ORR. 2527 // Otherwise, we'll trade an AND+ORR for ORR+BFI/BFXIL, which is most likely 2528 // performance neutral. 2529 if (AArch64_AM::isLogicalImmediate(OrImm, BitWidth)) 2530 return false; 2531 2532 uint64_t MaskImm; 2533 SDValue And = N->getOperand(0); 2534 // Must be a single use AND with an immediate operand. 2535 if (!And.hasOneUse() || 2536 !isOpcWithIntImmediate(And.getNode(), ISD::AND, MaskImm)) 2537 return false; 2538 2539 // Compute the Known Zero for the AND as this allows us to catch more general 2540 // cases than just looking for AND with imm. 2541 KnownBits Known = CurDAG->computeKnownBits(And); 2542 2543 // Non-zero in the sense that they're not provably zero, which is the key 2544 // point if we want to use this value. 2545 uint64_t NotKnownZero = (~Known.Zero).getZExtValue(); 2546 2547 // The KnownZero mask must be a shifted mask (e.g., 1110..011, 11100..00). 2548 if (!isShiftedMask(Known.Zero.getZExtValue(), VT)) 2549 return false; 2550 2551 // The bits being inserted must only set those bits that are known to be zero. 2552 if ((OrImm & NotKnownZero) != 0) { 2553 // FIXME: It's okay if the OrImm sets NotKnownZero bits to 1, but we don't 2554 // currently handle this case. 2555 return false; 2556 } 2557 2558 // BFI/BFXIL dst, src, #lsb, #width. 2559 int LSB = countTrailingOnes(NotKnownZero); 2560 int Width = BitWidth - APInt(BitWidth, NotKnownZero).countPopulation(); 2561 2562 // BFI/BFXIL is an alias of BFM, so translate to BFM operands. 2563 unsigned ImmR = (BitWidth - LSB) % BitWidth; 2564 unsigned ImmS = Width - 1; 2565 2566 // If we're creating a BFI instruction avoid cases where we need more 2567 // instructions to materialize the BFI constant as compared to the original 2568 // ORR. A BFXIL will use the same constant as the original ORR, so the code 2569 // should be no worse in this case. 2570 bool IsBFI = LSB != 0; 2571 uint64_t BFIImm = OrImm >> LSB; 2572 if (IsBFI && !AArch64_AM::isLogicalImmediate(BFIImm, BitWidth)) { 2573 // We have a BFI instruction and we know the constant can't be materialized 2574 // with a ORR-immediate with the zero register. 2575 unsigned OrChunks = 0, BFIChunks = 0; 2576 for (unsigned Shift = 0; Shift < BitWidth; Shift += 16) { 2577 if (((OrImm >> Shift) & 0xFFFF) != 0) 2578 ++OrChunks; 2579 if (((BFIImm >> Shift) & 0xFFFF) != 0) 2580 ++BFIChunks; 2581 } 2582 if (BFIChunks > OrChunks) 2583 return false; 2584 } 2585 2586 // Materialize the constant to be inserted. 2587 SDLoc DL(N); 2588 unsigned MOVIOpc = VT == MVT::i32 ? AArch64::MOVi32imm : AArch64::MOVi64imm; 2589 SDNode *MOVI = CurDAG->getMachineNode( 2590 MOVIOpc, DL, VT, CurDAG->getTargetConstant(BFIImm, DL, VT)); 2591 2592 // Create the BFI/BFXIL instruction. 2593 SDValue Ops[] = {And.getOperand(0), SDValue(MOVI, 0), 2594 CurDAG->getTargetConstant(ImmR, DL, VT), 2595 CurDAG->getTargetConstant(ImmS, DL, VT)}; 2596 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri; 2597 CurDAG->SelectNodeTo(N, Opc, VT, Ops); 2598 return true; 2599 } 2600 2601 static bool tryBitfieldInsertOpFromOr(SDNode *N, const APInt &UsefulBits, 2602 SelectionDAG *CurDAG) { 2603 assert(N->getOpcode() == ISD::OR && "Expect a OR operation"); 2604 2605 EVT VT = N->getValueType(0); 2606 if (VT != MVT::i32 && VT != MVT::i64) 2607 return false; 2608 2609 unsigned BitWidth = VT.getSizeInBits(); 2610 2611 // Because of simplify-demanded-bits in DAGCombine, involved masks may not 2612 // have the expected shape. Try to undo that. 2613 2614 unsigned NumberOfIgnoredLowBits = UsefulBits.countTrailingZeros(); 2615 unsigned NumberOfIgnoredHighBits = UsefulBits.countLeadingZeros(); 2616 2617 // Given a OR operation, check if we have the following pattern 2618 // ubfm c, b, imm, imm2 (or something that does the same jobs, see 2619 // isBitfieldExtractOp) 2620 // d = e & mask2 ; where mask is a binary sequence of 1..10..0 and 2621 // countTrailingZeros(mask2) == imm2 - imm + 1 2622 // f = d | c 2623 // if yes, replace the OR instruction with: 2624 // f = BFM Opd0, Opd1, LSB, MSB ; where LSB = imm, and MSB = imm2 2625 2626 // OR is commutative, check all combinations of operand order and values of 2627 // BiggerPattern, i.e. 2628 // Opd0, Opd1, BiggerPattern=false 2629 // Opd1, Opd0, BiggerPattern=false 2630 // Opd0, Opd1, BiggerPattern=true 2631 // Opd1, Opd0, BiggerPattern=true 2632 // Several of these combinations may match, so check with BiggerPattern=false 2633 // first since that will produce better results by matching more instructions 2634 // and/or inserting fewer extra instructions. 2635 for (int I = 0; I < 4; ++I) { 2636 2637 SDValue Dst, Src; 2638 unsigned ImmR, ImmS; 2639 bool BiggerPattern = I / 2; 2640 SDValue OrOpd0Val = N->getOperand(I % 2); 2641 SDNode *OrOpd0 = OrOpd0Val.getNode(); 2642 SDValue OrOpd1Val = N->getOperand((I + 1) % 2); 2643 SDNode *OrOpd1 = OrOpd1Val.getNode(); 2644 2645 unsigned BFXOpc; 2646 int DstLSB, Width; 2647 if (isBitfieldExtractOp(CurDAG, OrOpd0, BFXOpc, Src, ImmR, ImmS, 2648 NumberOfIgnoredLowBits, BiggerPattern)) { 2649 // Check that the returned opcode is compatible with the pattern, 2650 // i.e., same type and zero extended (U and not S) 2651 if ((BFXOpc != AArch64::UBFMXri && VT == MVT::i64) || 2652 (BFXOpc != AArch64::UBFMWri && VT == MVT::i32)) 2653 continue; 2654 2655 // Compute the width of the bitfield insertion 2656 DstLSB = 0; 2657 Width = ImmS - ImmR + 1; 2658 // FIXME: This constraint is to catch bitfield insertion we may 2659 // want to widen the pattern if we want to grab general bitfied 2660 // move case 2661 if (Width <= 0) 2662 continue; 2663 2664 // If the mask on the insertee is correct, we have a BFXIL operation. We 2665 // can share the ImmR and ImmS values from the already-computed UBFM. 2666 } else if (isBitfieldPositioningOp(CurDAG, OrOpd0Val, 2667 BiggerPattern, 2668 Src, DstLSB, Width)) { 2669 ImmR = (BitWidth - DstLSB) % BitWidth; 2670 ImmS = Width - 1; 2671 } else 2672 continue; 2673 2674 // Check the second part of the pattern 2675 EVT VT = OrOpd1Val.getValueType(); 2676 assert((VT == MVT::i32 || VT == MVT::i64) && "unexpected OR operand"); 2677 2678 // Compute the Known Zero for the candidate of the first operand. 2679 // This allows to catch more general case than just looking for 2680 // AND with imm. Indeed, simplify-demanded-bits may have removed 2681 // the AND instruction because it proves it was useless. 2682 KnownBits Known = CurDAG->computeKnownBits(OrOpd1Val); 2683 2684 // Check if there is enough room for the second operand to appear 2685 // in the first one 2686 APInt BitsToBeInserted = 2687 APInt::getBitsSet(Known.getBitWidth(), DstLSB, DstLSB + Width); 2688 2689 if ((BitsToBeInserted & ~Known.Zero) != 0) 2690 continue; 2691 2692 // Set the first operand 2693 uint64_t Imm; 2694 if (isOpcWithIntImmediate(OrOpd1, ISD::AND, Imm) && 2695 isBitfieldDstMask(Imm, BitsToBeInserted, NumberOfIgnoredHighBits, VT)) 2696 // In that case, we can eliminate the AND 2697 Dst = OrOpd1->getOperand(0); 2698 else 2699 // Maybe the AND has been removed by simplify-demanded-bits 2700 // or is useful because it discards more bits 2701 Dst = OrOpd1Val; 2702 2703 // both parts match 2704 SDLoc DL(N); 2705 SDValue Ops[] = {Dst, Src, CurDAG->getTargetConstant(ImmR, DL, VT), 2706 CurDAG->getTargetConstant(ImmS, DL, VT)}; 2707 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri; 2708 CurDAG->SelectNodeTo(N, Opc, VT, Ops); 2709 return true; 2710 } 2711 2712 // Generate a BFXIL from 'or (and X, Mask0Imm), (and Y, Mask1Imm)' iff 2713 // Mask0Imm and ~Mask1Imm are equivalent and one of the MaskImms is a shifted 2714 // mask (e.g., 0x000ffff0). 2715 uint64_t Mask0Imm, Mask1Imm; 2716 SDValue And0 = N->getOperand(0); 2717 SDValue And1 = N->getOperand(1); 2718 if (And0.hasOneUse() && And1.hasOneUse() && 2719 isOpcWithIntImmediate(And0.getNode(), ISD::AND, Mask0Imm) && 2720 isOpcWithIntImmediate(And1.getNode(), ISD::AND, Mask1Imm) && 2721 APInt(BitWidth, Mask0Imm) == ~APInt(BitWidth, Mask1Imm) && 2722 (isShiftedMask(Mask0Imm, VT) || isShiftedMask(Mask1Imm, VT))) { 2723 2724 // ORR is commutative, so canonicalize to the form 'or (and X, Mask0Imm), 2725 // (and Y, Mask1Imm)' where Mask1Imm is the shifted mask masking off the 2726 // bits to be inserted. 2727 if (isShiftedMask(Mask0Imm, VT)) { 2728 std::swap(And0, And1); 2729 std::swap(Mask0Imm, Mask1Imm); 2730 } 2731 2732 SDValue Src = And1->getOperand(0); 2733 SDValue Dst = And0->getOperand(0); 2734 unsigned LSB = countTrailingZeros(Mask1Imm); 2735 int Width = BitWidth - APInt(BitWidth, Mask0Imm).countPopulation(); 2736 2737 // The BFXIL inserts the low-order bits from a source register, so right 2738 // shift the needed bits into place. 2739 SDLoc DL(N); 2740 unsigned ShiftOpc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri; 2741 uint64_t LsrImm = LSB; 2742 if (Src->hasOneUse() && 2743 isOpcWithIntImmediate(Src.getNode(), ISD::SRL, LsrImm) && 2744 (LsrImm + LSB) < BitWidth) { 2745 Src = Src->getOperand(0); 2746 LsrImm += LSB; 2747 } 2748 2749 SDNode *LSR = CurDAG->getMachineNode( 2750 ShiftOpc, DL, VT, Src, CurDAG->getTargetConstant(LsrImm, DL, VT), 2751 CurDAG->getTargetConstant(BitWidth - 1, DL, VT)); 2752 2753 // BFXIL is an alias of BFM, so translate to BFM operands. 2754 unsigned ImmR = (BitWidth - LSB) % BitWidth; 2755 unsigned ImmS = Width - 1; 2756 2757 // Create the BFXIL instruction. 2758 SDValue Ops[] = {Dst, SDValue(LSR, 0), 2759 CurDAG->getTargetConstant(ImmR, DL, VT), 2760 CurDAG->getTargetConstant(ImmS, DL, VT)}; 2761 unsigned Opc = (VT == MVT::i32) ? AArch64::BFMWri : AArch64::BFMXri; 2762 CurDAG->SelectNodeTo(N, Opc, VT, Ops); 2763 return true; 2764 } 2765 2766 return false; 2767 } 2768 2769 bool AArch64DAGToDAGISel::tryBitfieldInsertOp(SDNode *N) { 2770 if (N->getOpcode() != ISD::OR) 2771 return false; 2772 2773 APInt NUsefulBits; 2774 getUsefulBits(SDValue(N, 0), NUsefulBits); 2775 2776 // If all bits are not useful, just return UNDEF. 2777 if (!NUsefulBits) { 2778 CurDAG->SelectNodeTo(N, TargetOpcode::IMPLICIT_DEF, N->getValueType(0)); 2779 return true; 2780 } 2781 2782 if (tryBitfieldInsertOpFromOr(N, NUsefulBits, CurDAG)) 2783 return true; 2784 2785 return tryBitfieldInsertOpFromOrAndImm(N, CurDAG); 2786 } 2787 2788 /// SelectBitfieldInsertInZeroOp - Match a UBFIZ instruction that is the 2789 /// equivalent of a left shift by a constant amount followed by an and masking 2790 /// out a contiguous set of bits. 2791 bool AArch64DAGToDAGISel::tryBitfieldInsertInZeroOp(SDNode *N) { 2792 if (N->getOpcode() != ISD::AND) 2793 return false; 2794 2795 EVT VT = N->getValueType(0); 2796 if (VT != MVT::i32 && VT != MVT::i64) 2797 return false; 2798 2799 SDValue Op0; 2800 int DstLSB, Width; 2801 if (!isBitfieldPositioningOp(CurDAG, SDValue(N, 0), /*BiggerPattern=*/false, 2802 Op0, DstLSB, Width)) 2803 return false; 2804 2805 // ImmR is the rotate right amount. 2806 unsigned ImmR = (VT.getSizeInBits() - DstLSB) % VT.getSizeInBits(); 2807 // ImmS is the most significant bit of the source to be moved. 2808 unsigned ImmS = Width - 1; 2809 2810 SDLoc DL(N); 2811 SDValue Ops[] = {Op0, CurDAG->getTargetConstant(ImmR, DL, VT), 2812 CurDAG->getTargetConstant(ImmS, DL, VT)}; 2813 unsigned Opc = (VT == MVT::i32) ? AArch64::UBFMWri : AArch64::UBFMXri; 2814 CurDAG->SelectNodeTo(N, Opc, VT, Ops); 2815 return true; 2816 } 2817 2818 /// tryShiftAmountMod - Take advantage of built-in mod of shift amount in 2819 /// variable shift/rotate instructions. 2820 bool AArch64DAGToDAGISel::tryShiftAmountMod(SDNode *N) { 2821 EVT VT = N->getValueType(0); 2822 2823 unsigned Opc; 2824 switch (N->getOpcode()) { 2825 case ISD::ROTR: 2826 Opc = (VT == MVT::i32) ? AArch64::RORVWr : AArch64::RORVXr; 2827 break; 2828 case ISD::SHL: 2829 Opc = (VT == MVT::i32) ? AArch64::LSLVWr : AArch64::LSLVXr; 2830 break; 2831 case ISD::SRL: 2832 Opc = (VT == MVT::i32) ? AArch64::LSRVWr : AArch64::LSRVXr; 2833 break; 2834 case ISD::SRA: 2835 Opc = (VT == MVT::i32) ? AArch64::ASRVWr : AArch64::ASRVXr; 2836 break; 2837 default: 2838 return false; 2839 } 2840 2841 uint64_t Size; 2842 uint64_t Bits; 2843 if (VT == MVT::i32) { 2844 Bits = 5; 2845 Size = 32; 2846 } else if (VT == MVT::i64) { 2847 Bits = 6; 2848 Size = 64; 2849 } else 2850 return false; 2851 2852 SDValue ShiftAmt = N->getOperand(1); 2853 SDLoc DL(N); 2854 SDValue NewShiftAmt; 2855 2856 // Skip over an extend of the shift amount. 2857 if (ShiftAmt->getOpcode() == ISD::ZERO_EXTEND || 2858 ShiftAmt->getOpcode() == ISD::ANY_EXTEND) 2859 ShiftAmt = ShiftAmt->getOperand(0); 2860 2861 if (ShiftAmt->getOpcode() == ISD::ADD || ShiftAmt->getOpcode() == ISD::SUB) { 2862 SDValue Add0 = ShiftAmt->getOperand(0); 2863 SDValue Add1 = ShiftAmt->getOperand(1); 2864 uint64_t Add0Imm; 2865 uint64_t Add1Imm; 2866 if (isIntImmediate(Add1, Add1Imm) && (Add1Imm % Size == 0)) { 2867 // If we are shifting by X+/-N where N == 0 mod Size, then just shift by X 2868 // to avoid the ADD/SUB. 2869 NewShiftAmt = Add0; 2870 } else if (ShiftAmt->getOpcode() == ISD::SUB && 2871 isIntImmediate(Add0, Add0Imm) && Add0Imm != 0 && 2872 (Add0Imm % Size == 0)) { 2873 // If we are shifting by N-X where N == 0 mod Size, then just shift by -X 2874 // to generate a NEG instead of a SUB from a constant. 2875 unsigned NegOpc; 2876 unsigned ZeroReg; 2877 EVT SubVT = ShiftAmt->getValueType(0); 2878 if (SubVT == MVT::i32) { 2879 NegOpc = AArch64::SUBWrr; 2880 ZeroReg = AArch64::WZR; 2881 } else { 2882 assert(SubVT == MVT::i64); 2883 NegOpc = AArch64::SUBXrr; 2884 ZeroReg = AArch64::XZR; 2885 } 2886 SDValue Zero = 2887 CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, ZeroReg, SubVT); 2888 MachineSDNode *Neg = 2889 CurDAG->getMachineNode(NegOpc, DL, SubVT, Zero, Add1); 2890 NewShiftAmt = SDValue(Neg, 0); 2891 } else if (ShiftAmt->getOpcode() == ISD::SUB && 2892 isIntImmediate(Add0, Add0Imm) && (Add0Imm % Size == Size - 1)) { 2893 // If we are shifting by N-X where N == -1 mod Size, then just shift by ~X 2894 // to generate a NOT instead of a SUB from a constant. 2895 unsigned NotOpc; 2896 unsigned ZeroReg; 2897 EVT SubVT = ShiftAmt->getValueType(0); 2898 if (SubVT == MVT::i32) { 2899 NotOpc = AArch64::ORNWrr; 2900 ZeroReg = AArch64::WZR; 2901 } else { 2902 assert(SubVT == MVT::i64); 2903 NotOpc = AArch64::ORNXrr; 2904 ZeroReg = AArch64::XZR; 2905 } 2906 SDValue Zero = 2907 CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, ZeroReg, SubVT); 2908 MachineSDNode *Not = 2909 CurDAG->getMachineNode(NotOpc, DL, SubVT, Zero, Add1); 2910 NewShiftAmt = SDValue(Not, 0); 2911 } else 2912 return false; 2913 } else { 2914 // If the shift amount is masked with an AND, check that the mask covers the 2915 // bits that are implicitly ANDed off by the above opcodes and if so, skip 2916 // the AND. 2917 uint64_t MaskImm; 2918 if (!isOpcWithIntImmediate(ShiftAmt.getNode(), ISD::AND, MaskImm) && 2919 !isOpcWithIntImmediate(ShiftAmt.getNode(), AArch64ISD::ANDS, MaskImm)) 2920 return false; 2921 2922 if (countTrailingOnes(MaskImm) < Bits) 2923 return false; 2924 2925 NewShiftAmt = ShiftAmt->getOperand(0); 2926 } 2927 2928 // Narrow/widen the shift amount to match the size of the shift operation. 2929 if (VT == MVT::i32) 2930 NewShiftAmt = narrowIfNeeded(CurDAG, NewShiftAmt); 2931 else if (VT == MVT::i64 && NewShiftAmt->getValueType(0) == MVT::i32) { 2932 SDValue SubReg = CurDAG->getTargetConstant(AArch64::sub_32, DL, MVT::i32); 2933 MachineSDNode *Ext = CurDAG->getMachineNode( 2934 AArch64::SUBREG_TO_REG, DL, VT, 2935 CurDAG->getTargetConstant(0, DL, MVT::i64), NewShiftAmt, SubReg); 2936 NewShiftAmt = SDValue(Ext, 0); 2937 } 2938 2939 SDValue Ops[] = {N->getOperand(0), NewShiftAmt}; 2940 CurDAG->SelectNodeTo(N, Opc, VT, Ops); 2941 return true; 2942 } 2943 2944 bool 2945 AArch64DAGToDAGISel::SelectCVTFixedPosOperand(SDValue N, SDValue &FixedPos, 2946 unsigned RegWidth) { 2947 APFloat FVal(0.0); 2948 if (ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N)) 2949 FVal = CN->getValueAPF(); 2950 else if (LoadSDNode *LN = dyn_cast<LoadSDNode>(N)) { 2951 // Some otherwise illegal constants are allowed in this case. 2952 if (LN->getOperand(1).getOpcode() != AArch64ISD::ADDlow || 2953 !isa<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1))) 2954 return false; 2955 2956 ConstantPoolSDNode *CN = 2957 dyn_cast<ConstantPoolSDNode>(LN->getOperand(1)->getOperand(1)); 2958 FVal = cast<ConstantFP>(CN->getConstVal())->getValueAPF(); 2959 } else 2960 return false; 2961 2962 // An FCVT[SU] instruction performs: convertToInt(Val * 2^fbits) where fbits 2963 // is between 1 and 32 for a destination w-register, or 1 and 64 for an 2964 // x-register. 2965 // 2966 // By this stage, we've detected (fp_to_[su]int (fmul Val, THIS_NODE)) so we 2967 // want THIS_NODE to be 2^fbits. This is much easier to deal with using 2968 // integers. 2969 bool IsExact; 2970 2971 // fbits is between 1 and 64 in the worst-case, which means the fmul 2972 // could have 2^64 as an actual operand. Need 65 bits of precision. 2973 APSInt IntVal(65, true); 2974 FVal.convertToInteger(IntVal, APFloat::rmTowardZero, &IsExact); 2975 2976 // N.b. isPowerOf2 also checks for > 0. 2977 if (!IsExact || !IntVal.isPowerOf2()) return false; 2978 unsigned FBits = IntVal.logBase2(); 2979 2980 // Checks above should have guaranteed that we haven't lost information in 2981 // finding FBits, but it must still be in range. 2982 if (FBits == 0 || FBits > RegWidth) return false; 2983 2984 FixedPos = CurDAG->getTargetConstant(FBits, SDLoc(N), MVT::i32); 2985 return true; 2986 } 2987 2988 // Inspects a register string of the form o0:op1:CRn:CRm:op2 gets the fields 2989 // of the string and obtains the integer values from them and combines these 2990 // into a single value to be used in the MRS/MSR instruction. 2991 static int getIntOperandFromRegisterString(StringRef RegString) { 2992 SmallVector<StringRef, 5> Fields; 2993 RegString.split(Fields, ':'); 2994 2995 if (Fields.size() == 1) 2996 return -1; 2997 2998 assert(Fields.size() == 5 2999 && "Invalid number of fields in read register string"); 3000 3001 SmallVector<int, 5> Ops; 3002 bool AllIntFields = true; 3003 3004 for (StringRef Field : Fields) { 3005 unsigned IntField; 3006 AllIntFields &= !Field.getAsInteger(10, IntField); 3007 Ops.push_back(IntField); 3008 } 3009 3010 assert(AllIntFields && 3011 "Unexpected non-integer value in special register string."); 3012 (void)AllIntFields; 3013 3014 // Need to combine the integer fields of the string into a single value 3015 // based on the bit encoding of MRS/MSR instruction. 3016 return (Ops[0] << 14) | (Ops[1] << 11) | (Ops[2] << 7) | 3017 (Ops[3] << 3) | (Ops[4]); 3018 } 3019 3020 // Lower the read_register intrinsic to an MRS instruction node if the special 3021 // register string argument is either of the form detailed in the ALCE (the 3022 // form described in getIntOperandsFromRegsterString) or is a named register 3023 // known by the MRS SysReg mapper. 3024 bool AArch64DAGToDAGISel::tryReadRegister(SDNode *N) { 3025 const auto *MD = cast<MDNodeSDNode>(N->getOperand(1)); 3026 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0)); 3027 SDLoc DL(N); 3028 3029 int Reg = getIntOperandFromRegisterString(RegString->getString()); 3030 if (Reg != -1) { 3031 ReplaceNode(N, CurDAG->getMachineNode( 3032 AArch64::MRS, DL, N->getSimpleValueType(0), MVT::Other, 3033 CurDAG->getTargetConstant(Reg, DL, MVT::i32), 3034 N->getOperand(0))); 3035 return true; 3036 } 3037 3038 // Use the sysreg mapper to map the remaining possible strings to the 3039 // value for the register to be used for the instruction operand. 3040 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString()); 3041 if (TheReg && TheReg->Readable && 3042 TheReg->haveFeatures(Subtarget->getFeatureBits())) 3043 Reg = TheReg->Encoding; 3044 else 3045 Reg = AArch64SysReg::parseGenericRegister(RegString->getString()); 3046 3047 if (Reg != -1) { 3048 ReplaceNode(N, CurDAG->getMachineNode( 3049 AArch64::MRS, DL, N->getSimpleValueType(0), MVT::Other, 3050 CurDAG->getTargetConstant(Reg, DL, MVT::i32), 3051 N->getOperand(0))); 3052 return true; 3053 } 3054 3055 if (RegString->getString() == "pc") { 3056 ReplaceNode(N, CurDAG->getMachineNode( 3057 AArch64::ADR, DL, N->getSimpleValueType(0), MVT::Other, 3058 CurDAG->getTargetConstant(0, DL, MVT::i32), 3059 N->getOperand(0))); 3060 return true; 3061 } 3062 3063 return false; 3064 } 3065 3066 // Lower the write_register intrinsic to an MSR instruction node if the special 3067 // register string argument is either of the form detailed in the ALCE (the 3068 // form described in getIntOperandsFromRegsterString) or is a named register 3069 // known by the MSR SysReg mapper. 3070 bool AArch64DAGToDAGISel::tryWriteRegister(SDNode *N) { 3071 const auto *MD = cast<MDNodeSDNode>(N->getOperand(1)); 3072 const auto *RegString = cast<MDString>(MD->getMD()->getOperand(0)); 3073 SDLoc DL(N); 3074 3075 int Reg = getIntOperandFromRegisterString(RegString->getString()); 3076 if (Reg != -1) { 3077 ReplaceNode( 3078 N, CurDAG->getMachineNode(AArch64::MSR, DL, MVT::Other, 3079 CurDAG->getTargetConstant(Reg, DL, MVT::i32), 3080 N->getOperand(2), N->getOperand(0))); 3081 return true; 3082 } 3083 3084 // Check if the register was one of those allowed as the pstatefield value in 3085 // the MSR (immediate) instruction. To accept the values allowed in the 3086 // pstatefield for the MSR (immediate) instruction, we also require that an 3087 // immediate value has been provided as an argument, we know that this is 3088 // the case as it has been ensured by semantic checking. 3089 auto PMapper = AArch64PState::lookupPStateByName(RegString->getString()); 3090 if (PMapper) { 3091 assert (isa<ConstantSDNode>(N->getOperand(2)) 3092 && "Expected a constant integer expression."); 3093 unsigned Reg = PMapper->Encoding; 3094 uint64_t Immed = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue(); 3095 unsigned State; 3096 if (Reg == AArch64PState::PAN || Reg == AArch64PState::UAO || Reg == AArch64PState::SSBS) { 3097 assert(Immed < 2 && "Bad imm"); 3098 State = AArch64::MSRpstateImm1; 3099 } else { 3100 assert(Immed < 16 && "Bad imm"); 3101 State = AArch64::MSRpstateImm4; 3102 } 3103 ReplaceNode(N, CurDAG->getMachineNode( 3104 State, DL, MVT::Other, 3105 CurDAG->getTargetConstant(Reg, DL, MVT::i32), 3106 CurDAG->getTargetConstant(Immed, DL, MVT::i16), 3107 N->getOperand(0))); 3108 return true; 3109 } 3110 3111 // Use the sysreg mapper to attempt to map the remaining possible strings 3112 // to the value for the register to be used for the MSR (register) 3113 // instruction operand. 3114 auto TheReg = AArch64SysReg::lookupSysRegByName(RegString->getString()); 3115 if (TheReg && TheReg->Writeable && 3116 TheReg->haveFeatures(Subtarget->getFeatureBits())) 3117 Reg = TheReg->Encoding; 3118 else 3119 Reg = AArch64SysReg::parseGenericRegister(RegString->getString()); 3120 if (Reg != -1) { 3121 ReplaceNode(N, CurDAG->getMachineNode( 3122 AArch64::MSR, DL, MVT::Other, 3123 CurDAG->getTargetConstant(Reg, DL, MVT::i32), 3124 N->getOperand(2), N->getOperand(0))); 3125 return true; 3126 } 3127 3128 return false; 3129 } 3130 3131 /// We've got special pseudo-instructions for these 3132 bool AArch64DAGToDAGISel::SelectCMP_SWAP(SDNode *N) { 3133 unsigned Opcode; 3134 EVT MemTy = cast<MemSDNode>(N)->getMemoryVT(); 3135 3136 // Leave IR for LSE if subtarget supports it. 3137 if (Subtarget->hasLSE()) return false; 3138 3139 if (MemTy == MVT::i8) 3140 Opcode = AArch64::CMP_SWAP_8; 3141 else if (MemTy == MVT::i16) 3142 Opcode = AArch64::CMP_SWAP_16; 3143 else if (MemTy == MVT::i32) 3144 Opcode = AArch64::CMP_SWAP_32; 3145 else if (MemTy == MVT::i64) 3146 Opcode = AArch64::CMP_SWAP_64; 3147 else 3148 llvm_unreachable("Unknown AtomicCmpSwap type"); 3149 3150 MVT RegTy = MemTy == MVT::i64 ? MVT::i64 : MVT::i32; 3151 SDValue Ops[] = {N->getOperand(1), N->getOperand(2), N->getOperand(3), 3152 N->getOperand(0)}; 3153 SDNode *CmpSwap = CurDAG->getMachineNode( 3154 Opcode, SDLoc(N), 3155 CurDAG->getVTList(RegTy, MVT::i32, MVT::Other), Ops); 3156 3157 MachineMemOperand *MemOp = cast<MemSDNode>(N)->getMemOperand(); 3158 CurDAG->setNodeMemRefs(cast<MachineSDNode>(CmpSwap), {MemOp}); 3159 3160 ReplaceUses(SDValue(N, 0), SDValue(CmpSwap, 0)); 3161 ReplaceUses(SDValue(N, 1), SDValue(CmpSwap, 2)); 3162 CurDAG->RemoveDeadNode(N); 3163 3164 return true; 3165 } 3166 3167 bool AArch64DAGToDAGISel::SelectSVEAddSubImm(SDValue N, MVT VT, SDValue &Imm, 3168 SDValue &Shift) { 3169 if (!isa<ConstantSDNode>(N)) 3170 return false; 3171 3172 SDLoc DL(N); 3173 uint64_t Val = cast<ConstantSDNode>(N) 3174 ->getAPIntValue() 3175 .trunc(VT.getFixedSizeInBits()) 3176 .getZExtValue(); 3177 3178 switch (VT.SimpleTy) { 3179 case MVT::i8: 3180 // All immediates are supported. 3181 Shift = CurDAG->getTargetConstant(0, DL, MVT::i32); 3182 Imm = CurDAG->getTargetConstant(Val, DL, MVT::i32); 3183 return true; 3184 case MVT::i16: 3185 case MVT::i32: 3186 case MVT::i64: 3187 // Support 8bit unsigned immediates. 3188 if (Val <= 255) { 3189 Shift = CurDAG->getTargetConstant(0, DL, MVT::i32); 3190 Imm = CurDAG->getTargetConstant(Val, DL, MVT::i32); 3191 return true; 3192 } 3193 // Support 16bit unsigned immediates that are a multiple of 256. 3194 if (Val <= 65280 && Val % 256 == 0) { 3195 Shift = CurDAG->getTargetConstant(8, DL, MVT::i32); 3196 Imm = CurDAG->getTargetConstant(Val >> 8, DL, MVT::i32); 3197 return true; 3198 } 3199 break; 3200 default: 3201 break; 3202 } 3203 3204 return false; 3205 } 3206 3207 bool AArch64DAGToDAGISel::SelectSVECpyDupImm(SDValue N, MVT VT, SDValue &Imm, 3208 SDValue &Shift) { 3209 if (!isa<ConstantSDNode>(N)) 3210 return false; 3211 3212 SDLoc DL(N); 3213 int64_t Val = cast<ConstantSDNode>(N) 3214 ->getAPIntValue() 3215 .trunc(VT.getFixedSizeInBits()) 3216 .getSExtValue(); 3217 3218 switch (VT.SimpleTy) { 3219 case MVT::i8: 3220 // All immediates are supported. 3221 Shift = CurDAG->getTargetConstant(0, DL, MVT::i32); 3222 Imm = CurDAG->getTargetConstant(Val & 0xFF, DL, MVT::i32); 3223 return true; 3224 case MVT::i16: 3225 case MVT::i32: 3226 case MVT::i64: 3227 // Support 8bit signed immediates. 3228 if (Val >= -128 && Val <= 127) { 3229 Shift = CurDAG->getTargetConstant(0, DL, MVT::i32); 3230 Imm = CurDAG->getTargetConstant(Val & 0xFF, DL, MVT::i32); 3231 return true; 3232 } 3233 // Support 16bit signed immediates that are a multiple of 256. 3234 if (Val >= -32768 && Val <= 32512 && Val % 256 == 0) { 3235 Shift = CurDAG->getTargetConstant(8, DL, MVT::i32); 3236 Imm = CurDAG->getTargetConstant((Val >> 8) & 0xFF, DL, MVT::i32); 3237 return true; 3238 } 3239 break; 3240 default: 3241 break; 3242 } 3243 3244 return false; 3245 } 3246 3247 bool AArch64DAGToDAGISel::SelectSVESignedArithImm(SDValue N, SDValue &Imm) { 3248 if (auto CNode = dyn_cast<ConstantSDNode>(N)) { 3249 int64_t ImmVal = CNode->getSExtValue(); 3250 SDLoc DL(N); 3251 if (ImmVal >= -128 && ImmVal < 128) { 3252 Imm = CurDAG->getTargetConstant(ImmVal, DL, MVT::i32); 3253 return true; 3254 } 3255 } 3256 return false; 3257 } 3258 3259 bool AArch64DAGToDAGISel::SelectSVEArithImm(SDValue N, MVT VT, SDValue &Imm) { 3260 if (auto CNode = dyn_cast<ConstantSDNode>(N)) { 3261 uint64_t ImmVal = CNode->getZExtValue(); 3262 3263 switch (VT.SimpleTy) { 3264 case MVT::i8: 3265 ImmVal &= 0xFF; 3266 break; 3267 case MVT::i16: 3268 ImmVal &= 0xFFFF; 3269 break; 3270 case MVT::i32: 3271 ImmVal &= 0xFFFFFFFF; 3272 break; 3273 case MVT::i64: 3274 break; 3275 default: 3276 llvm_unreachable("Unexpected type"); 3277 } 3278 3279 if (ImmVal < 256) { 3280 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), MVT::i32); 3281 return true; 3282 } 3283 } 3284 return false; 3285 } 3286 3287 bool AArch64DAGToDAGISel::SelectSVELogicalImm(SDValue N, MVT VT, SDValue &Imm, 3288 bool Invert) { 3289 if (auto CNode = dyn_cast<ConstantSDNode>(N)) { 3290 uint64_t ImmVal = CNode->getZExtValue(); 3291 SDLoc DL(N); 3292 3293 if (Invert) 3294 ImmVal = ~ImmVal; 3295 3296 // Shift mask depending on type size. 3297 switch (VT.SimpleTy) { 3298 case MVT::i8: 3299 ImmVal &= 0xFF; 3300 ImmVal |= ImmVal << 8; 3301 ImmVal |= ImmVal << 16; 3302 ImmVal |= ImmVal << 32; 3303 break; 3304 case MVT::i16: 3305 ImmVal &= 0xFFFF; 3306 ImmVal |= ImmVal << 16; 3307 ImmVal |= ImmVal << 32; 3308 break; 3309 case MVT::i32: 3310 ImmVal &= 0xFFFFFFFF; 3311 ImmVal |= ImmVal << 32; 3312 break; 3313 case MVT::i64: 3314 break; 3315 default: 3316 llvm_unreachable("Unexpected type"); 3317 } 3318 3319 uint64_t encoding; 3320 if (AArch64_AM::processLogicalImmediate(ImmVal, 64, encoding)) { 3321 Imm = CurDAG->getTargetConstant(encoding, DL, MVT::i64); 3322 return true; 3323 } 3324 } 3325 return false; 3326 } 3327 3328 // SVE shift intrinsics allow shift amounts larger than the element's bitwidth. 3329 // Rather than attempt to normalise everything we can sometimes saturate the 3330 // shift amount during selection. This function also allows for consistent 3331 // isel patterns by ensuring the resulting "Imm" node is of the i32 type 3332 // required by the instructions. 3333 bool AArch64DAGToDAGISel::SelectSVEShiftImm(SDValue N, uint64_t Low, 3334 uint64_t High, bool AllowSaturation, 3335 SDValue &Imm) { 3336 if (auto *CN = dyn_cast<ConstantSDNode>(N)) { 3337 uint64_t ImmVal = CN->getZExtValue(); 3338 3339 // Reject shift amounts that are too small. 3340 if (ImmVal < Low) 3341 return false; 3342 3343 // Reject or saturate shift amounts that are too big. 3344 if (ImmVal > High) { 3345 if (!AllowSaturation) 3346 return false; 3347 ImmVal = High; 3348 } 3349 3350 Imm = CurDAG->getTargetConstant(ImmVal, SDLoc(N), MVT::i32); 3351 return true; 3352 } 3353 3354 return false; 3355 } 3356 3357 bool AArch64DAGToDAGISel::trySelectStackSlotTagP(SDNode *N) { 3358 // tagp(FrameIndex, IRGstack, tag_offset): 3359 // since the offset between FrameIndex and IRGstack is a compile-time 3360 // constant, this can be lowered to a single ADDG instruction. 3361 if (!(isa<FrameIndexSDNode>(N->getOperand(1)))) { 3362 return false; 3363 } 3364 3365 SDValue IRG_SP = N->getOperand(2); 3366 if (IRG_SP->getOpcode() != ISD::INTRINSIC_W_CHAIN || 3367 cast<ConstantSDNode>(IRG_SP->getOperand(1))->getZExtValue() != 3368 Intrinsic::aarch64_irg_sp) { 3369 return false; 3370 } 3371 3372 const TargetLowering *TLI = getTargetLowering(); 3373 SDLoc DL(N); 3374 int FI = cast<FrameIndexSDNode>(N->getOperand(1))->getIndex(); 3375 SDValue FiOp = CurDAG->getTargetFrameIndex( 3376 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 3377 int TagOffset = cast<ConstantSDNode>(N->getOperand(3))->getZExtValue(); 3378 3379 SDNode *Out = CurDAG->getMachineNode( 3380 AArch64::TAGPstack, DL, MVT::i64, 3381 {FiOp, CurDAG->getTargetConstant(0, DL, MVT::i64), N->getOperand(2), 3382 CurDAG->getTargetConstant(TagOffset, DL, MVT::i64)}); 3383 ReplaceNode(N, Out); 3384 return true; 3385 } 3386 3387 void AArch64DAGToDAGISel::SelectTagP(SDNode *N) { 3388 assert(isa<ConstantSDNode>(N->getOperand(3)) && 3389 "llvm.aarch64.tagp third argument must be an immediate"); 3390 if (trySelectStackSlotTagP(N)) 3391 return; 3392 // FIXME: above applies in any case when offset between Op1 and Op2 is a 3393 // compile-time constant, not just for stack allocations. 3394 3395 // General case for unrelated pointers in Op1 and Op2. 3396 SDLoc DL(N); 3397 int TagOffset = cast<ConstantSDNode>(N->getOperand(3))->getZExtValue(); 3398 SDNode *N1 = CurDAG->getMachineNode(AArch64::SUBP, DL, MVT::i64, 3399 {N->getOperand(1), N->getOperand(2)}); 3400 SDNode *N2 = CurDAG->getMachineNode(AArch64::ADDXrr, DL, MVT::i64, 3401 {SDValue(N1, 0), N->getOperand(2)}); 3402 SDNode *N3 = CurDAG->getMachineNode( 3403 AArch64::ADDG, DL, MVT::i64, 3404 {SDValue(N2, 0), CurDAG->getTargetConstant(0, DL, MVT::i64), 3405 CurDAG->getTargetConstant(TagOffset, DL, MVT::i64)}); 3406 ReplaceNode(N, N3); 3407 } 3408 3409 // NOTE: We cannot use EXTRACT_SUBREG in all cases because the fixed length 3410 // vector types larger than NEON don't have a matching SubRegIndex. 3411 static SDNode *extractSubReg(SelectionDAG *DAG, EVT VT, SDValue V) { 3412 assert(V.getValueType().isScalableVector() && 3413 V.getValueType().getSizeInBits().getKnownMinSize() == 3414 AArch64::SVEBitsPerBlock && 3415 "Expected to extract from a packed scalable vector!"); 3416 assert(VT.isFixedLengthVector() && 3417 "Expected to extract a fixed length vector!"); 3418 3419 SDLoc DL(V); 3420 switch (VT.getSizeInBits()) { 3421 case 64: { 3422 auto SubReg = DAG->getTargetConstant(AArch64::dsub, DL, MVT::i32); 3423 return DAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, VT, V, SubReg); 3424 } 3425 case 128: { 3426 auto SubReg = DAG->getTargetConstant(AArch64::zsub, DL, MVT::i32); 3427 return DAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, DL, VT, V, SubReg); 3428 } 3429 default: { 3430 auto RC = DAG->getTargetConstant(AArch64::ZPRRegClassID, DL, MVT::i64); 3431 return DAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC); 3432 } 3433 } 3434 } 3435 3436 // NOTE: We cannot use INSERT_SUBREG in all cases because the fixed length 3437 // vector types larger than NEON don't have a matching SubRegIndex. 3438 static SDNode *insertSubReg(SelectionDAG *DAG, EVT VT, SDValue V) { 3439 assert(VT.isScalableVector() && 3440 VT.getSizeInBits().getKnownMinSize() == AArch64::SVEBitsPerBlock && 3441 "Expected to insert into a packed scalable vector!"); 3442 assert(V.getValueType().isFixedLengthVector() && 3443 "Expected to insert a fixed length vector!"); 3444 3445 SDLoc DL(V); 3446 switch (V.getValueType().getSizeInBits()) { 3447 case 64: { 3448 auto SubReg = DAG->getTargetConstant(AArch64::dsub, DL, MVT::i32); 3449 auto Container = DAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT); 3450 return DAG->getMachineNode(TargetOpcode::INSERT_SUBREG, DL, VT, 3451 SDValue(Container, 0), V, SubReg); 3452 } 3453 case 128: { 3454 auto SubReg = DAG->getTargetConstant(AArch64::zsub, DL, MVT::i32); 3455 auto Container = DAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, DL, VT); 3456 return DAG->getMachineNode(TargetOpcode::INSERT_SUBREG, DL, VT, 3457 SDValue(Container, 0), V, SubReg); 3458 } 3459 default: { 3460 auto RC = DAG->getTargetConstant(AArch64::ZPRRegClassID, DL, MVT::i64); 3461 return DAG->getMachineNode(TargetOpcode::COPY_TO_REGCLASS, DL, VT, V, RC); 3462 } 3463 } 3464 } 3465 3466 void AArch64DAGToDAGISel::Select(SDNode *Node) { 3467 // If we have a custom node, we already have selected! 3468 if (Node->isMachineOpcode()) { 3469 LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); 3470 Node->setNodeId(-1); 3471 return; 3472 } 3473 3474 // Few custom selection stuff. 3475 EVT VT = Node->getValueType(0); 3476 3477 switch (Node->getOpcode()) { 3478 default: 3479 break; 3480 3481 case ISD::ATOMIC_CMP_SWAP: 3482 if (SelectCMP_SWAP(Node)) 3483 return; 3484 break; 3485 3486 case ISD::READ_REGISTER: 3487 if (tryReadRegister(Node)) 3488 return; 3489 break; 3490 3491 case ISD::WRITE_REGISTER: 3492 if (tryWriteRegister(Node)) 3493 return; 3494 break; 3495 3496 case ISD::ADD: 3497 if (tryMLAV64LaneV128(Node)) 3498 return; 3499 break; 3500 3501 case ISD::LOAD: { 3502 // Try to select as an indexed load. Fall through to normal processing 3503 // if we can't. 3504 if (tryIndexedLoad(Node)) 3505 return; 3506 break; 3507 } 3508 3509 case ISD::SRL: 3510 case ISD::AND: 3511 case ISD::SRA: 3512 case ISD::SIGN_EXTEND_INREG: 3513 if (tryBitfieldExtractOp(Node)) 3514 return; 3515 if (tryBitfieldInsertInZeroOp(Node)) 3516 return; 3517 LLVM_FALLTHROUGH; 3518 case ISD::ROTR: 3519 case ISD::SHL: 3520 if (tryShiftAmountMod(Node)) 3521 return; 3522 break; 3523 3524 case ISD::SIGN_EXTEND: 3525 if (tryBitfieldExtractOpFromSExt(Node)) 3526 return; 3527 break; 3528 3529 case ISD::FP_EXTEND: 3530 if (tryHighFPExt(Node)) 3531 return; 3532 break; 3533 3534 case ISD::OR: 3535 if (tryBitfieldInsertOp(Node)) 3536 return; 3537 break; 3538 3539 case ISD::EXTRACT_SUBVECTOR: { 3540 // Bail when not a "cast" like extract_subvector. 3541 if (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue() != 0) 3542 break; 3543 3544 // Bail when normal isel can do the job. 3545 EVT InVT = Node->getOperand(0).getValueType(); 3546 if (VT.isScalableVector() || InVT.isFixedLengthVector()) 3547 break; 3548 3549 // NOTE: We can only get here when doing fixed length SVE code generation. 3550 // We do manual selection because the types involved are not linked to real 3551 // registers (despite being legal) and must be coerced into SVE registers. 3552 // 3553 // NOTE: If the above changes, be aware that selection will still not work 3554 // because the td definition of extract_vector does not support extracting 3555 // a fixed length vector from a scalable vector. 3556 3557 ReplaceNode(Node, extractSubReg(CurDAG, VT, Node->getOperand(0))); 3558 return; 3559 } 3560 3561 case ISD::INSERT_SUBVECTOR: { 3562 // Bail when not a "cast" like insert_subvector. 3563 if (cast<ConstantSDNode>(Node->getOperand(2))->getZExtValue() != 0) 3564 break; 3565 if (!Node->getOperand(0).isUndef()) 3566 break; 3567 3568 // Bail when normal isel should do the job. 3569 EVT InVT = Node->getOperand(1).getValueType(); 3570 if (VT.isFixedLengthVector() || InVT.isScalableVector()) 3571 break; 3572 3573 // NOTE: We can only get here when doing fixed length SVE code generation. 3574 // We do manual selection because the types involved are not linked to real 3575 // registers (despite being legal) and must be coerced into SVE registers. 3576 // 3577 // NOTE: If the above changes, be aware that selection will still not work 3578 // because the td definition of insert_vector does not support inserting a 3579 // fixed length vector into a scalable vector. 3580 3581 ReplaceNode(Node, insertSubReg(CurDAG, VT, Node->getOperand(1))); 3582 return; 3583 } 3584 3585 case ISD::Constant: { 3586 // Materialize zero constants as copies from WZR/XZR. This allows 3587 // the coalescer to propagate these into other instructions. 3588 ConstantSDNode *ConstNode = cast<ConstantSDNode>(Node); 3589 if (ConstNode->isZero()) { 3590 if (VT == MVT::i32) { 3591 SDValue New = CurDAG->getCopyFromReg( 3592 CurDAG->getEntryNode(), SDLoc(Node), AArch64::WZR, MVT::i32); 3593 ReplaceNode(Node, New.getNode()); 3594 return; 3595 } else if (VT == MVT::i64) { 3596 SDValue New = CurDAG->getCopyFromReg( 3597 CurDAG->getEntryNode(), SDLoc(Node), AArch64::XZR, MVT::i64); 3598 ReplaceNode(Node, New.getNode()); 3599 return; 3600 } 3601 } 3602 break; 3603 } 3604 3605 case ISD::FrameIndex: { 3606 // Selects to ADDXri FI, 0 which in turn will become ADDXri SP, imm. 3607 int FI = cast<FrameIndexSDNode>(Node)->getIndex(); 3608 unsigned Shifter = AArch64_AM::getShifterImm(AArch64_AM::LSL, 0); 3609 const TargetLowering *TLI = getTargetLowering(); 3610 SDValue TFI = CurDAG->getTargetFrameIndex( 3611 FI, TLI->getPointerTy(CurDAG->getDataLayout())); 3612 SDLoc DL(Node); 3613 SDValue Ops[] = { TFI, CurDAG->getTargetConstant(0, DL, MVT::i32), 3614 CurDAG->getTargetConstant(Shifter, DL, MVT::i32) }; 3615 CurDAG->SelectNodeTo(Node, AArch64::ADDXri, MVT::i64, Ops); 3616 return; 3617 } 3618 case ISD::INTRINSIC_W_CHAIN: { 3619 unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue(); 3620 switch (IntNo) { 3621 default: 3622 break; 3623 case Intrinsic::aarch64_ldaxp: 3624 case Intrinsic::aarch64_ldxp: { 3625 unsigned Op = 3626 IntNo == Intrinsic::aarch64_ldaxp ? AArch64::LDAXPX : AArch64::LDXPX; 3627 SDValue MemAddr = Node->getOperand(2); 3628 SDLoc DL(Node); 3629 SDValue Chain = Node->getOperand(0); 3630 3631 SDNode *Ld = CurDAG->getMachineNode(Op, DL, MVT::i64, MVT::i64, 3632 MVT::Other, MemAddr, Chain); 3633 3634 // Transfer memoperands. 3635 MachineMemOperand *MemOp = 3636 cast<MemIntrinsicSDNode>(Node)->getMemOperand(); 3637 CurDAG->setNodeMemRefs(cast<MachineSDNode>(Ld), {MemOp}); 3638 ReplaceNode(Node, Ld); 3639 return; 3640 } 3641 case Intrinsic::aarch64_stlxp: 3642 case Intrinsic::aarch64_stxp: { 3643 unsigned Op = 3644 IntNo == Intrinsic::aarch64_stlxp ? AArch64::STLXPX : AArch64::STXPX; 3645 SDLoc DL(Node); 3646 SDValue Chain = Node->getOperand(0); 3647 SDValue ValLo = Node->getOperand(2); 3648 SDValue ValHi = Node->getOperand(3); 3649 SDValue MemAddr = Node->getOperand(4); 3650 3651 // Place arguments in the right order. 3652 SDValue Ops[] = {ValLo, ValHi, MemAddr, Chain}; 3653 3654 SDNode *St = CurDAG->getMachineNode(Op, DL, MVT::i32, MVT::Other, Ops); 3655 // Transfer memoperands. 3656 MachineMemOperand *MemOp = 3657 cast<MemIntrinsicSDNode>(Node)->getMemOperand(); 3658 CurDAG->setNodeMemRefs(cast<MachineSDNode>(St), {MemOp}); 3659 3660 ReplaceNode(Node, St); 3661 return; 3662 } 3663 case Intrinsic::aarch64_neon_ld1x2: 3664 if (VT == MVT::v8i8) { 3665 SelectLoad(Node, 2, AArch64::LD1Twov8b, AArch64::dsub0); 3666 return; 3667 } else if (VT == MVT::v16i8) { 3668 SelectLoad(Node, 2, AArch64::LD1Twov16b, AArch64::qsub0); 3669 return; 3670 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 3671 SelectLoad(Node, 2, AArch64::LD1Twov4h, AArch64::dsub0); 3672 return; 3673 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 3674 SelectLoad(Node, 2, AArch64::LD1Twov8h, AArch64::qsub0); 3675 return; 3676 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 3677 SelectLoad(Node, 2, AArch64::LD1Twov2s, AArch64::dsub0); 3678 return; 3679 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 3680 SelectLoad(Node, 2, AArch64::LD1Twov4s, AArch64::qsub0); 3681 return; 3682 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 3683 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0); 3684 return; 3685 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 3686 SelectLoad(Node, 2, AArch64::LD1Twov2d, AArch64::qsub0); 3687 return; 3688 } 3689 break; 3690 case Intrinsic::aarch64_neon_ld1x3: 3691 if (VT == MVT::v8i8) { 3692 SelectLoad(Node, 3, AArch64::LD1Threev8b, AArch64::dsub0); 3693 return; 3694 } else if (VT == MVT::v16i8) { 3695 SelectLoad(Node, 3, AArch64::LD1Threev16b, AArch64::qsub0); 3696 return; 3697 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 3698 SelectLoad(Node, 3, AArch64::LD1Threev4h, AArch64::dsub0); 3699 return; 3700 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 3701 SelectLoad(Node, 3, AArch64::LD1Threev8h, AArch64::qsub0); 3702 return; 3703 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 3704 SelectLoad(Node, 3, AArch64::LD1Threev2s, AArch64::dsub0); 3705 return; 3706 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 3707 SelectLoad(Node, 3, AArch64::LD1Threev4s, AArch64::qsub0); 3708 return; 3709 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 3710 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0); 3711 return; 3712 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 3713 SelectLoad(Node, 3, AArch64::LD1Threev2d, AArch64::qsub0); 3714 return; 3715 } 3716 break; 3717 case Intrinsic::aarch64_neon_ld1x4: 3718 if (VT == MVT::v8i8) { 3719 SelectLoad(Node, 4, AArch64::LD1Fourv8b, AArch64::dsub0); 3720 return; 3721 } else if (VT == MVT::v16i8) { 3722 SelectLoad(Node, 4, AArch64::LD1Fourv16b, AArch64::qsub0); 3723 return; 3724 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 3725 SelectLoad(Node, 4, AArch64::LD1Fourv4h, AArch64::dsub0); 3726 return; 3727 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 3728 SelectLoad(Node, 4, AArch64::LD1Fourv8h, AArch64::qsub0); 3729 return; 3730 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 3731 SelectLoad(Node, 4, AArch64::LD1Fourv2s, AArch64::dsub0); 3732 return; 3733 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 3734 SelectLoad(Node, 4, AArch64::LD1Fourv4s, AArch64::qsub0); 3735 return; 3736 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 3737 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0); 3738 return; 3739 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 3740 SelectLoad(Node, 4, AArch64::LD1Fourv2d, AArch64::qsub0); 3741 return; 3742 } 3743 break; 3744 case Intrinsic::aarch64_neon_ld2: 3745 if (VT == MVT::v8i8) { 3746 SelectLoad(Node, 2, AArch64::LD2Twov8b, AArch64::dsub0); 3747 return; 3748 } else if (VT == MVT::v16i8) { 3749 SelectLoad(Node, 2, AArch64::LD2Twov16b, AArch64::qsub0); 3750 return; 3751 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 3752 SelectLoad(Node, 2, AArch64::LD2Twov4h, AArch64::dsub0); 3753 return; 3754 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 3755 SelectLoad(Node, 2, AArch64::LD2Twov8h, AArch64::qsub0); 3756 return; 3757 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 3758 SelectLoad(Node, 2, AArch64::LD2Twov2s, AArch64::dsub0); 3759 return; 3760 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 3761 SelectLoad(Node, 2, AArch64::LD2Twov4s, AArch64::qsub0); 3762 return; 3763 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 3764 SelectLoad(Node, 2, AArch64::LD1Twov1d, AArch64::dsub0); 3765 return; 3766 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 3767 SelectLoad(Node, 2, AArch64::LD2Twov2d, AArch64::qsub0); 3768 return; 3769 } 3770 break; 3771 case Intrinsic::aarch64_neon_ld3: 3772 if (VT == MVT::v8i8) { 3773 SelectLoad(Node, 3, AArch64::LD3Threev8b, AArch64::dsub0); 3774 return; 3775 } else if (VT == MVT::v16i8) { 3776 SelectLoad(Node, 3, AArch64::LD3Threev16b, AArch64::qsub0); 3777 return; 3778 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 3779 SelectLoad(Node, 3, AArch64::LD3Threev4h, AArch64::dsub0); 3780 return; 3781 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 3782 SelectLoad(Node, 3, AArch64::LD3Threev8h, AArch64::qsub0); 3783 return; 3784 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 3785 SelectLoad(Node, 3, AArch64::LD3Threev2s, AArch64::dsub0); 3786 return; 3787 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 3788 SelectLoad(Node, 3, AArch64::LD3Threev4s, AArch64::qsub0); 3789 return; 3790 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 3791 SelectLoad(Node, 3, AArch64::LD1Threev1d, AArch64::dsub0); 3792 return; 3793 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 3794 SelectLoad(Node, 3, AArch64::LD3Threev2d, AArch64::qsub0); 3795 return; 3796 } 3797 break; 3798 case Intrinsic::aarch64_neon_ld4: 3799 if (VT == MVT::v8i8) { 3800 SelectLoad(Node, 4, AArch64::LD4Fourv8b, AArch64::dsub0); 3801 return; 3802 } else if (VT == MVT::v16i8) { 3803 SelectLoad(Node, 4, AArch64::LD4Fourv16b, AArch64::qsub0); 3804 return; 3805 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 3806 SelectLoad(Node, 4, AArch64::LD4Fourv4h, AArch64::dsub0); 3807 return; 3808 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 3809 SelectLoad(Node, 4, AArch64::LD4Fourv8h, AArch64::qsub0); 3810 return; 3811 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 3812 SelectLoad(Node, 4, AArch64::LD4Fourv2s, AArch64::dsub0); 3813 return; 3814 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 3815 SelectLoad(Node, 4, AArch64::LD4Fourv4s, AArch64::qsub0); 3816 return; 3817 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 3818 SelectLoad(Node, 4, AArch64::LD1Fourv1d, AArch64::dsub0); 3819 return; 3820 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 3821 SelectLoad(Node, 4, AArch64::LD4Fourv2d, AArch64::qsub0); 3822 return; 3823 } 3824 break; 3825 case Intrinsic::aarch64_neon_ld2r: 3826 if (VT == MVT::v8i8) { 3827 SelectLoad(Node, 2, AArch64::LD2Rv8b, AArch64::dsub0); 3828 return; 3829 } else if (VT == MVT::v16i8) { 3830 SelectLoad(Node, 2, AArch64::LD2Rv16b, AArch64::qsub0); 3831 return; 3832 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 3833 SelectLoad(Node, 2, AArch64::LD2Rv4h, AArch64::dsub0); 3834 return; 3835 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 3836 SelectLoad(Node, 2, AArch64::LD2Rv8h, AArch64::qsub0); 3837 return; 3838 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 3839 SelectLoad(Node, 2, AArch64::LD2Rv2s, AArch64::dsub0); 3840 return; 3841 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 3842 SelectLoad(Node, 2, AArch64::LD2Rv4s, AArch64::qsub0); 3843 return; 3844 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 3845 SelectLoad(Node, 2, AArch64::LD2Rv1d, AArch64::dsub0); 3846 return; 3847 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 3848 SelectLoad(Node, 2, AArch64::LD2Rv2d, AArch64::qsub0); 3849 return; 3850 } 3851 break; 3852 case Intrinsic::aarch64_neon_ld3r: 3853 if (VT == MVT::v8i8) { 3854 SelectLoad(Node, 3, AArch64::LD3Rv8b, AArch64::dsub0); 3855 return; 3856 } else if (VT == MVT::v16i8) { 3857 SelectLoad(Node, 3, AArch64::LD3Rv16b, AArch64::qsub0); 3858 return; 3859 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 3860 SelectLoad(Node, 3, AArch64::LD3Rv4h, AArch64::dsub0); 3861 return; 3862 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 3863 SelectLoad(Node, 3, AArch64::LD3Rv8h, AArch64::qsub0); 3864 return; 3865 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 3866 SelectLoad(Node, 3, AArch64::LD3Rv2s, AArch64::dsub0); 3867 return; 3868 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 3869 SelectLoad(Node, 3, AArch64::LD3Rv4s, AArch64::qsub0); 3870 return; 3871 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 3872 SelectLoad(Node, 3, AArch64::LD3Rv1d, AArch64::dsub0); 3873 return; 3874 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 3875 SelectLoad(Node, 3, AArch64::LD3Rv2d, AArch64::qsub0); 3876 return; 3877 } 3878 break; 3879 case Intrinsic::aarch64_neon_ld4r: 3880 if (VT == MVT::v8i8) { 3881 SelectLoad(Node, 4, AArch64::LD4Rv8b, AArch64::dsub0); 3882 return; 3883 } else if (VT == MVT::v16i8) { 3884 SelectLoad(Node, 4, AArch64::LD4Rv16b, AArch64::qsub0); 3885 return; 3886 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 3887 SelectLoad(Node, 4, AArch64::LD4Rv4h, AArch64::dsub0); 3888 return; 3889 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 3890 SelectLoad(Node, 4, AArch64::LD4Rv8h, AArch64::qsub0); 3891 return; 3892 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 3893 SelectLoad(Node, 4, AArch64::LD4Rv2s, AArch64::dsub0); 3894 return; 3895 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 3896 SelectLoad(Node, 4, AArch64::LD4Rv4s, AArch64::qsub0); 3897 return; 3898 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 3899 SelectLoad(Node, 4, AArch64::LD4Rv1d, AArch64::dsub0); 3900 return; 3901 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 3902 SelectLoad(Node, 4, AArch64::LD4Rv2d, AArch64::qsub0); 3903 return; 3904 } 3905 break; 3906 case Intrinsic::aarch64_neon_ld2lane: 3907 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 3908 SelectLoadLane(Node, 2, AArch64::LD2i8); 3909 return; 3910 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 3911 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 3912 SelectLoadLane(Node, 2, AArch64::LD2i16); 3913 return; 3914 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 3915 VT == MVT::v2f32) { 3916 SelectLoadLane(Node, 2, AArch64::LD2i32); 3917 return; 3918 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 3919 VT == MVT::v1f64) { 3920 SelectLoadLane(Node, 2, AArch64::LD2i64); 3921 return; 3922 } 3923 break; 3924 case Intrinsic::aarch64_neon_ld3lane: 3925 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 3926 SelectLoadLane(Node, 3, AArch64::LD3i8); 3927 return; 3928 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 3929 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 3930 SelectLoadLane(Node, 3, AArch64::LD3i16); 3931 return; 3932 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 3933 VT == MVT::v2f32) { 3934 SelectLoadLane(Node, 3, AArch64::LD3i32); 3935 return; 3936 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 3937 VT == MVT::v1f64) { 3938 SelectLoadLane(Node, 3, AArch64::LD3i64); 3939 return; 3940 } 3941 break; 3942 case Intrinsic::aarch64_neon_ld4lane: 3943 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 3944 SelectLoadLane(Node, 4, AArch64::LD4i8); 3945 return; 3946 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 3947 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 3948 SelectLoadLane(Node, 4, AArch64::LD4i16); 3949 return; 3950 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 3951 VT == MVT::v2f32) { 3952 SelectLoadLane(Node, 4, AArch64::LD4i32); 3953 return; 3954 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 3955 VT == MVT::v1f64) { 3956 SelectLoadLane(Node, 4, AArch64::LD4i64); 3957 return; 3958 } 3959 break; 3960 case Intrinsic::aarch64_ld64b: 3961 SelectLoad(Node, 8, AArch64::LD64B, AArch64::x8sub_0); 3962 return; 3963 case Intrinsic::aarch64_sve_ld2_sret: { 3964 if (VT == MVT::nxv16i8) { 3965 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B, 3966 true); 3967 return; 3968 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 || 3969 VT == MVT::nxv8bf16) { 3970 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H, 3971 true); 3972 return; 3973 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) { 3974 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W, 3975 true); 3976 return; 3977 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) { 3978 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D, 3979 true); 3980 return; 3981 } 3982 break; 3983 } 3984 case Intrinsic::aarch64_sve_ld3_sret: { 3985 if (VT == MVT::nxv16i8) { 3986 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B, 3987 true); 3988 return; 3989 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 || 3990 VT == MVT::nxv8bf16) { 3991 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H, 3992 true); 3993 return; 3994 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) { 3995 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W, 3996 true); 3997 return; 3998 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) { 3999 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D, 4000 true); 4001 return; 4002 } 4003 break; 4004 } 4005 case Intrinsic::aarch64_sve_ld4_sret: { 4006 if (VT == MVT::nxv16i8) { 4007 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B, 4008 true); 4009 return; 4010 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 || 4011 VT == MVT::nxv8bf16) { 4012 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H, 4013 true); 4014 return; 4015 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) { 4016 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W, 4017 true); 4018 return; 4019 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) { 4020 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D, 4021 true); 4022 return; 4023 } 4024 break; 4025 } 4026 } 4027 } break; 4028 case ISD::INTRINSIC_WO_CHAIN: { 4029 unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue(); 4030 switch (IntNo) { 4031 default: 4032 break; 4033 case Intrinsic::aarch64_tagp: 4034 SelectTagP(Node); 4035 return; 4036 case Intrinsic::aarch64_neon_tbl2: 4037 SelectTable(Node, 2, 4038 VT == MVT::v8i8 ? AArch64::TBLv8i8Two : AArch64::TBLv16i8Two, 4039 false); 4040 return; 4041 case Intrinsic::aarch64_neon_tbl3: 4042 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBLv8i8Three 4043 : AArch64::TBLv16i8Three, 4044 false); 4045 return; 4046 case Intrinsic::aarch64_neon_tbl4: 4047 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBLv8i8Four 4048 : AArch64::TBLv16i8Four, 4049 false); 4050 return; 4051 case Intrinsic::aarch64_neon_tbx2: 4052 SelectTable(Node, 2, 4053 VT == MVT::v8i8 ? AArch64::TBXv8i8Two : AArch64::TBXv16i8Two, 4054 true); 4055 return; 4056 case Intrinsic::aarch64_neon_tbx3: 4057 SelectTable(Node, 3, VT == MVT::v8i8 ? AArch64::TBXv8i8Three 4058 : AArch64::TBXv16i8Three, 4059 true); 4060 return; 4061 case Intrinsic::aarch64_neon_tbx4: 4062 SelectTable(Node, 4, VT == MVT::v8i8 ? AArch64::TBXv8i8Four 4063 : AArch64::TBXv16i8Four, 4064 true); 4065 return; 4066 case Intrinsic::aarch64_neon_smull: 4067 case Intrinsic::aarch64_neon_umull: 4068 if (tryMULLV64LaneV128(IntNo, Node)) 4069 return; 4070 break; 4071 case Intrinsic::swift_async_context_addr: { 4072 SDLoc DL(Node); 4073 CurDAG->SelectNodeTo(Node, AArch64::SUBXri, MVT::i64, 4074 CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, 4075 AArch64::FP, MVT::i64), 4076 CurDAG->getTargetConstant(8, DL, MVT::i32), 4077 CurDAG->getTargetConstant(0, DL, MVT::i32)); 4078 auto &MF = CurDAG->getMachineFunction(); 4079 MF.getFrameInfo().setFrameAddressIsTaken(true); 4080 MF.getInfo<AArch64FunctionInfo>()->setHasSwiftAsyncContext(true); 4081 return; 4082 } 4083 } 4084 break; 4085 } 4086 case ISD::INTRINSIC_VOID: { 4087 unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue(); 4088 if (Node->getNumOperands() >= 3) 4089 VT = Node->getOperand(2)->getValueType(0); 4090 switch (IntNo) { 4091 default: 4092 break; 4093 case Intrinsic::aarch64_neon_st1x2: { 4094 if (VT == MVT::v8i8) { 4095 SelectStore(Node, 2, AArch64::ST1Twov8b); 4096 return; 4097 } else if (VT == MVT::v16i8) { 4098 SelectStore(Node, 2, AArch64::ST1Twov16b); 4099 return; 4100 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || 4101 VT == MVT::v4bf16) { 4102 SelectStore(Node, 2, AArch64::ST1Twov4h); 4103 return; 4104 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || 4105 VT == MVT::v8bf16) { 4106 SelectStore(Node, 2, AArch64::ST1Twov8h); 4107 return; 4108 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4109 SelectStore(Node, 2, AArch64::ST1Twov2s); 4110 return; 4111 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4112 SelectStore(Node, 2, AArch64::ST1Twov4s); 4113 return; 4114 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4115 SelectStore(Node, 2, AArch64::ST1Twov2d); 4116 return; 4117 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4118 SelectStore(Node, 2, AArch64::ST1Twov1d); 4119 return; 4120 } 4121 break; 4122 } 4123 case Intrinsic::aarch64_neon_st1x3: { 4124 if (VT == MVT::v8i8) { 4125 SelectStore(Node, 3, AArch64::ST1Threev8b); 4126 return; 4127 } else if (VT == MVT::v16i8) { 4128 SelectStore(Node, 3, AArch64::ST1Threev16b); 4129 return; 4130 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || 4131 VT == MVT::v4bf16) { 4132 SelectStore(Node, 3, AArch64::ST1Threev4h); 4133 return; 4134 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || 4135 VT == MVT::v8bf16) { 4136 SelectStore(Node, 3, AArch64::ST1Threev8h); 4137 return; 4138 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4139 SelectStore(Node, 3, AArch64::ST1Threev2s); 4140 return; 4141 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4142 SelectStore(Node, 3, AArch64::ST1Threev4s); 4143 return; 4144 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4145 SelectStore(Node, 3, AArch64::ST1Threev2d); 4146 return; 4147 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4148 SelectStore(Node, 3, AArch64::ST1Threev1d); 4149 return; 4150 } 4151 break; 4152 } 4153 case Intrinsic::aarch64_neon_st1x4: { 4154 if (VT == MVT::v8i8) { 4155 SelectStore(Node, 4, AArch64::ST1Fourv8b); 4156 return; 4157 } else if (VT == MVT::v16i8) { 4158 SelectStore(Node, 4, AArch64::ST1Fourv16b); 4159 return; 4160 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || 4161 VT == MVT::v4bf16) { 4162 SelectStore(Node, 4, AArch64::ST1Fourv4h); 4163 return; 4164 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || 4165 VT == MVT::v8bf16) { 4166 SelectStore(Node, 4, AArch64::ST1Fourv8h); 4167 return; 4168 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4169 SelectStore(Node, 4, AArch64::ST1Fourv2s); 4170 return; 4171 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4172 SelectStore(Node, 4, AArch64::ST1Fourv4s); 4173 return; 4174 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4175 SelectStore(Node, 4, AArch64::ST1Fourv2d); 4176 return; 4177 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4178 SelectStore(Node, 4, AArch64::ST1Fourv1d); 4179 return; 4180 } 4181 break; 4182 } 4183 case Intrinsic::aarch64_neon_st2: { 4184 if (VT == MVT::v8i8) { 4185 SelectStore(Node, 2, AArch64::ST2Twov8b); 4186 return; 4187 } else if (VT == MVT::v16i8) { 4188 SelectStore(Node, 2, AArch64::ST2Twov16b); 4189 return; 4190 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || 4191 VT == MVT::v4bf16) { 4192 SelectStore(Node, 2, AArch64::ST2Twov4h); 4193 return; 4194 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || 4195 VT == MVT::v8bf16) { 4196 SelectStore(Node, 2, AArch64::ST2Twov8h); 4197 return; 4198 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4199 SelectStore(Node, 2, AArch64::ST2Twov2s); 4200 return; 4201 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4202 SelectStore(Node, 2, AArch64::ST2Twov4s); 4203 return; 4204 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4205 SelectStore(Node, 2, AArch64::ST2Twov2d); 4206 return; 4207 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4208 SelectStore(Node, 2, AArch64::ST1Twov1d); 4209 return; 4210 } 4211 break; 4212 } 4213 case Intrinsic::aarch64_neon_st3: { 4214 if (VT == MVT::v8i8) { 4215 SelectStore(Node, 3, AArch64::ST3Threev8b); 4216 return; 4217 } else if (VT == MVT::v16i8) { 4218 SelectStore(Node, 3, AArch64::ST3Threev16b); 4219 return; 4220 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || 4221 VT == MVT::v4bf16) { 4222 SelectStore(Node, 3, AArch64::ST3Threev4h); 4223 return; 4224 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || 4225 VT == MVT::v8bf16) { 4226 SelectStore(Node, 3, AArch64::ST3Threev8h); 4227 return; 4228 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4229 SelectStore(Node, 3, AArch64::ST3Threev2s); 4230 return; 4231 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4232 SelectStore(Node, 3, AArch64::ST3Threev4s); 4233 return; 4234 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4235 SelectStore(Node, 3, AArch64::ST3Threev2d); 4236 return; 4237 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4238 SelectStore(Node, 3, AArch64::ST1Threev1d); 4239 return; 4240 } 4241 break; 4242 } 4243 case Intrinsic::aarch64_neon_st4: { 4244 if (VT == MVT::v8i8) { 4245 SelectStore(Node, 4, AArch64::ST4Fourv8b); 4246 return; 4247 } else if (VT == MVT::v16i8) { 4248 SelectStore(Node, 4, AArch64::ST4Fourv16b); 4249 return; 4250 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || 4251 VT == MVT::v4bf16) { 4252 SelectStore(Node, 4, AArch64::ST4Fourv4h); 4253 return; 4254 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || 4255 VT == MVT::v8bf16) { 4256 SelectStore(Node, 4, AArch64::ST4Fourv8h); 4257 return; 4258 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4259 SelectStore(Node, 4, AArch64::ST4Fourv2s); 4260 return; 4261 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4262 SelectStore(Node, 4, AArch64::ST4Fourv4s); 4263 return; 4264 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4265 SelectStore(Node, 4, AArch64::ST4Fourv2d); 4266 return; 4267 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4268 SelectStore(Node, 4, AArch64::ST1Fourv1d); 4269 return; 4270 } 4271 break; 4272 } 4273 case Intrinsic::aarch64_neon_st2lane: { 4274 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 4275 SelectStoreLane(Node, 2, AArch64::ST2i8); 4276 return; 4277 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 4278 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 4279 SelectStoreLane(Node, 2, AArch64::ST2i16); 4280 return; 4281 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 4282 VT == MVT::v2f32) { 4283 SelectStoreLane(Node, 2, AArch64::ST2i32); 4284 return; 4285 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 4286 VT == MVT::v1f64) { 4287 SelectStoreLane(Node, 2, AArch64::ST2i64); 4288 return; 4289 } 4290 break; 4291 } 4292 case Intrinsic::aarch64_neon_st3lane: { 4293 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 4294 SelectStoreLane(Node, 3, AArch64::ST3i8); 4295 return; 4296 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 4297 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 4298 SelectStoreLane(Node, 3, AArch64::ST3i16); 4299 return; 4300 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 4301 VT == MVT::v2f32) { 4302 SelectStoreLane(Node, 3, AArch64::ST3i32); 4303 return; 4304 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 4305 VT == MVT::v1f64) { 4306 SelectStoreLane(Node, 3, AArch64::ST3i64); 4307 return; 4308 } 4309 break; 4310 } 4311 case Intrinsic::aarch64_neon_st4lane: { 4312 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 4313 SelectStoreLane(Node, 4, AArch64::ST4i8); 4314 return; 4315 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 4316 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 4317 SelectStoreLane(Node, 4, AArch64::ST4i16); 4318 return; 4319 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 4320 VT == MVT::v2f32) { 4321 SelectStoreLane(Node, 4, AArch64::ST4i32); 4322 return; 4323 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 4324 VT == MVT::v1f64) { 4325 SelectStoreLane(Node, 4, AArch64::ST4i64); 4326 return; 4327 } 4328 break; 4329 } 4330 case Intrinsic::aarch64_sve_st2: { 4331 if (VT == MVT::nxv16i8) { 4332 SelectPredicatedStore(Node, 2, 0, AArch64::ST2B, AArch64::ST2B_IMM); 4333 return; 4334 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 || 4335 VT == MVT::nxv8bf16) { 4336 SelectPredicatedStore(Node, 2, 1, AArch64::ST2H, AArch64::ST2H_IMM); 4337 return; 4338 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) { 4339 SelectPredicatedStore(Node, 2, 2, AArch64::ST2W, AArch64::ST2W_IMM); 4340 return; 4341 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) { 4342 SelectPredicatedStore(Node, 2, 3, AArch64::ST2D, AArch64::ST2D_IMM); 4343 return; 4344 } 4345 break; 4346 } 4347 case Intrinsic::aarch64_sve_st3: { 4348 if (VT == MVT::nxv16i8) { 4349 SelectPredicatedStore(Node, 3, 0, AArch64::ST3B, AArch64::ST3B_IMM); 4350 return; 4351 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 || 4352 VT == MVT::nxv8bf16) { 4353 SelectPredicatedStore(Node, 3, 1, AArch64::ST3H, AArch64::ST3H_IMM); 4354 return; 4355 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) { 4356 SelectPredicatedStore(Node, 3, 2, AArch64::ST3W, AArch64::ST3W_IMM); 4357 return; 4358 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) { 4359 SelectPredicatedStore(Node, 3, 3, AArch64::ST3D, AArch64::ST3D_IMM); 4360 return; 4361 } 4362 break; 4363 } 4364 case Intrinsic::aarch64_sve_st4: { 4365 if (VT == MVT::nxv16i8) { 4366 SelectPredicatedStore(Node, 4, 0, AArch64::ST4B, AArch64::ST4B_IMM); 4367 return; 4368 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 || 4369 VT == MVT::nxv8bf16) { 4370 SelectPredicatedStore(Node, 4, 1, AArch64::ST4H, AArch64::ST4H_IMM); 4371 return; 4372 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) { 4373 SelectPredicatedStore(Node, 4, 2, AArch64::ST4W, AArch64::ST4W_IMM); 4374 return; 4375 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) { 4376 SelectPredicatedStore(Node, 4, 3, AArch64::ST4D, AArch64::ST4D_IMM); 4377 return; 4378 } 4379 break; 4380 } 4381 } 4382 break; 4383 } 4384 case AArch64ISD::LD2post: { 4385 if (VT == MVT::v8i8) { 4386 SelectPostLoad(Node, 2, AArch64::LD2Twov8b_POST, AArch64::dsub0); 4387 return; 4388 } else if (VT == MVT::v16i8) { 4389 SelectPostLoad(Node, 2, AArch64::LD2Twov16b_POST, AArch64::qsub0); 4390 return; 4391 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4392 SelectPostLoad(Node, 2, AArch64::LD2Twov4h_POST, AArch64::dsub0); 4393 return; 4394 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4395 SelectPostLoad(Node, 2, AArch64::LD2Twov8h_POST, AArch64::qsub0); 4396 return; 4397 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4398 SelectPostLoad(Node, 2, AArch64::LD2Twov2s_POST, AArch64::dsub0); 4399 return; 4400 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4401 SelectPostLoad(Node, 2, AArch64::LD2Twov4s_POST, AArch64::qsub0); 4402 return; 4403 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4404 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0); 4405 return; 4406 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4407 SelectPostLoad(Node, 2, AArch64::LD2Twov2d_POST, AArch64::qsub0); 4408 return; 4409 } 4410 break; 4411 } 4412 case AArch64ISD::LD3post: { 4413 if (VT == MVT::v8i8) { 4414 SelectPostLoad(Node, 3, AArch64::LD3Threev8b_POST, AArch64::dsub0); 4415 return; 4416 } else if (VT == MVT::v16i8) { 4417 SelectPostLoad(Node, 3, AArch64::LD3Threev16b_POST, AArch64::qsub0); 4418 return; 4419 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4420 SelectPostLoad(Node, 3, AArch64::LD3Threev4h_POST, AArch64::dsub0); 4421 return; 4422 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4423 SelectPostLoad(Node, 3, AArch64::LD3Threev8h_POST, AArch64::qsub0); 4424 return; 4425 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4426 SelectPostLoad(Node, 3, AArch64::LD3Threev2s_POST, AArch64::dsub0); 4427 return; 4428 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4429 SelectPostLoad(Node, 3, AArch64::LD3Threev4s_POST, AArch64::qsub0); 4430 return; 4431 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4432 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0); 4433 return; 4434 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4435 SelectPostLoad(Node, 3, AArch64::LD3Threev2d_POST, AArch64::qsub0); 4436 return; 4437 } 4438 break; 4439 } 4440 case AArch64ISD::LD4post: { 4441 if (VT == MVT::v8i8) { 4442 SelectPostLoad(Node, 4, AArch64::LD4Fourv8b_POST, AArch64::dsub0); 4443 return; 4444 } else if (VT == MVT::v16i8) { 4445 SelectPostLoad(Node, 4, AArch64::LD4Fourv16b_POST, AArch64::qsub0); 4446 return; 4447 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4448 SelectPostLoad(Node, 4, AArch64::LD4Fourv4h_POST, AArch64::dsub0); 4449 return; 4450 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4451 SelectPostLoad(Node, 4, AArch64::LD4Fourv8h_POST, AArch64::qsub0); 4452 return; 4453 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4454 SelectPostLoad(Node, 4, AArch64::LD4Fourv2s_POST, AArch64::dsub0); 4455 return; 4456 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4457 SelectPostLoad(Node, 4, AArch64::LD4Fourv4s_POST, AArch64::qsub0); 4458 return; 4459 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4460 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0); 4461 return; 4462 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4463 SelectPostLoad(Node, 4, AArch64::LD4Fourv2d_POST, AArch64::qsub0); 4464 return; 4465 } 4466 break; 4467 } 4468 case AArch64ISD::LD1x2post: { 4469 if (VT == MVT::v8i8) { 4470 SelectPostLoad(Node, 2, AArch64::LD1Twov8b_POST, AArch64::dsub0); 4471 return; 4472 } else if (VT == MVT::v16i8) { 4473 SelectPostLoad(Node, 2, AArch64::LD1Twov16b_POST, AArch64::qsub0); 4474 return; 4475 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4476 SelectPostLoad(Node, 2, AArch64::LD1Twov4h_POST, AArch64::dsub0); 4477 return; 4478 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4479 SelectPostLoad(Node, 2, AArch64::LD1Twov8h_POST, AArch64::qsub0); 4480 return; 4481 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4482 SelectPostLoad(Node, 2, AArch64::LD1Twov2s_POST, AArch64::dsub0); 4483 return; 4484 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4485 SelectPostLoad(Node, 2, AArch64::LD1Twov4s_POST, AArch64::qsub0); 4486 return; 4487 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4488 SelectPostLoad(Node, 2, AArch64::LD1Twov1d_POST, AArch64::dsub0); 4489 return; 4490 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4491 SelectPostLoad(Node, 2, AArch64::LD1Twov2d_POST, AArch64::qsub0); 4492 return; 4493 } 4494 break; 4495 } 4496 case AArch64ISD::LD1x3post: { 4497 if (VT == MVT::v8i8) { 4498 SelectPostLoad(Node, 3, AArch64::LD1Threev8b_POST, AArch64::dsub0); 4499 return; 4500 } else if (VT == MVT::v16i8) { 4501 SelectPostLoad(Node, 3, AArch64::LD1Threev16b_POST, AArch64::qsub0); 4502 return; 4503 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4504 SelectPostLoad(Node, 3, AArch64::LD1Threev4h_POST, AArch64::dsub0); 4505 return; 4506 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4507 SelectPostLoad(Node, 3, AArch64::LD1Threev8h_POST, AArch64::qsub0); 4508 return; 4509 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4510 SelectPostLoad(Node, 3, AArch64::LD1Threev2s_POST, AArch64::dsub0); 4511 return; 4512 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4513 SelectPostLoad(Node, 3, AArch64::LD1Threev4s_POST, AArch64::qsub0); 4514 return; 4515 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4516 SelectPostLoad(Node, 3, AArch64::LD1Threev1d_POST, AArch64::dsub0); 4517 return; 4518 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4519 SelectPostLoad(Node, 3, AArch64::LD1Threev2d_POST, AArch64::qsub0); 4520 return; 4521 } 4522 break; 4523 } 4524 case AArch64ISD::LD1x4post: { 4525 if (VT == MVT::v8i8) { 4526 SelectPostLoad(Node, 4, AArch64::LD1Fourv8b_POST, AArch64::dsub0); 4527 return; 4528 } else if (VT == MVT::v16i8) { 4529 SelectPostLoad(Node, 4, AArch64::LD1Fourv16b_POST, AArch64::qsub0); 4530 return; 4531 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4532 SelectPostLoad(Node, 4, AArch64::LD1Fourv4h_POST, AArch64::dsub0); 4533 return; 4534 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4535 SelectPostLoad(Node, 4, AArch64::LD1Fourv8h_POST, AArch64::qsub0); 4536 return; 4537 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4538 SelectPostLoad(Node, 4, AArch64::LD1Fourv2s_POST, AArch64::dsub0); 4539 return; 4540 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4541 SelectPostLoad(Node, 4, AArch64::LD1Fourv4s_POST, AArch64::qsub0); 4542 return; 4543 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4544 SelectPostLoad(Node, 4, AArch64::LD1Fourv1d_POST, AArch64::dsub0); 4545 return; 4546 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4547 SelectPostLoad(Node, 4, AArch64::LD1Fourv2d_POST, AArch64::qsub0); 4548 return; 4549 } 4550 break; 4551 } 4552 case AArch64ISD::LD1DUPpost: { 4553 if (VT == MVT::v8i8) { 4554 SelectPostLoad(Node, 1, AArch64::LD1Rv8b_POST, AArch64::dsub0); 4555 return; 4556 } else if (VT == MVT::v16i8) { 4557 SelectPostLoad(Node, 1, AArch64::LD1Rv16b_POST, AArch64::qsub0); 4558 return; 4559 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4560 SelectPostLoad(Node, 1, AArch64::LD1Rv4h_POST, AArch64::dsub0); 4561 return; 4562 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4563 SelectPostLoad(Node, 1, AArch64::LD1Rv8h_POST, AArch64::qsub0); 4564 return; 4565 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4566 SelectPostLoad(Node, 1, AArch64::LD1Rv2s_POST, AArch64::dsub0); 4567 return; 4568 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4569 SelectPostLoad(Node, 1, AArch64::LD1Rv4s_POST, AArch64::qsub0); 4570 return; 4571 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4572 SelectPostLoad(Node, 1, AArch64::LD1Rv1d_POST, AArch64::dsub0); 4573 return; 4574 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4575 SelectPostLoad(Node, 1, AArch64::LD1Rv2d_POST, AArch64::qsub0); 4576 return; 4577 } 4578 break; 4579 } 4580 case AArch64ISD::LD2DUPpost: { 4581 if (VT == MVT::v8i8) { 4582 SelectPostLoad(Node, 2, AArch64::LD2Rv8b_POST, AArch64::dsub0); 4583 return; 4584 } else if (VT == MVT::v16i8) { 4585 SelectPostLoad(Node, 2, AArch64::LD2Rv16b_POST, AArch64::qsub0); 4586 return; 4587 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4588 SelectPostLoad(Node, 2, AArch64::LD2Rv4h_POST, AArch64::dsub0); 4589 return; 4590 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4591 SelectPostLoad(Node, 2, AArch64::LD2Rv8h_POST, AArch64::qsub0); 4592 return; 4593 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4594 SelectPostLoad(Node, 2, AArch64::LD2Rv2s_POST, AArch64::dsub0); 4595 return; 4596 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4597 SelectPostLoad(Node, 2, AArch64::LD2Rv4s_POST, AArch64::qsub0); 4598 return; 4599 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4600 SelectPostLoad(Node, 2, AArch64::LD2Rv1d_POST, AArch64::dsub0); 4601 return; 4602 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4603 SelectPostLoad(Node, 2, AArch64::LD2Rv2d_POST, AArch64::qsub0); 4604 return; 4605 } 4606 break; 4607 } 4608 case AArch64ISD::LD3DUPpost: { 4609 if (VT == MVT::v8i8) { 4610 SelectPostLoad(Node, 3, AArch64::LD3Rv8b_POST, AArch64::dsub0); 4611 return; 4612 } else if (VT == MVT::v16i8) { 4613 SelectPostLoad(Node, 3, AArch64::LD3Rv16b_POST, AArch64::qsub0); 4614 return; 4615 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4616 SelectPostLoad(Node, 3, AArch64::LD3Rv4h_POST, AArch64::dsub0); 4617 return; 4618 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4619 SelectPostLoad(Node, 3, AArch64::LD3Rv8h_POST, AArch64::qsub0); 4620 return; 4621 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4622 SelectPostLoad(Node, 3, AArch64::LD3Rv2s_POST, AArch64::dsub0); 4623 return; 4624 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4625 SelectPostLoad(Node, 3, AArch64::LD3Rv4s_POST, AArch64::qsub0); 4626 return; 4627 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4628 SelectPostLoad(Node, 3, AArch64::LD3Rv1d_POST, AArch64::dsub0); 4629 return; 4630 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4631 SelectPostLoad(Node, 3, AArch64::LD3Rv2d_POST, AArch64::qsub0); 4632 return; 4633 } 4634 break; 4635 } 4636 case AArch64ISD::LD4DUPpost: { 4637 if (VT == MVT::v8i8) { 4638 SelectPostLoad(Node, 4, AArch64::LD4Rv8b_POST, AArch64::dsub0); 4639 return; 4640 } else if (VT == MVT::v16i8) { 4641 SelectPostLoad(Node, 4, AArch64::LD4Rv16b_POST, AArch64::qsub0); 4642 return; 4643 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4644 SelectPostLoad(Node, 4, AArch64::LD4Rv4h_POST, AArch64::dsub0); 4645 return; 4646 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4647 SelectPostLoad(Node, 4, AArch64::LD4Rv8h_POST, AArch64::qsub0); 4648 return; 4649 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4650 SelectPostLoad(Node, 4, AArch64::LD4Rv2s_POST, AArch64::dsub0); 4651 return; 4652 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4653 SelectPostLoad(Node, 4, AArch64::LD4Rv4s_POST, AArch64::qsub0); 4654 return; 4655 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4656 SelectPostLoad(Node, 4, AArch64::LD4Rv1d_POST, AArch64::dsub0); 4657 return; 4658 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4659 SelectPostLoad(Node, 4, AArch64::LD4Rv2d_POST, AArch64::qsub0); 4660 return; 4661 } 4662 break; 4663 } 4664 case AArch64ISD::LD1LANEpost: { 4665 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 4666 SelectPostLoadLane(Node, 1, AArch64::LD1i8_POST); 4667 return; 4668 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 4669 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 4670 SelectPostLoadLane(Node, 1, AArch64::LD1i16_POST); 4671 return; 4672 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 4673 VT == MVT::v2f32) { 4674 SelectPostLoadLane(Node, 1, AArch64::LD1i32_POST); 4675 return; 4676 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 4677 VT == MVT::v1f64) { 4678 SelectPostLoadLane(Node, 1, AArch64::LD1i64_POST); 4679 return; 4680 } 4681 break; 4682 } 4683 case AArch64ISD::LD2LANEpost: { 4684 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 4685 SelectPostLoadLane(Node, 2, AArch64::LD2i8_POST); 4686 return; 4687 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 4688 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 4689 SelectPostLoadLane(Node, 2, AArch64::LD2i16_POST); 4690 return; 4691 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 4692 VT == MVT::v2f32) { 4693 SelectPostLoadLane(Node, 2, AArch64::LD2i32_POST); 4694 return; 4695 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 4696 VT == MVT::v1f64) { 4697 SelectPostLoadLane(Node, 2, AArch64::LD2i64_POST); 4698 return; 4699 } 4700 break; 4701 } 4702 case AArch64ISD::LD3LANEpost: { 4703 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 4704 SelectPostLoadLane(Node, 3, AArch64::LD3i8_POST); 4705 return; 4706 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 4707 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 4708 SelectPostLoadLane(Node, 3, AArch64::LD3i16_POST); 4709 return; 4710 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 4711 VT == MVT::v2f32) { 4712 SelectPostLoadLane(Node, 3, AArch64::LD3i32_POST); 4713 return; 4714 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 4715 VT == MVT::v1f64) { 4716 SelectPostLoadLane(Node, 3, AArch64::LD3i64_POST); 4717 return; 4718 } 4719 break; 4720 } 4721 case AArch64ISD::LD4LANEpost: { 4722 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 4723 SelectPostLoadLane(Node, 4, AArch64::LD4i8_POST); 4724 return; 4725 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 4726 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 4727 SelectPostLoadLane(Node, 4, AArch64::LD4i16_POST); 4728 return; 4729 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 4730 VT == MVT::v2f32) { 4731 SelectPostLoadLane(Node, 4, AArch64::LD4i32_POST); 4732 return; 4733 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 4734 VT == MVT::v1f64) { 4735 SelectPostLoadLane(Node, 4, AArch64::LD4i64_POST); 4736 return; 4737 } 4738 break; 4739 } 4740 case AArch64ISD::ST2post: { 4741 VT = Node->getOperand(1).getValueType(); 4742 if (VT == MVT::v8i8) { 4743 SelectPostStore(Node, 2, AArch64::ST2Twov8b_POST); 4744 return; 4745 } else if (VT == MVT::v16i8) { 4746 SelectPostStore(Node, 2, AArch64::ST2Twov16b_POST); 4747 return; 4748 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4749 SelectPostStore(Node, 2, AArch64::ST2Twov4h_POST); 4750 return; 4751 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4752 SelectPostStore(Node, 2, AArch64::ST2Twov8h_POST); 4753 return; 4754 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4755 SelectPostStore(Node, 2, AArch64::ST2Twov2s_POST); 4756 return; 4757 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4758 SelectPostStore(Node, 2, AArch64::ST2Twov4s_POST); 4759 return; 4760 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4761 SelectPostStore(Node, 2, AArch64::ST2Twov2d_POST); 4762 return; 4763 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4764 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST); 4765 return; 4766 } 4767 break; 4768 } 4769 case AArch64ISD::ST3post: { 4770 VT = Node->getOperand(1).getValueType(); 4771 if (VT == MVT::v8i8) { 4772 SelectPostStore(Node, 3, AArch64::ST3Threev8b_POST); 4773 return; 4774 } else if (VT == MVT::v16i8) { 4775 SelectPostStore(Node, 3, AArch64::ST3Threev16b_POST); 4776 return; 4777 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4778 SelectPostStore(Node, 3, AArch64::ST3Threev4h_POST); 4779 return; 4780 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4781 SelectPostStore(Node, 3, AArch64::ST3Threev8h_POST); 4782 return; 4783 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4784 SelectPostStore(Node, 3, AArch64::ST3Threev2s_POST); 4785 return; 4786 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4787 SelectPostStore(Node, 3, AArch64::ST3Threev4s_POST); 4788 return; 4789 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4790 SelectPostStore(Node, 3, AArch64::ST3Threev2d_POST); 4791 return; 4792 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4793 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST); 4794 return; 4795 } 4796 break; 4797 } 4798 case AArch64ISD::ST4post: { 4799 VT = Node->getOperand(1).getValueType(); 4800 if (VT == MVT::v8i8) { 4801 SelectPostStore(Node, 4, AArch64::ST4Fourv8b_POST); 4802 return; 4803 } else if (VT == MVT::v16i8) { 4804 SelectPostStore(Node, 4, AArch64::ST4Fourv16b_POST); 4805 return; 4806 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4807 SelectPostStore(Node, 4, AArch64::ST4Fourv4h_POST); 4808 return; 4809 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4810 SelectPostStore(Node, 4, AArch64::ST4Fourv8h_POST); 4811 return; 4812 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4813 SelectPostStore(Node, 4, AArch64::ST4Fourv2s_POST); 4814 return; 4815 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4816 SelectPostStore(Node, 4, AArch64::ST4Fourv4s_POST); 4817 return; 4818 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4819 SelectPostStore(Node, 4, AArch64::ST4Fourv2d_POST); 4820 return; 4821 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4822 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST); 4823 return; 4824 } 4825 break; 4826 } 4827 case AArch64ISD::ST1x2post: { 4828 VT = Node->getOperand(1).getValueType(); 4829 if (VT == MVT::v8i8) { 4830 SelectPostStore(Node, 2, AArch64::ST1Twov8b_POST); 4831 return; 4832 } else if (VT == MVT::v16i8) { 4833 SelectPostStore(Node, 2, AArch64::ST1Twov16b_POST); 4834 return; 4835 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4836 SelectPostStore(Node, 2, AArch64::ST1Twov4h_POST); 4837 return; 4838 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4839 SelectPostStore(Node, 2, AArch64::ST1Twov8h_POST); 4840 return; 4841 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4842 SelectPostStore(Node, 2, AArch64::ST1Twov2s_POST); 4843 return; 4844 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4845 SelectPostStore(Node, 2, AArch64::ST1Twov4s_POST); 4846 return; 4847 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4848 SelectPostStore(Node, 2, AArch64::ST1Twov1d_POST); 4849 return; 4850 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4851 SelectPostStore(Node, 2, AArch64::ST1Twov2d_POST); 4852 return; 4853 } 4854 break; 4855 } 4856 case AArch64ISD::ST1x3post: { 4857 VT = Node->getOperand(1).getValueType(); 4858 if (VT == MVT::v8i8) { 4859 SelectPostStore(Node, 3, AArch64::ST1Threev8b_POST); 4860 return; 4861 } else if (VT == MVT::v16i8) { 4862 SelectPostStore(Node, 3, AArch64::ST1Threev16b_POST); 4863 return; 4864 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4865 SelectPostStore(Node, 3, AArch64::ST1Threev4h_POST); 4866 return; 4867 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16 ) { 4868 SelectPostStore(Node, 3, AArch64::ST1Threev8h_POST); 4869 return; 4870 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4871 SelectPostStore(Node, 3, AArch64::ST1Threev2s_POST); 4872 return; 4873 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4874 SelectPostStore(Node, 3, AArch64::ST1Threev4s_POST); 4875 return; 4876 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4877 SelectPostStore(Node, 3, AArch64::ST1Threev1d_POST); 4878 return; 4879 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4880 SelectPostStore(Node, 3, AArch64::ST1Threev2d_POST); 4881 return; 4882 } 4883 break; 4884 } 4885 case AArch64ISD::ST1x4post: { 4886 VT = Node->getOperand(1).getValueType(); 4887 if (VT == MVT::v8i8) { 4888 SelectPostStore(Node, 4, AArch64::ST1Fourv8b_POST); 4889 return; 4890 } else if (VT == MVT::v16i8) { 4891 SelectPostStore(Node, 4, AArch64::ST1Fourv16b_POST); 4892 return; 4893 } else if (VT == MVT::v4i16 || VT == MVT::v4f16 || VT == MVT::v4bf16) { 4894 SelectPostStore(Node, 4, AArch64::ST1Fourv4h_POST); 4895 return; 4896 } else if (VT == MVT::v8i16 || VT == MVT::v8f16 || VT == MVT::v8bf16) { 4897 SelectPostStore(Node, 4, AArch64::ST1Fourv8h_POST); 4898 return; 4899 } else if (VT == MVT::v2i32 || VT == MVT::v2f32) { 4900 SelectPostStore(Node, 4, AArch64::ST1Fourv2s_POST); 4901 return; 4902 } else if (VT == MVT::v4i32 || VT == MVT::v4f32) { 4903 SelectPostStore(Node, 4, AArch64::ST1Fourv4s_POST); 4904 return; 4905 } else if (VT == MVT::v1i64 || VT == MVT::v1f64) { 4906 SelectPostStore(Node, 4, AArch64::ST1Fourv1d_POST); 4907 return; 4908 } else if (VT == MVT::v2i64 || VT == MVT::v2f64) { 4909 SelectPostStore(Node, 4, AArch64::ST1Fourv2d_POST); 4910 return; 4911 } 4912 break; 4913 } 4914 case AArch64ISD::ST2LANEpost: { 4915 VT = Node->getOperand(1).getValueType(); 4916 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 4917 SelectPostStoreLane(Node, 2, AArch64::ST2i8_POST); 4918 return; 4919 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 4920 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 4921 SelectPostStoreLane(Node, 2, AArch64::ST2i16_POST); 4922 return; 4923 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 4924 VT == MVT::v2f32) { 4925 SelectPostStoreLane(Node, 2, AArch64::ST2i32_POST); 4926 return; 4927 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 4928 VT == MVT::v1f64) { 4929 SelectPostStoreLane(Node, 2, AArch64::ST2i64_POST); 4930 return; 4931 } 4932 break; 4933 } 4934 case AArch64ISD::ST3LANEpost: { 4935 VT = Node->getOperand(1).getValueType(); 4936 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 4937 SelectPostStoreLane(Node, 3, AArch64::ST3i8_POST); 4938 return; 4939 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 4940 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 4941 SelectPostStoreLane(Node, 3, AArch64::ST3i16_POST); 4942 return; 4943 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 4944 VT == MVT::v2f32) { 4945 SelectPostStoreLane(Node, 3, AArch64::ST3i32_POST); 4946 return; 4947 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 4948 VT == MVT::v1f64) { 4949 SelectPostStoreLane(Node, 3, AArch64::ST3i64_POST); 4950 return; 4951 } 4952 break; 4953 } 4954 case AArch64ISD::ST4LANEpost: { 4955 VT = Node->getOperand(1).getValueType(); 4956 if (VT == MVT::v16i8 || VT == MVT::v8i8) { 4957 SelectPostStoreLane(Node, 4, AArch64::ST4i8_POST); 4958 return; 4959 } else if (VT == MVT::v8i16 || VT == MVT::v4i16 || VT == MVT::v4f16 || 4960 VT == MVT::v8f16 || VT == MVT::v4bf16 || VT == MVT::v8bf16) { 4961 SelectPostStoreLane(Node, 4, AArch64::ST4i16_POST); 4962 return; 4963 } else if (VT == MVT::v4i32 || VT == MVT::v2i32 || VT == MVT::v4f32 || 4964 VT == MVT::v2f32) { 4965 SelectPostStoreLane(Node, 4, AArch64::ST4i32_POST); 4966 return; 4967 } else if (VT == MVT::v2i64 || VT == MVT::v1i64 || VT == MVT::v2f64 || 4968 VT == MVT::v1f64) { 4969 SelectPostStoreLane(Node, 4, AArch64::ST4i64_POST); 4970 return; 4971 } 4972 break; 4973 } 4974 case AArch64ISD::SVE_LD2_MERGE_ZERO: { 4975 if (VT == MVT::nxv16i8) { 4976 SelectPredicatedLoad(Node, 2, 0, AArch64::LD2B_IMM, AArch64::LD2B); 4977 return; 4978 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 || 4979 VT == MVT::nxv8bf16) { 4980 SelectPredicatedLoad(Node, 2, 1, AArch64::LD2H_IMM, AArch64::LD2H); 4981 return; 4982 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) { 4983 SelectPredicatedLoad(Node, 2, 2, AArch64::LD2W_IMM, AArch64::LD2W); 4984 return; 4985 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) { 4986 SelectPredicatedLoad(Node, 2, 3, AArch64::LD2D_IMM, AArch64::LD2D); 4987 return; 4988 } 4989 break; 4990 } 4991 case AArch64ISD::SVE_LD3_MERGE_ZERO: { 4992 if (VT == MVT::nxv16i8) { 4993 SelectPredicatedLoad(Node, 3, 0, AArch64::LD3B_IMM, AArch64::LD3B); 4994 return; 4995 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 || 4996 VT == MVT::nxv8bf16) { 4997 SelectPredicatedLoad(Node, 3, 1, AArch64::LD3H_IMM, AArch64::LD3H); 4998 return; 4999 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) { 5000 SelectPredicatedLoad(Node, 3, 2, AArch64::LD3W_IMM, AArch64::LD3W); 5001 return; 5002 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) { 5003 SelectPredicatedLoad(Node, 3, 3, AArch64::LD3D_IMM, AArch64::LD3D); 5004 return; 5005 } 5006 break; 5007 } 5008 case AArch64ISD::SVE_LD4_MERGE_ZERO: { 5009 if (VT == MVT::nxv16i8) { 5010 SelectPredicatedLoad(Node, 4, 0, AArch64::LD4B_IMM, AArch64::LD4B); 5011 return; 5012 } else if (VT == MVT::nxv8i16 || VT == MVT::nxv8f16 || 5013 VT == MVT::nxv8bf16) { 5014 SelectPredicatedLoad(Node, 4, 1, AArch64::LD4H_IMM, AArch64::LD4H); 5015 return; 5016 } else if (VT == MVT::nxv4i32 || VT == MVT::nxv4f32) { 5017 SelectPredicatedLoad(Node, 4, 2, AArch64::LD4W_IMM, AArch64::LD4W); 5018 return; 5019 } else if (VT == MVT::nxv2i64 || VT == MVT::nxv2f64) { 5020 SelectPredicatedLoad(Node, 4, 3, AArch64::LD4D_IMM, AArch64::LD4D); 5021 return; 5022 } 5023 break; 5024 } 5025 } 5026 5027 // Select the default instruction 5028 SelectCode(Node); 5029 } 5030 5031 /// createAArch64ISelDag - This pass converts a legalized DAG into a 5032 /// AArch64-specific DAG, ready for instruction scheduling. 5033 FunctionPass *llvm::createAArch64ISelDag(AArch64TargetMachine &TM, 5034 CodeGenOpt::Level OptLevel) { 5035 return new AArch64DAGToDAGISel(TM, OptLevel); 5036 } 5037 5038 /// When \p PredVT is a scalable vector predicate in the form 5039 /// MVT::nx<M>xi1, it builds the correspondent scalable vector of 5040 /// integers MVT::nx<M>xi<bits> s.t. M x bits = 128. When targeting 5041 /// structured vectors (NumVec >1), the output data type is 5042 /// MVT::nx<M*NumVec>xi<bits> s.t. M x bits = 128. If the input 5043 /// PredVT is not in the form MVT::nx<M>xi1, it returns an invalid 5044 /// EVT. 5045 static EVT getPackedVectorTypeFromPredicateType(LLVMContext &Ctx, EVT PredVT, 5046 unsigned NumVec) { 5047 assert(NumVec > 0 && NumVec < 5 && "Invalid number of vectors."); 5048 if (!PredVT.isScalableVector() || PredVT.getVectorElementType() != MVT::i1) 5049 return EVT(); 5050 5051 if (PredVT != MVT::nxv16i1 && PredVT != MVT::nxv8i1 && 5052 PredVT != MVT::nxv4i1 && PredVT != MVT::nxv2i1) 5053 return EVT(); 5054 5055 ElementCount EC = PredVT.getVectorElementCount(); 5056 EVT ScalarVT = 5057 EVT::getIntegerVT(Ctx, AArch64::SVEBitsPerBlock / EC.getKnownMinValue()); 5058 EVT MemVT = EVT::getVectorVT(Ctx, ScalarVT, EC * NumVec); 5059 5060 return MemVT; 5061 } 5062 5063 /// Return the EVT of the data associated to a memory operation in \p 5064 /// Root. If such EVT cannot be retrived, it returns an invalid EVT. 5065 static EVT getMemVTFromNode(LLVMContext &Ctx, SDNode *Root) { 5066 if (isa<MemSDNode>(Root)) 5067 return cast<MemSDNode>(Root)->getMemoryVT(); 5068 5069 if (isa<MemIntrinsicSDNode>(Root)) 5070 return cast<MemIntrinsicSDNode>(Root)->getMemoryVT(); 5071 5072 const unsigned Opcode = Root->getOpcode(); 5073 // For custom ISD nodes, we have to look at them individually to extract the 5074 // type of the data moved to/from memory. 5075 switch (Opcode) { 5076 case AArch64ISD::LD1_MERGE_ZERO: 5077 case AArch64ISD::LD1S_MERGE_ZERO: 5078 case AArch64ISD::LDNF1_MERGE_ZERO: 5079 case AArch64ISD::LDNF1S_MERGE_ZERO: 5080 return cast<VTSDNode>(Root->getOperand(3))->getVT(); 5081 case AArch64ISD::ST1_PRED: 5082 return cast<VTSDNode>(Root->getOperand(4))->getVT(); 5083 case AArch64ISD::SVE_LD2_MERGE_ZERO: 5084 return getPackedVectorTypeFromPredicateType( 5085 Ctx, Root->getOperand(1)->getValueType(0), /*NumVec=*/2); 5086 case AArch64ISD::SVE_LD3_MERGE_ZERO: 5087 return getPackedVectorTypeFromPredicateType( 5088 Ctx, Root->getOperand(1)->getValueType(0), /*NumVec=*/3); 5089 case AArch64ISD::SVE_LD4_MERGE_ZERO: 5090 return getPackedVectorTypeFromPredicateType( 5091 Ctx, Root->getOperand(1)->getValueType(0), /*NumVec=*/4); 5092 default: 5093 break; 5094 } 5095 5096 if (Opcode != ISD::INTRINSIC_VOID) 5097 return EVT(); 5098 5099 const unsigned IntNo = 5100 cast<ConstantSDNode>(Root->getOperand(1))->getZExtValue(); 5101 if (IntNo != Intrinsic::aarch64_sve_prf) 5102 return EVT(); 5103 5104 // We are using an SVE prefetch intrinsic. Type must be inferred 5105 // from the width of the predicate. 5106 return getPackedVectorTypeFromPredicateType( 5107 Ctx, Root->getOperand(2)->getValueType(0), /*NumVec=*/1); 5108 } 5109 5110 /// SelectAddrModeIndexedSVE - Attempt selection of the addressing mode: 5111 /// Base + OffImm * sizeof(MemVT) for Min >= OffImm <= Max 5112 /// where Root is the memory access using N for its address. 5113 template <int64_t Min, int64_t Max> 5114 bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root, SDValue N, 5115 SDValue &Base, 5116 SDValue &OffImm) { 5117 const EVT MemVT = getMemVTFromNode(*(CurDAG->getContext()), Root); 5118 const DataLayout &DL = CurDAG->getDataLayout(); 5119 const MachineFrameInfo &MFI = MF->getFrameInfo(); 5120 5121 if (N.getOpcode() == ISD::FrameIndex) { 5122 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 5123 // We can only encode VL scaled offsets, so only fold in frame indexes 5124 // referencing SVE objects. 5125 if (FI == 0 || MFI.getStackID(FI) == TargetStackID::ScalableVector) { 5126 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL)); 5127 OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i64); 5128 return true; 5129 } 5130 5131 return false; 5132 } 5133 5134 if (MemVT == EVT()) 5135 return false; 5136 5137 if (N.getOpcode() != ISD::ADD) 5138 return false; 5139 5140 SDValue VScale = N.getOperand(1); 5141 if (VScale.getOpcode() != ISD::VSCALE) 5142 return false; 5143 5144 TypeSize TS = MemVT.getSizeInBits(); 5145 int64_t MemWidthBytes = static_cast<int64_t>(TS.getKnownMinSize()) / 8; 5146 int64_t MulImm = cast<ConstantSDNode>(VScale.getOperand(0))->getSExtValue(); 5147 5148 if ((MulImm % MemWidthBytes) != 0) 5149 return false; 5150 5151 int64_t Offset = MulImm / MemWidthBytes; 5152 if (Offset < Min || Offset > Max) 5153 return false; 5154 5155 Base = N.getOperand(0); 5156 if (Base.getOpcode() == ISD::FrameIndex) { 5157 int FI = cast<FrameIndexSDNode>(Base)->getIndex(); 5158 // We can only encode VL scaled offsets, so only fold in frame indexes 5159 // referencing SVE objects. 5160 if (FI == 0 || MFI.getStackID(FI) == TargetStackID::ScalableVector) 5161 Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL)); 5162 } 5163 5164 OffImm = CurDAG->getTargetConstant(Offset, SDLoc(N), MVT::i64); 5165 return true; 5166 } 5167 5168 /// Select register plus register addressing mode for SVE, with scaled 5169 /// offset. 5170 bool AArch64DAGToDAGISel::SelectSVERegRegAddrMode(SDValue N, unsigned Scale, 5171 SDValue &Base, 5172 SDValue &Offset) { 5173 if (N.getOpcode() != ISD::ADD) 5174 return false; 5175 5176 // Process an ADD node. 5177 const SDValue LHS = N.getOperand(0); 5178 const SDValue RHS = N.getOperand(1); 5179 5180 // 8 bit data does not come with the SHL node, so it is treated 5181 // separately. 5182 if (Scale == 0) { 5183 Base = LHS; 5184 Offset = RHS; 5185 return true; 5186 } 5187 5188 if (auto C = dyn_cast<ConstantSDNode>(RHS)) { 5189 int64_t ImmOff = C->getSExtValue(); 5190 unsigned Size = 1 << Scale; 5191 5192 // To use the reg+reg addressing mode, the immediate must be a multiple of 5193 // the vector element's byte size. 5194 if (ImmOff % Size) 5195 return false; 5196 5197 SDLoc DL(N); 5198 Base = LHS; 5199 Offset = CurDAG->getTargetConstant(ImmOff >> Scale, DL, MVT::i64); 5200 SDValue Ops[] = {Offset}; 5201 SDNode *MI = CurDAG->getMachineNode(AArch64::MOVi64imm, DL, MVT::i64, Ops); 5202 Offset = SDValue(MI, 0); 5203 return true; 5204 } 5205 5206 // Check if the RHS is a shift node with a constant. 5207 if (RHS.getOpcode() != ISD::SHL) 5208 return false; 5209 5210 const SDValue ShiftRHS = RHS.getOperand(1); 5211 if (auto *C = dyn_cast<ConstantSDNode>(ShiftRHS)) 5212 if (C->getZExtValue() == Scale) { 5213 Base = LHS; 5214 Offset = RHS.getOperand(0); 5215 return true; 5216 } 5217 5218 return false; 5219 } 5220 5221 bool AArch64DAGToDAGISel::SelectAllActivePredicate(SDValue N) { 5222 const AArch64TargetLowering *TLI = 5223 static_cast<const AArch64TargetLowering *>(getTargetLowering()); 5224 5225 return TLI->isAllActivePredicate(*CurDAG, N); 5226 } 5227