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