1 //===-- AMDILISelDAGToDAG.cpp - A dag to dag inst selector for AMDIL ------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //==-----------------------------------------------------------------------===// 9 // 10 /// \file 11 /// \brief Defines an instruction selector for the AMDGPU target. 12 // 13 //===----------------------------------------------------------------------===// 14 #include "AMDGPUInstrInfo.h" 15 #include "AMDGPUISelLowering.h" // For AMDGPUISD 16 #include "AMDGPURegisterInfo.h" 17 #include "AMDGPUSubtarget.h" 18 #include "R600InstrInfo.h" 19 #include "SIDefines.h" 20 #include "SIISelLowering.h" 21 #include "SIMachineFunctionInfo.h" 22 #include "llvm/CodeGen/FunctionLoweringInfo.h" 23 #include "llvm/CodeGen/PseudoSourceValue.h" 24 #include "llvm/CodeGen/MachineFrameInfo.h" 25 #include "llvm/CodeGen/MachineRegisterInfo.h" 26 #include "llvm/CodeGen/SelectionDAG.h" 27 #include "llvm/CodeGen/SelectionDAGISel.h" 28 #include "llvm/IR/Function.h" 29 30 using namespace llvm; 31 32 //===----------------------------------------------------------------------===// 33 // Instruction Selector Implementation 34 //===----------------------------------------------------------------------===// 35 36 namespace { 37 /// AMDGPU specific code to select AMDGPU machine instructions for 38 /// SelectionDAG operations. 39 class AMDGPUDAGToDAGISel : public SelectionDAGISel { 40 // Subtarget - Keep a pointer to the AMDGPU Subtarget around so that we can 41 // make the right decision when generating code for different targets. 42 const AMDGPUSubtarget *Subtarget; 43 public: 44 AMDGPUDAGToDAGISel(TargetMachine &TM); 45 virtual ~AMDGPUDAGToDAGISel(); 46 bool runOnMachineFunction(MachineFunction &MF) override; 47 SDNode *Select(SDNode *N) override; 48 const char *getPassName() const override; 49 void PostprocessISelDAG() override; 50 51 private: 52 bool isInlineImmediate(SDNode *N) const; 53 bool FoldOperand(SDValue &Src, SDValue &Sel, SDValue &Neg, SDValue &Abs, 54 const R600InstrInfo *TII); 55 bool FoldOperands(unsigned, const R600InstrInfo *, std::vector<SDValue> &); 56 bool FoldDotOperands(unsigned, const R600InstrInfo *, std::vector<SDValue> &); 57 58 // Complex pattern selectors 59 bool SelectADDRParam(SDValue Addr, SDValue& R1, SDValue& R2); 60 bool SelectADDR(SDValue N, SDValue &R1, SDValue &R2); 61 bool SelectADDR64(SDValue N, SDValue &R1, SDValue &R2); 62 63 static bool checkType(const Value *ptr, unsigned int addrspace); 64 static bool checkPrivateAddress(const MachineMemOperand *Op); 65 66 static bool isGlobalStore(const StoreSDNode *N); 67 static bool isFlatStore(const StoreSDNode *N); 68 static bool isPrivateStore(const StoreSDNode *N); 69 static bool isLocalStore(const StoreSDNode *N); 70 static bool isRegionStore(const StoreSDNode *N); 71 72 bool isCPLoad(const LoadSDNode *N) const; 73 bool isConstantLoad(const LoadSDNode *N, int cbID) const; 74 bool isGlobalLoad(const LoadSDNode *N) const; 75 bool isFlatLoad(const LoadSDNode *N) const; 76 bool isParamLoad(const LoadSDNode *N) const; 77 bool isPrivateLoad(const LoadSDNode *N) const; 78 bool isLocalLoad(const LoadSDNode *N) const; 79 bool isRegionLoad(const LoadSDNode *N) const; 80 81 SDNode *glueCopyToM0(SDNode *N) const; 82 83 const TargetRegisterClass *getOperandRegClass(SDNode *N, unsigned OpNo) const; 84 bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue& IntPtr); 85 bool SelectGlobalValueVariableOffset(SDValue Addr, SDValue &BaseReg, 86 SDValue& Offset); 87 bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset); 88 bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset); 89 bool isDSOffsetLegal(const SDValue &Base, unsigned Offset, 90 unsigned OffsetBits) const; 91 bool SelectDS1Addr1Offset(SDValue Ptr, SDValue &Base, SDValue &Offset) const; 92 bool SelectDS64Bit4ByteAligned(SDValue Ptr, SDValue &Base, SDValue &Offset0, 93 SDValue &Offset1) const; 94 void SelectMUBUF(SDValue Addr, SDValue &SRsrc, SDValue &VAddr, 95 SDValue &SOffset, SDValue &Offset, SDValue &Offen, 96 SDValue &Idxen, SDValue &Addr64, SDValue &GLC, SDValue &SLC, 97 SDValue &TFE) const; 98 bool SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, SDValue &VAddr, 99 SDValue &SOffset, SDValue &Offset, SDValue &GLC, 100 SDValue &SLC, SDValue &TFE) const; 101 bool SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, 102 SDValue &VAddr, SDValue &SOffset, SDValue &Offset, 103 SDValue &SLC) const; 104 bool SelectMUBUFScratch(SDValue Addr, SDValue &RSrc, SDValue &VAddr, 105 SDValue &SOffset, SDValue &ImmOffset) const; 106 bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &SOffset, 107 SDValue &Offset, SDValue &GLC, SDValue &SLC, 108 SDValue &TFE) const; 109 bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &Soffset, 110 SDValue &Offset, SDValue &GLC) const; 111 bool SelectSMRDOffset(SDValue ByteOffsetNode, SDValue &Offset, 112 bool &Imm) const; 113 bool SelectSMRD(SDValue Addr, SDValue &SBase, SDValue &Offset, 114 bool &Imm) const; 115 bool SelectSMRDImm(SDValue Addr, SDValue &SBase, SDValue &Offset) const; 116 bool SelectSMRDImm32(SDValue Addr, SDValue &SBase, SDValue &Offset) const; 117 bool SelectSMRDSgpr(SDValue Addr, SDValue &SBase, SDValue &Offset) const; 118 bool SelectSMRDBufferImm(SDValue Addr, SDValue &Offset) const; 119 bool SelectSMRDBufferImm32(SDValue Addr, SDValue &Offset) const; 120 bool SelectSMRDBufferSgpr(SDValue Addr, SDValue &Offset) const; 121 SDNode *SelectAddrSpaceCast(SDNode *N); 122 bool SelectVOP3Mods(SDValue In, SDValue &Src, SDValue &SrcMods) const; 123 bool SelectVOP3NoMods(SDValue In, SDValue &Src, SDValue &SrcMods) const; 124 bool SelectVOP3Mods0(SDValue In, SDValue &Src, SDValue &SrcMods, 125 SDValue &Clamp, SDValue &Omod) const; 126 bool SelectVOP3NoMods0(SDValue In, SDValue &Src, SDValue &SrcMods, 127 SDValue &Clamp, SDValue &Omod) const; 128 129 bool SelectVOP3Mods0Clamp(SDValue In, SDValue &Src, SDValue &SrcMods, 130 SDValue &Omod) const; 131 bool SelectVOP3Mods0Clamp0OMod(SDValue In, SDValue &Src, SDValue &SrcMods, 132 SDValue &Clamp, 133 SDValue &Omod) const; 134 135 SDNode *SelectADD_SUB_I64(SDNode *N); 136 SDNode *SelectDIV_SCALE(SDNode *N); 137 138 SDNode *getS_BFE(unsigned Opcode, SDLoc DL, SDValue Val, 139 uint32_t Offset, uint32_t Width); 140 SDNode *SelectS_BFEFromShifts(SDNode *N); 141 SDNode *SelectS_BFE(SDNode *N); 142 143 // Include the pieces autogenerated from the target description. 144 #include "AMDGPUGenDAGISel.inc" 145 }; 146 } // end anonymous namespace 147 148 /// \brief This pass converts a legalized DAG into a AMDGPU-specific 149 // DAG, ready for instruction scheduling. 150 FunctionPass *llvm::createAMDGPUISelDag(TargetMachine &TM) { 151 return new AMDGPUDAGToDAGISel(TM); 152 } 153 154 AMDGPUDAGToDAGISel::AMDGPUDAGToDAGISel(TargetMachine &TM) 155 : SelectionDAGISel(TM) {} 156 157 bool AMDGPUDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { 158 Subtarget = &static_cast<const AMDGPUSubtarget &>(MF.getSubtarget()); 159 return SelectionDAGISel::runOnMachineFunction(MF); 160 } 161 162 AMDGPUDAGToDAGISel::~AMDGPUDAGToDAGISel() { 163 } 164 165 bool AMDGPUDAGToDAGISel::isInlineImmediate(SDNode *N) const { 166 const SITargetLowering *TL 167 = static_cast<const SITargetLowering *>(getTargetLowering()); 168 return TL->analyzeImmediate(N) == 0; 169 } 170 171 /// \brief Determine the register class for \p OpNo 172 /// \returns The register class of the virtual register that will be used for 173 /// the given operand number \OpNo or NULL if the register class cannot be 174 /// determined. 175 const TargetRegisterClass *AMDGPUDAGToDAGISel::getOperandRegClass(SDNode *N, 176 unsigned OpNo) const { 177 if (!N->isMachineOpcode()) 178 return nullptr; 179 180 switch (N->getMachineOpcode()) { 181 default: { 182 const MCInstrDesc &Desc = 183 Subtarget->getInstrInfo()->get(N->getMachineOpcode()); 184 unsigned OpIdx = Desc.getNumDefs() + OpNo; 185 if (OpIdx >= Desc.getNumOperands()) 186 return nullptr; 187 int RegClass = Desc.OpInfo[OpIdx].RegClass; 188 if (RegClass == -1) 189 return nullptr; 190 191 return Subtarget->getRegisterInfo()->getRegClass(RegClass); 192 } 193 case AMDGPU::REG_SEQUENCE: { 194 unsigned RCID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 195 const TargetRegisterClass *SuperRC = 196 Subtarget->getRegisterInfo()->getRegClass(RCID); 197 198 SDValue SubRegOp = N->getOperand(OpNo + 1); 199 unsigned SubRegIdx = cast<ConstantSDNode>(SubRegOp)->getZExtValue(); 200 return Subtarget->getRegisterInfo()->getSubClassWithSubReg(SuperRC, 201 SubRegIdx); 202 } 203 } 204 } 205 206 bool AMDGPUDAGToDAGISel::SelectADDRParam( 207 SDValue Addr, SDValue& R1, SDValue& R2) { 208 209 if (Addr.getOpcode() == ISD::FrameIndex) { 210 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 211 R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 212 R2 = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 213 } else { 214 R1 = Addr; 215 R2 = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 216 } 217 } else if (Addr.getOpcode() == ISD::ADD) { 218 R1 = Addr.getOperand(0); 219 R2 = Addr.getOperand(1); 220 } else { 221 R1 = Addr; 222 R2 = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 223 } 224 return true; 225 } 226 227 bool AMDGPUDAGToDAGISel::SelectADDR(SDValue Addr, SDValue& R1, SDValue& R2) { 228 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 229 Addr.getOpcode() == ISD::TargetGlobalAddress) { 230 return false; 231 } 232 return SelectADDRParam(Addr, R1, R2); 233 } 234 235 236 bool AMDGPUDAGToDAGISel::SelectADDR64(SDValue Addr, SDValue& R1, SDValue& R2) { 237 if (Addr.getOpcode() == ISD::TargetExternalSymbol || 238 Addr.getOpcode() == ISD::TargetGlobalAddress) { 239 return false; 240 } 241 242 if (Addr.getOpcode() == ISD::FrameIndex) { 243 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 244 R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64); 245 R2 = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i64); 246 } else { 247 R1 = Addr; 248 R2 = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i64); 249 } 250 } else if (Addr.getOpcode() == ISD::ADD) { 251 R1 = Addr.getOperand(0); 252 R2 = Addr.getOperand(1); 253 } else { 254 R1 = Addr; 255 R2 = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i64); 256 } 257 return true; 258 } 259 260 SDNode *AMDGPUDAGToDAGISel::glueCopyToM0(SDNode *N) const { 261 if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS || 262 !checkType(cast<MemSDNode>(N)->getMemOperand()->getValue(), 263 AMDGPUAS::LOCAL_ADDRESS)) 264 return N; 265 266 const SITargetLowering& Lowering = 267 *static_cast<const SITargetLowering*>(getTargetLowering()); 268 269 // Write max value to m0 before each load operation 270 271 SDValue M0 = Lowering.copyToM0(*CurDAG, CurDAG->getEntryNode(), SDLoc(N), 272 CurDAG->getTargetConstant(-1, SDLoc(N), MVT::i32)); 273 274 SDValue Glue = M0.getValue(1); 275 276 SmallVector <SDValue, 8> Ops; 277 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { 278 Ops.push_back(N->getOperand(i)); 279 } 280 Ops.push_back(Glue); 281 CurDAG->MorphNodeTo(N, N->getOpcode(), N->getVTList(), Ops); 282 283 return N; 284 } 285 286 SDNode *AMDGPUDAGToDAGISel::Select(SDNode *N) { 287 unsigned int Opc = N->getOpcode(); 288 if (N->isMachineOpcode()) { 289 N->setNodeId(-1); 290 return nullptr; // Already selected. 291 } 292 293 if (isa<AtomicSDNode>(N)) 294 N = glueCopyToM0(N); 295 296 switch (Opc) { 297 default: break; 298 // We are selecting i64 ADD here instead of custom lower it during 299 // DAG legalization, so we can fold some i64 ADDs used for address 300 // calculation into the LOAD and STORE instructions. 301 case ISD::ADD: 302 case ISD::SUB: { 303 if (N->getValueType(0) != MVT::i64 || 304 Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS) 305 break; 306 307 return SelectADD_SUB_I64(N); 308 } 309 case ISD::SCALAR_TO_VECTOR: 310 case AMDGPUISD::BUILD_VERTICAL_VECTOR: 311 case ISD::BUILD_VECTOR: { 312 unsigned RegClassID; 313 const AMDGPURegisterInfo *TRI = Subtarget->getRegisterInfo(); 314 EVT VT = N->getValueType(0); 315 unsigned NumVectorElts = VT.getVectorNumElements(); 316 EVT EltVT = VT.getVectorElementType(); 317 assert(EltVT.bitsEq(MVT::i32)); 318 if (Subtarget->getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) { 319 bool UseVReg = true; 320 for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end(); 321 U != E; ++U) { 322 if (!U->isMachineOpcode()) { 323 continue; 324 } 325 const TargetRegisterClass *RC = getOperandRegClass(*U, U.getOperandNo()); 326 if (!RC) { 327 continue; 328 } 329 if (static_cast<const SIRegisterInfo *>(TRI)->isSGPRClass(RC)) { 330 UseVReg = false; 331 } 332 } 333 switch(NumVectorElts) { 334 case 1: RegClassID = UseVReg ? AMDGPU::VGPR_32RegClassID : 335 AMDGPU::SReg_32RegClassID; 336 break; 337 case 2: RegClassID = UseVReg ? AMDGPU::VReg_64RegClassID : 338 AMDGPU::SReg_64RegClassID; 339 break; 340 case 4: RegClassID = UseVReg ? AMDGPU::VReg_128RegClassID : 341 AMDGPU::SReg_128RegClassID; 342 break; 343 case 8: RegClassID = UseVReg ? AMDGPU::VReg_256RegClassID : 344 AMDGPU::SReg_256RegClassID; 345 break; 346 case 16: RegClassID = UseVReg ? AMDGPU::VReg_512RegClassID : 347 AMDGPU::SReg_512RegClassID; 348 break; 349 default: llvm_unreachable("Do not know how to lower this BUILD_VECTOR"); 350 } 351 } else { 352 // BUILD_VECTOR was lowered into an IMPLICIT_DEF + 4 INSERT_SUBREG 353 // that adds a 128 bits reg copy when going through TwoAddressInstructions 354 // pass. We want to avoid 128 bits copies as much as possible because they 355 // can't be bundled by our scheduler. 356 switch(NumVectorElts) { 357 case 2: RegClassID = AMDGPU::R600_Reg64RegClassID; break; 358 case 4: 359 if (Opc == AMDGPUISD::BUILD_VERTICAL_VECTOR) 360 RegClassID = AMDGPU::R600_Reg128VerticalRegClassID; 361 else 362 RegClassID = AMDGPU::R600_Reg128RegClassID; 363 break; 364 default: llvm_unreachable("Do not know how to lower this BUILD_VECTOR"); 365 } 366 } 367 368 SDLoc DL(N); 369 SDValue RegClass = CurDAG->getTargetConstant(RegClassID, DL, MVT::i32); 370 371 if (NumVectorElts == 1) { 372 return CurDAG->SelectNodeTo(N, AMDGPU::COPY_TO_REGCLASS, EltVT, 373 N->getOperand(0), RegClass); 374 } 375 376 assert(NumVectorElts <= 16 && "Vectors with more than 16 elements not " 377 "supported yet"); 378 // 16 = Max Num Vector Elements 379 // 2 = 2 REG_SEQUENCE operands per element (value, subreg index) 380 // 1 = Vector Register Class 381 SmallVector<SDValue, 16 * 2 + 1> RegSeqArgs(NumVectorElts * 2 + 1); 382 383 RegSeqArgs[0] = CurDAG->getTargetConstant(RegClassID, DL, MVT::i32); 384 bool IsRegSeq = true; 385 unsigned NOps = N->getNumOperands(); 386 for (unsigned i = 0; i < NOps; i++) { 387 // XXX: Why is this here? 388 if (isa<RegisterSDNode>(N->getOperand(i))) { 389 IsRegSeq = false; 390 break; 391 } 392 RegSeqArgs[1 + (2 * i)] = N->getOperand(i); 393 RegSeqArgs[1 + (2 * i) + 1] = 394 CurDAG->getTargetConstant(TRI->getSubRegFromChannel(i), DL, 395 MVT::i32); 396 } 397 398 if (NOps != NumVectorElts) { 399 // Fill in the missing undef elements if this was a scalar_to_vector. 400 assert(Opc == ISD::SCALAR_TO_VECTOR && NOps < NumVectorElts); 401 402 MachineSDNode *ImpDef = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, 403 DL, EltVT); 404 for (unsigned i = NOps; i < NumVectorElts; ++i) { 405 RegSeqArgs[1 + (2 * i)] = SDValue(ImpDef, 0); 406 RegSeqArgs[1 + (2 * i) + 1] = 407 CurDAG->getTargetConstant(TRI->getSubRegFromChannel(i), DL, MVT::i32); 408 } 409 } 410 411 if (!IsRegSeq) 412 break; 413 return CurDAG->SelectNodeTo(N, AMDGPU::REG_SEQUENCE, N->getVTList(), 414 RegSeqArgs); 415 } 416 case ISD::BUILD_PAIR: { 417 SDValue RC, SubReg0, SubReg1; 418 if (Subtarget->getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) { 419 break; 420 } 421 SDLoc DL(N); 422 if (N->getValueType(0) == MVT::i128) { 423 RC = CurDAG->getTargetConstant(AMDGPU::SReg_128RegClassID, DL, MVT::i32); 424 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0_sub1, DL, MVT::i32); 425 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub2_sub3, DL, MVT::i32); 426 } else if (N->getValueType(0) == MVT::i64) { 427 RC = CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32); 428 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32); 429 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32); 430 } else { 431 llvm_unreachable("Unhandled value type for BUILD_PAIR"); 432 } 433 const SDValue Ops[] = { RC, N->getOperand(0), SubReg0, 434 N->getOperand(1), SubReg1 }; 435 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, 436 DL, N->getValueType(0), Ops); 437 } 438 439 case ISD::Constant: 440 case ISD::ConstantFP: { 441 if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS || 442 N->getValueType(0).getSizeInBits() != 64 || isInlineImmediate(N)) 443 break; 444 445 uint64_t Imm; 446 if (ConstantFPSDNode *FP = dyn_cast<ConstantFPSDNode>(N)) 447 Imm = FP->getValueAPF().bitcastToAPInt().getZExtValue(); 448 else { 449 ConstantSDNode *C = cast<ConstantSDNode>(N); 450 Imm = C->getZExtValue(); 451 } 452 453 SDLoc DL(N); 454 SDNode *Lo = CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, 455 CurDAG->getConstant(Imm & 0xFFFFFFFF, DL, 456 MVT::i32)); 457 SDNode *Hi = CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, 458 CurDAG->getConstant(Imm >> 32, DL, MVT::i32)); 459 const SDValue Ops[] = { 460 CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32), 461 SDValue(Lo, 0), CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32), 462 SDValue(Hi, 0), CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32) 463 }; 464 465 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, 466 N->getValueType(0), Ops); 467 } 468 469 case ISD::LOAD: { 470 LoadSDNode *LD = cast<LoadSDNode>(N); 471 SDLoc SL(N); 472 EVT VT = N->getValueType(0); 473 474 if (VT != MVT::i64 || LD->getExtensionType() != ISD::NON_EXTLOAD) { 475 N = glueCopyToM0(N); 476 break; 477 } 478 479 // To simplify the TableGen patters, we replace all i64 loads with 480 // v2i32 loads. Alternatively, we could promote i64 loads to v2i32 481 // during DAG legalization, however, so places (ExpandUnalignedLoad) 482 // in the DAG legalizer assume that if i64 is legal, so doing this 483 // promotion early can cause problems. 484 485 SDValue NewLoad = CurDAG->getLoad(MVT::v2i32, SDLoc(N), LD->getChain(), 486 LD->getBasePtr(), LD->getMemOperand()); 487 SDValue BitCast = CurDAG->getNode(ISD::BITCAST, SL, 488 MVT::i64, NewLoad); 489 CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 1), NewLoad.getValue(1)); 490 CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), BitCast); 491 SDNode *Load = glueCopyToM0(NewLoad.getNode()); 492 SelectCode(Load); 493 N = BitCast.getNode(); 494 break; 495 } 496 497 case ISD::STORE: { 498 // Handle i64 stores here for the same reason mentioned above for loads. 499 StoreSDNode *ST = cast<StoreSDNode>(N); 500 SDValue Value = ST->getValue(); 501 if (Value.getValueType() == MVT::i64 && !ST->isTruncatingStore()) { 502 503 SDValue NewValue = CurDAG->getNode(ISD::BITCAST, SDLoc(N), 504 MVT::v2i32, Value); 505 SDValue NewStore = CurDAG->getStore(ST->getChain(), SDLoc(N), NewValue, 506 ST->getBasePtr(), ST->getMemOperand()); 507 508 CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 0), NewStore); 509 510 if (NewValue.getOpcode() == ISD::BITCAST) { 511 Select(NewStore.getNode()); 512 return SelectCode(NewValue.getNode()); 513 } 514 515 // getNode() may fold the bitcast if its input was another bitcast. If that 516 // happens we should only select the new store. 517 N = NewStore.getNode(); 518 } 519 520 N = glueCopyToM0(N); 521 break; 522 } 523 524 case AMDGPUISD::REGISTER_LOAD: { 525 if (Subtarget->getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 526 break; 527 SDValue Addr, Offset; 528 529 SDLoc DL(N); 530 SelectADDRIndirect(N->getOperand(1), Addr, Offset); 531 const SDValue Ops[] = { 532 Addr, 533 Offset, 534 CurDAG->getTargetConstant(0, DL, MVT::i32), 535 N->getOperand(0), 536 }; 537 return CurDAG->getMachineNode(AMDGPU::SI_RegisterLoad, DL, 538 CurDAG->getVTList(MVT::i32, MVT::i64, 539 MVT::Other), 540 Ops); 541 } 542 case AMDGPUISD::REGISTER_STORE: { 543 if (Subtarget->getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) 544 break; 545 SDValue Addr, Offset; 546 SelectADDRIndirect(N->getOperand(2), Addr, Offset); 547 SDLoc DL(N); 548 const SDValue Ops[] = { 549 N->getOperand(1), 550 Addr, 551 Offset, 552 CurDAG->getTargetConstant(0, DL, MVT::i32), 553 N->getOperand(0), 554 }; 555 return CurDAG->getMachineNode(AMDGPU::SI_RegisterStorePseudo, DL, 556 CurDAG->getVTList(MVT::Other), 557 Ops); 558 } 559 560 case AMDGPUISD::BFE_I32: 561 case AMDGPUISD::BFE_U32: { 562 if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS) 563 break; 564 565 // There is a scalar version available, but unlike the vector version which 566 // has a separate operand for the offset and width, the scalar version packs 567 // the width and offset into a single operand. Try to move to the scalar 568 // version if the offsets are constant, so that we can try to keep extended 569 // loads of kernel arguments in SGPRs. 570 571 // TODO: Technically we could try to pattern match scalar bitshifts of 572 // dynamic values, but it's probably not useful. 573 ConstantSDNode *Offset = dyn_cast<ConstantSDNode>(N->getOperand(1)); 574 if (!Offset) 575 break; 576 577 ConstantSDNode *Width = dyn_cast<ConstantSDNode>(N->getOperand(2)); 578 if (!Width) 579 break; 580 581 bool Signed = Opc == AMDGPUISD::BFE_I32; 582 583 uint32_t OffsetVal = Offset->getZExtValue(); 584 uint32_t WidthVal = Width->getZExtValue(); 585 586 return getS_BFE(Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32, SDLoc(N), 587 N->getOperand(0), OffsetVal, WidthVal); 588 589 } 590 case AMDGPUISD::DIV_SCALE: { 591 return SelectDIV_SCALE(N); 592 } 593 case ISD::CopyToReg: { 594 const SITargetLowering& Lowering = 595 *static_cast<const SITargetLowering*>(getTargetLowering()); 596 Lowering.legalizeTargetIndependentNode(N, *CurDAG); 597 break; 598 } 599 case ISD::ADDRSPACECAST: 600 return SelectAddrSpaceCast(N); 601 case ISD::AND: 602 case ISD::SRL: 603 case ISD::SRA: 604 if (N->getValueType(0) != MVT::i32 || 605 Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS) 606 break; 607 608 return SelectS_BFE(N); 609 } 610 611 return SelectCode(N); 612 } 613 614 615 bool AMDGPUDAGToDAGISel::checkType(const Value *Ptr, unsigned AS) { 616 assert(AS != 0 && "Use checkPrivateAddress instead."); 617 if (!Ptr) 618 return false; 619 620 return Ptr->getType()->getPointerAddressSpace() == AS; 621 } 622 623 bool AMDGPUDAGToDAGISel::checkPrivateAddress(const MachineMemOperand *Op) { 624 if (Op->getPseudoValue()) 625 return true; 626 627 if (PointerType *PT = dyn_cast<PointerType>(Op->getValue()->getType())) 628 return PT->getAddressSpace() == AMDGPUAS::PRIVATE_ADDRESS; 629 630 return false; 631 } 632 633 bool AMDGPUDAGToDAGISel::isGlobalStore(const StoreSDNode *N) { 634 return checkType(N->getMemOperand()->getValue(), AMDGPUAS::GLOBAL_ADDRESS); 635 } 636 637 bool AMDGPUDAGToDAGISel::isPrivateStore(const StoreSDNode *N) { 638 const Value *MemVal = N->getMemOperand()->getValue(); 639 return (!checkType(MemVal, AMDGPUAS::LOCAL_ADDRESS) && 640 !checkType(MemVal, AMDGPUAS::GLOBAL_ADDRESS) && 641 !checkType(MemVal, AMDGPUAS::REGION_ADDRESS)); 642 } 643 644 bool AMDGPUDAGToDAGISel::isLocalStore(const StoreSDNode *N) { 645 return checkType(N->getMemOperand()->getValue(), AMDGPUAS::LOCAL_ADDRESS); 646 } 647 648 bool AMDGPUDAGToDAGISel::isFlatStore(const StoreSDNode *N) { 649 return checkType(N->getMemOperand()->getValue(), AMDGPUAS::FLAT_ADDRESS); 650 } 651 652 bool AMDGPUDAGToDAGISel::isRegionStore(const StoreSDNode *N) { 653 return checkType(N->getMemOperand()->getValue(), AMDGPUAS::REGION_ADDRESS); 654 } 655 656 bool AMDGPUDAGToDAGISel::isConstantLoad(const LoadSDNode *N, int CbId) const { 657 const Value *MemVal = N->getMemOperand()->getValue(); 658 if (CbId == -1) 659 return checkType(MemVal, AMDGPUAS::CONSTANT_ADDRESS); 660 661 return checkType(MemVal, AMDGPUAS::CONSTANT_BUFFER_0 + CbId); 662 } 663 664 bool AMDGPUDAGToDAGISel::isGlobalLoad(const LoadSDNode *N) const { 665 if (N->getAddressSpace() == AMDGPUAS::CONSTANT_ADDRESS) 666 if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS || 667 N->getMemoryVT().bitsLT(MVT::i32)) 668 return true; 669 670 return checkType(N->getMemOperand()->getValue(), AMDGPUAS::GLOBAL_ADDRESS); 671 } 672 673 bool AMDGPUDAGToDAGISel::isParamLoad(const LoadSDNode *N) const { 674 return checkType(N->getMemOperand()->getValue(), AMDGPUAS::PARAM_I_ADDRESS); 675 } 676 677 bool AMDGPUDAGToDAGISel::isLocalLoad(const LoadSDNode *N) const { 678 return checkType(N->getMemOperand()->getValue(), AMDGPUAS::LOCAL_ADDRESS); 679 } 680 681 bool AMDGPUDAGToDAGISel::isFlatLoad(const LoadSDNode *N) const { 682 return checkType(N->getMemOperand()->getValue(), AMDGPUAS::FLAT_ADDRESS); 683 } 684 685 bool AMDGPUDAGToDAGISel::isRegionLoad(const LoadSDNode *N) const { 686 return checkType(N->getMemOperand()->getValue(), AMDGPUAS::REGION_ADDRESS); 687 } 688 689 bool AMDGPUDAGToDAGISel::isCPLoad(const LoadSDNode *N) const { 690 MachineMemOperand *MMO = N->getMemOperand(); 691 if (checkPrivateAddress(N->getMemOperand())) { 692 if (MMO) { 693 const PseudoSourceValue *PSV = MMO->getPseudoValue(); 694 if (PSV && PSV->isConstantPool()) { 695 return true; 696 } 697 } 698 } 699 return false; 700 } 701 702 bool AMDGPUDAGToDAGISel::isPrivateLoad(const LoadSDNode *N) const { 703 if (checkPrivateAddress(N->getMemOperand())) { 704 // Check to make sure we are not a constant pool load or a constant load 705 // that is marked as a private load 706 if (isCPLoad(N) || isConstantLoad(N, -1)) { 707 return false; 708 } 709 } 710 711 const Value *MemVal = N->getMemOperand()->getValue(); 712 if (!checkType(MemVal, AMDGPUAS::LOCAL_ADDRESS) && 713 !checkType(MemVal, AMDGPUAS::GLOBAL_ADDRESS) && 714 !checkType(MemVal, AMDGPUAS::FLAT_ADDRESS) && 715 !checkType(MemVal, AMDGPUAS::REGION_ADDRESS) && 716 !checkType(MemVal, AMDGPUAS::CONSTANT_ADDRESS) && 717 !checkType(MemVal, AMDGPUAS::PARAM_D_ADDRESS) && 718 !checkType(MemVal, AMDGPUAS::PARAM_I_ADDRESS)) { 719 return true; 720 } 721 return false; 722 } 723 724 const char *AMDGPUDAGToDAGISel::getPassName() const { 725 return "AMDGPU DAG->DAG Pattern Instruction Selection"; 726 } 727 728 #ifdef DEBUGTMP 729 #undef INT64_C 730 #endif 731 #undef DEBUGTMP 732 733 //===----------------------------------------------------------------------===// 734 // Complex Patterns 735 //===----------------------------------------------------------------------===// 736 737 bool AMDGPUDAGToDAGISel::SelectGlobalValueConstantOffset(SDValue Addr, 738 SDValue& IntPtr) { 739 if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Addr)) { 740 IntPtr = CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4, SDLoc(Addr), 741 true); 742 return true; 743 } 744 return false; 745 } 746 747 bool AMDGPUDAGToDAGISel::SelectGlobalValueVariableOffset(SDValue Addr, 748 SDValue& BaseReg, SDValue &Offset) { 749 if (!isa<ConstantSDNode>(Addr)) { 750 BaseReg = Addr; 751 Offset = CurDAG->getIntPtrConstant(0, SDLoc(Addr), true); 752 return true; 753 } 754 return false; 755 } 756 757 bool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, 758 SDValue &Offset) { 759 ConstantSDNode *IMMOffset; 760 761 if (Addr.getOpcode() == ISD::ADD 762 && (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 763 && isInt<16>(IMMOffset->getZExtValue())) { 764 765 Base = Addr.getOperand(0); 766 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), SDLoc(Addr), 767 MVT::i32); 768 return true; 769 // If the pointer address is constant, we can move it to the offset field. 770 } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr)) 771 && isInt<16>(IMMOffset->getZExtValue())) { 772 Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), 773 SDLoc(CurDAG->getEntryNode()), 774 AMDGPU::ZERO, MVT::i32); 775 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), SDLoc(Addr), 776 MVT::i32); 777 return true; 778 } 779 780 // Default case, no offset 781 Base = Addr; 782 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 783 return true; 784 } 785 786 bool AMDGPUDAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base, 787 SDValue &Offset) { 788 ConstantSDNode *C; 789 SDLoc DL(Addr); 790 791 if ((C = dyn_cast<ConstantSDNode>(Addr))) { 792 Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32); 793 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32); 794 } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) && 795 (C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) { 796 Base = Addr.getOperand(0); 797 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32); 798 } else { 799 Base = Addr; 800 Offset = CurDAG->getTargetConstant(0, DL, MVT::i32); 801 } 802 803 return true; 804 } 805 806 SDNode *AMDGPUDAGToDAGISel::SelectADD_SUB_I64(SDNode *N) { 807 SDLoc DL(N); 808 SDValue LHS = N->getOperand(0); 809 SDValue RHS = N->getOperand(1); 810 811 bool IsAdd = (N->getOpcode() == ISD::ADD); 812 813 SDValue Sub0 = CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32); 814 SDValue Sub1 = CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32); 815 816 SDNode *Lo0 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 817 DL, MVT::i32, LHS, Sub0); 818 SDNode *Hi0 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 819 DL, MVT::i32, LHS, Sub1); 820 821 SDNode *Lo1 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 822 DL, MVT::i32, RHS, Sub0); 823 SDNode *Hi1 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 824 DL, MVT::i32, RHS, Sub1); 825 826 SDVTList VTList = CurDAG->getVTList(MVT::i32, MVT::Glue); 827 SDValue AddLoArgs[] = { SDValue(Lo0, 0), SDValue(Lo1, 0) }; 828 829 830 unsigned Opc = IsAdd ? AMDGPU::S_ADD_U32 : AMDGPU::S_SUB_U32; 831 unsigned CarryOpc = IsAdd ? AMDGPU::S_ADDC_U32 : AMDGPU::S_SUBB_U32; 832 833 SDNode *AddLo = CurDAG->getMachineNode( Opc, DL, VTList, AddLoArgs); 834 SDValue Carry(AddLo, 1); 835 SDNode *AddHi 836 = CurDAG->getMachineNode(CarryOpc, DL, MVT::i32, 837 SDValue(Hi0, 0), SDValue(Hi1, 0), Carry); 838 839 SDValue Args[5] = { 840 CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32), 841 SDValue(AddLo,0), 842 Sub0, 843 SDValue(AddHi,0), 844 Sub1, 845 }; 846 return CurDAG->SelectNodeTo(N, AMDGPU::REG_SEQUENCE, MVT::i64, Args); 847 } 848 849 // We need to handle this here because tablegen doesn't support matching 850 // instructions with multiple outputs. 851 SDNode *AMDGPUDAGToDAGISel::SelectDIV_SCALE(SDNode *N) { 852 SDLoc SL(N); 853 EVT VT = N->getValueType(0); 854 855 assert(VT == MVT::f32 || VT == MVT::f64); 856 857 unsigned Opc 858 = (VT == MVT::f64) ? AMDGPU::V_DIV_SCALE_F64 : AMDGPU::V_DIV_SCALE_F32; 859 860 // src0_modifiers, src0, src1_modifiers, src1, src2_modifiers, src2, clamp, omod 861 SDValue Ops[8]; 862 863 SelectVOP3Mods0(N->getOperand(0), Ops[1], Ops[0], Ops[6], Ops[7]); 864 SelectVOP3Mods(N->getOperand(1), Ops[3], Ops[2]); 865 SelectVOP3Mods(N->getOperand(2), Ops[5], Ops[4]); 866 return CurDAG->SelectNodeTo(N, Opc, VT, MVT::i1, Ops); 867 } 868 869 bool AMDGPUDAGToDAGISel::isDSOffsetLegal(const SDValue &Base, unsigned Offset, 870 unsigned OffsetBits) const { 871 if ((OffsetBits == 16 && !isUInt<16>(Offset)) || 872 (OffsetBits == 8 && !isUInt<8>(Offset))) 873 return false; 874 875 if (Subtarget->getGeneration() >= AMDGPUSubtarget::SEA_ISLANDS || 876 Subtarget->unsafeDSOffsetFoldingEnabled()) 877 return true; 878 879 // On Southern Islands instruction with a negative base value and an offset 880 // don't seem to work. 881 return CurDAG->SignBitIsZero(Base); 882 } 883 884 bool AMDGPUDAGToDAGISel::SelectDS1Addr1Offset(SDValue Addr, SDValue &Base, 885 SDValue &Offset) const { 886 if (CurDAG->isBaseWithConstantOffset(Addr)) { 887 SDValue N0 = Addr.getOperand(0); 888 SDValue N1 = Addr.getOperand(1); 889 ConstantSDNode *C1 = cast<ConstantSDNode>(N1); 890 if (isDSOffsetLegal(N0, C1->getSExtValue(), 16)) { 891 // (add n0, c0) 892 Base = N0; 893 Offset = N1; 894 return true; 895 } 896 } 897 898 SDLoc DL(Addr); 899 900 // If we have a constant address, prefer to put the constant into the 901 // offset. This can save moves to load the constant address since multiple 902 // operations can share the zero base address register, and enables merging 903 // into read2 / write2 instructions. 904 if (const ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) { 905 if (isUInt<16>(CAddr->getZExtValue())) { 906 SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32); 907 MachineSDNode *MovZero = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32, 908 DL, MVT::i32, Zero); 909 Base = SDValue(MovZero, 0); 910 Offset = Addr; 911 return true; 912 } 913 } 914 915 // default case 916 Base = Addr; 917 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16); 918 return true; 919 } 920 921 bool AMDGPUDAGToDAGISel::SelectDS64Bit4ByteAligned(SDValue Addr, SDValue &Base, 922 SDValue &Offset0, 923 SDValue &Offset1) const { 924 SDLoc DL(Addr); 925 926 if (CurDAG->isBaseWithConstantOffset(Addr)) { 927 SDValue N0 = Addr.getOperand(0); 928 SDValue N1 = Addr.getOperand(1); 929 ConstantSDNode *C1 = cast<ConstantSDNode>(N1); 930 unsigned DWordOffset0 = C1->getZExtValue() / 4; 931 unsigned DWordOffset1 = DWordOffset0 + 1; 932 // (add n0, c0) 933 if (isDSOffsetLegal(N0, DWordOffset1, 8)) { 934 Base = N0; 935 Offset0 = CurDAG->getTargetConstant(DWordOffset0, DL, MVT::i8); 936 Offset1 = CurDAG->getTargetConstant(DWordOffset1, DL, MVT::i8); 937 return true; 938 } 939 } 940 941 if (const ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) { 942 unsigned DWordOffset0 = CAddr->getZExtValue() / 4; 943 unsigned DWordOffset1 = DWordOffset0 + 1; 944 assert(4 * DWordOffset0 == CAddr->getZExtValue()); 945 946 if (isUInt<8>(DWordOffset0) && isUInt<8>(DWordOffset1)) { 947 SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32); 948 MachineSDNode *MovZero 949 = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32, 950 DL, MVT::i32, Zero); 951 Base = SDValue(MovZero, 0); 952 Offset0 = CurDAG->getTargetConstant(DWordOffset0, DL, MVT::i8); 953 Offset1 = CurDAG->getTargetConstant(DWordOffset1, DL, MVT::i8); 954 return true; 955 } 956 } 957 958 // default case 959 Base = Addr; 960 Offset0 = CurDAG->getTargetConstant(0, DL, MVT::i8); 961 Offset1 = CurDAG->getTargetConstant(1, DL, MVT::i8); 962 return true; 963 } 964 965 static bool isLegalMUBUFImmOffset(const ConstantSDNode *Imm) { 966 return isUInt<12>(Imm->getZExtValue()); 967 } 968 969 void AMDGPUDAGToDAGISel::SelectMUBUF(SDValue Addr, SDValue &Ptr, 970 SDValue &VAddr, SDValue &SOffset, 971 SDValue &Offset, SDValue &Offen, 972 SDValue &Idxen, SDValue &Addr64, 973 SDValue &GLC, SDValue &SLC, 974 SDValue &TFE) const { 975 SDLoc DL(Addr); 976 977 GLC = CurDAG->getTargetConstant(0, DL, MVT::i1); 978 SLC = CurDAG->getTargetConstant(0, DL, MVT::i1); 979 TFE = CurDAG->getTargetConstant(0, DL, MVT::i1); 980 981 Idxen = CurDAG->getTargetConstant(0, DL, MVT::i1); 982 Offen = CurDAG->getTargetConstant(0, DL, MVT::i1); 983 Addr64 = CurDAG->getTargetConstant(0, DL, MVT::i1); 984 SOffset = CurDAG->getTargetConstant(0, DL, MVT::i32); 985 986 if (CurDAG->isBaseWithConstantOffset(Addr)) { 987 SDValue N0 = Addr.getOperand(0); 988 SDValue N1 = Addr.getOperand(1); 989 ConstantSDNode *C1 = cast<ConstantSDNode>(N1); 990 991 if (N0.getOpcode() == ISD::ADD) { 992 // (add (add N2, N3), C1) -> addr64 993 SDValue N2 = N0.getOperand(0); 994 SDValue N3 = N0.getOperand(1); 995 Addr64 = CurDAG->getTargetConstant(1, DL, MVT::i1); 996 Ptr = N2; 997 VAddr = N3; 998 } else { 999 1000 // (add N0, C1) -> offset 1001 VAddr = CurDAG->getTargetConstant(0, DL, MVT::i32); 1002 Ptr = N0; 1003 } 1004 1005 if (isLegalMUBUFImmOffset(C1)) { 1006 Offset = CurDAG->getTargetConstant(C1->getZExtValue(), DL, MVT::i16); 1007 return; 1008 } else if (isUInt<32>(C1->getZExtValue())) { 1009 // Illegal offset, store it in soffset. 1010 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16); 1011 SOffset = SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, 1012 CurDAG->getTargetConstant(C1->getZExtValue(), DL, MVT::i32)), 1013 0); 1014 return; 1015 } 1016 } 1017 1018 if (Addr.getOpcode() == ISD::ADD) { 1019 // (add N0, N1) -> addr64 1020 SDValue N0 = Addr.getOperand(0); 1021 SDValue N1 = Addr.getOperand(1); 1022 Addr64 = CurDAG->getTargetConstant(1, DL, MVT::i1); 1023 Ptr = N0; 1024 VAddr = N1; 1025 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16); 1026 return; 1027 } 1028 1029 // default case -> offset 1030 VAddr = CurDAG->getTargetConstant(0, DL, MVT::i32); 1031 Ptr = Addr; 1032 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16); 1033 1034 } 1035 1036 bool AMDGPUDAGToDAGISel::SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, 1037 SDValue &VAddr, SDValue &SOffset, 1038 SDValue &Offset, SDValue &GLC, 1039 SDValue &SLC, SDValue &TFE) const { 1040 SDValue Ptr, Offen, Idxen, Addr64; 1041 1042 // addr64 bit was removed for volcanic islands. 1043 if (Subtarget->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS) 1044 return false; 1045 1046 SelectMUBUF(Addr, Ptr, VAddr, SOffset, Offset, Offen, Idxen, Addr64, 1047 GLC, SLC, TFE); 1048 1049 ConstantSDNode *C = cast<ConstantSDNode>(Addr64); 1050 if (C->getSExtValue()) { 1051 SDLoc DL(Addr); 1052 1053 const SITargetLowering& Lowering = 1054 *static_cast<const SITargetLowering*>(getTargetLowering()); 1055 1056 SRsrc = SDValue(Lowering.wrapAddr64Rsrc(*CurDAG, DL, Ptr), 0); 1057 return true; 1058 } 1059 1060 return false; 1061 } 1062 1063 bool AMDGPUDAGToDAGISel::SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, 1064 SDValue &VAddr, SDValue &SOffset, 1065 SDValue &Offset, 1066 SDValue &SLC) const { 1067 SLC = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i1); 1068 SDValue GLC, TFE; 1069 1070 return SelectMUBUFAddr64(Addr, SRsrc, VAddr, SOffset, Offset, GLC, SLC, TFE); 1071 } 1072 1073 bool AMDGPUDAGToDAGISel::SelectMUBUFScratch(SDValue Addr, SDValue &Rsrc, 1074 SDValue &VAddr, SDValue &SOffset, 1075 SDValue &ImmOffset) const { 1076 1077 SDLoc DL(Addr); 1078 MachineFunction &MF = CurDAG->getMachineFunction(); 1079 const SIRegisterInfo *TRI = 1080 static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo()); 1081 MachineRegisterInfo &MRI = MF.getRegInfo(); 1082 const SITargetLowering& Lowering = 1083 *static_cast<const SITargetLowering*>(getTargetLowering()); 1084 1085 unsigned ScratchOffsetReg = 1086 TRI->getPreloadedValue(MF, SIRegisterInfo::SCRATCH_WAVE_OFFSET); 1087 Lowering.CreateLiveInRegister(*CurDAG, &AMDGPU::SReg_32RegClass, 1088 ScratchOffsetReg, MVT::i32); 1089 SDValue Sym0 = CurDAG->getExternalSymbol("SCRATCH_RSRC_DWORD0", MVT::i32); 1090 SDValue ScratchRsrcDword0 = 1091 SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, Sym0), 0); 1092 1093 SDValue Sym1 = CurDAG->getExternalSymbol("SCRATCH_RSRC_DWORD1", MVT::i32); 1094 SDValue ScratchRsrcDword1 = 1095 SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, Sym1), 0); 1096 1097 const SDValue RsrcOps[] = { 1098 CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32), 1099 ScratchRsrcDword0, 1100 CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32), 1101 ScratchRsrcDword1, 1102 CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32), 1103 }; 1104 SDValue ScratchPtr = SDValue(CurDAG->getMachineNode(AMDGPU::REG_SEQUENCE, DL, 1105 MVT::v2i32, RsrcOps), 0); 1106 Rsrc = SDValue(Lowering.buildScratchRSRC(*CurDAG, DL, ScratchPtr), 0); 1107 SOffset = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, 1108 MRI.getLiveInVirtReg(ScratchOffsetReg), MVT::i32); 1109 1110 // (add n0, c1) 1111 if (CurDAG->isBaseWithConstantOffset(Addr)) { 1112 SDValue N0 = Addr.getOperand(0); 1113 SDValue N1 = Addr.getOperand(1); 1114 // Offsets in vaddr must be positive. 1115 if (CurDAG->SignBitIsZero(N0)) { 1116 ConstantSDNode *C1 = cast<ConstantSDNode>(N1); 1117 if (isLegalMUBUFImmOffset(C1)) { 1118 VAddr = N0; 1119 ImmOffset = CurDAG->getTargetConstant(C1->getZExtValue(), DL, MVT::i16); 1120 return true; 1121 } 1122 } 1123 } 1124 1125 // (node) 1126 VAddr = Addr; 1127 ImmOffset = CurDAG->getTargetConstant(0, DL, MVT::i16); 1128 return true; 1129 } 1130 1131 bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, 1132 SDValue &SOffset, SDValue &Offset, 1133 SDValue &GLC, SDValue &SLC, 1134 SDValue &TFE) const { 1135 SDValue Ptr, VAddr, Offen, Idxen, Addr64; 1136 const SIInstrInfo *TII = 1137 static_cast<const SIInstrInfo *>(Subtarget->getInstrInfo()); 1138 1139 SelectMUBUF(Addr, Ptr, VAddr, SOffset, Offset, Offen, Idxen, Addr64, 1140 GLC, SLC, TFE); 1141 1142 if (!cast<ConstantSDNode>(Offen)->getSExtValue() && 1143 !cast<ConstantSDNode>(Idxen)->getSExtValue() && 1144 !cast<ConstantSDNode>(Addr64)->getSExtValue()) { 1145 uint64_t Rsrc = TII->getDefaultRsrcDataFormat() | 1146 APInt::getAllOnesValue(32).getZExtValue(); // Size 1147 SDLoc DL(Addr); 1148 1149 const SITargetLowering& Lowering = 1150 *static_cast<const SITargetLowering*>(getTargetLowering()); 1151 1152 SRsrc = SDValue(Lowering.buildRSRC(*CurDAG, DL, Ptr, 0, Rsrc), 0); 1153 return true; 1154 } 1155 return false; 1156 } 1157 1158 bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, 1159 SDValue &Soffset, SDValue &Offset, 1160 SDValue &GLC) const { 1161 SDValue SLC, TFE; 1162 1163 return SelectMUBUFOffset(Addr, SRsrc, Soffset, Offset, GLC, SLC, TFE); 1164 } 1165 1166 /// 1167 /// \param EncodedOffset This is the immediate value that will be encoded 1168 /// directly into the instruction. On SI/CI the \p EncodedOffset 1169 /// will be in units of dwords and on VI+ it will be units of bytes. 1170 static bool isLegalSMRDImmOffset(const AMDGPUSubtarget *ST, 1171 int64_t EncodedOffset) { 1172 return ST->getGeneration() < AMDGPUSubtarget::VOLCANIC_ISLANDS ? 1173 isUInt<8>(EncodedOffset) : isUInt<20>(EncodedOffset); 1174 } 1175 1176 bool AMDGPUDAGToDAGISel::SelectSMRDOffset(SDValue ByteOffsetNode, 1177 SDValue &Offset, bool &Imm) const { 1178 1179 // FIXME: Handle non-constant offsets. 1180 ConstantSDNode *C = dyn_cast<ConstantSDNode>(ByteOffsetNode); 1181 if (!C) 1182 return false; 1183 1184 SDLoc SL(ByteOffsetNode); 1185 AMDGPUSubtarget::Generation Gen = Subtarget->getGeneration(); 1186 int64_t ByteOffset = C->getSExtValue(); 1187 int64_t EncodedOffset = Gen < AMDGPUSubtarget::VOLCANIC_ISLANDS ? 1188 ByteOffset >> 2 : ByteOffset; 1189 1190 if (isLegalSMRDImmOffset(Subtarget, EncodedOffset)) { 1191 Offset = CurDAG->getTargetConstant(EncodedOffset, SL, MVT::i32); 1192 Imm = true; 1193 return true; 1194 } 1195 1196 if (!isUInt<32>(EncodedOffset) || !isUInt<32>(ByteOffset)) 1197 return false; 1198 1199 if (Gen == AMDGPUSubtarget::SEA_ISLANDS && isUInt<32>(EncodedOffset)) { 1200 // 32-bit Immediates are supported on Sea Islands. 1201 Offset = CurDAG->getTargetConstant(EncodedOffset, SL, MVT::i32); 1202 } else { 1203 SDValue C32Bit = CurDAG->getTargetConstant(ByteOffset, SL, MVT::i32); 1204 Offset = SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, SL, MVT::i32, 1205 C32Bit), 0); 1206 } 1207 Imm = false; 1208 return true; 1209 } 1210 1211 bool AMDGPUDAGToDAGISel::SelectSMRD(SDValue Addr, SDValue &SBase, 1212 SDValue &Offset, bool &Imm) const { 1213 1214 SDLoc SL(Addr); 1215 if (CurDAG->isBaseWithConstantOffset(Addr)) { 1216 SDValue N0 = Addr.getOperand(0); 1217 SDValue N1 = Addr.getOperand(1); 1218 1219 if (SelectSMRDOffset(N1, Offset, Imm)) { 1220 SBase = N0; 1221 return true; 1222 } 1223 } 1224 SBase = Addr; 1225 Offset = CurDAG->getTargetConstant(0, SL, MVT::i32); 1226 Imm = true; 1227 return true; 1228 } 1229 1230 bool AMDGPUDAGToDAGISel::SelectSMRDImm(SDValue Addr, SDValue &SBase, 1231 SDValue &Offset) const { 1232 bool Imm; 1233 return SelectSMRD(Addr, SBase, Offset, Imm) && Imm; 1234 } 1235 1236 bool AMDGPUDAGToDAGISel::SelectSMRDImm32(SDValue Addr, SDValue &SBase, 1237 SDValue &Offset) const { 1238 1239 if (Subtarget->getGeneration() != AMDGPUSubtarget::SEA_ISLANDS) 1240 return false; 1241 1242 bool Imm; 1243 if (!SelectSMRD(Addr, SBase, Offset, Imm)) 1244 return false; 1245 1246 return !Imm && isa<ConstantSDNode>(Offset); 1247 } 1248 1249 bool AMDGPUDAGToDAGISel::SelectSMRDSgpr(SDValue Addr, SDValue &SBase, 1250 SDValue &Offset) const { 1251 bool Imm; 1252 return SelectSMRD(Addr, SBase, Offset, Imm) && !Imm && 1253 !isa<ConstantSDNode>(Offset); 1254 } 1255 1256 bool AMDGPUDAGToDAGISel::SelectSMRDBufferImm(SDValue Addr, 1257 SDValue &Offset) const { 1258 bool Imm; 1259 return SelectSMRDOffset(Addr, Offset, Imm) && Imm; 1260 } 1261 1262 bool AMDGPUDAGToDAGISel::SelectSMRDBufferImm32(SDValue Addr, 1263 SDValue &Offset) const { 1264 if (Subtarget->getGeneration() != AMDGPUSubtarget::SEA_ISLANDS) 1265 return false; 1266 1267 bool Imm; 1268 if (!SelectSMRDOffset(Addr, Offset, Imm)) 1269 return false; 1270 1271 return !Imm && isa<ConstantSDNode>(Offset); 1272 } 1273 1274 bool AMDGPUDAGToDAGISel::SelectSMRDBufferSgpr(SDValue Addr, 1275 SDValue &Offset) const { 1276 bool Imm; 1277 return SelectSMRDOffset(Addr, Offset, Imm) && !Imm && 1278 !isa<ConstantSDNode>(Offset); 1279 } 1280 1281 // FIXME: This is incorrect and only enough to be able to compile. 1282 SDNode *AMDGPUDAGToDAGISel::SelectAddrSpaceCast(SDNode *N) { 1283 AddrSpaceCastSDNode *ASC = cast<AddrSpaceCastSDNode>(N); 1284 SDLoc DL(N); 1285 1286 assert(Subtarget->hasFlatAddressSpace() && 1287 "addrspacecast only supported with flat address space!"); 1288 1289 assert((ASC->getSrcAddressSpace() != AMDGPUAS::CONSTANT_ADDRESS && 1290 ASC->getDestAddressSpace() != AMDGPUAS::CONSTANT_ADDRESS) && 1291 "Cannot cast address space to / from constant address!"); 1292 1293 assert((ASC->getSrcAddressSpace() == AMDGPUAS::FLAT_ADDRESS || 1294 ASC->getDestAddressSpace() == AMDGPUAS::FLAT_ADDRESS) && 1295 "Can only cast to / from flat address space!"); 1296 1297 // The flat instructions read the address as the index of the VGPR holding the 1298 // address, so casting should just be reinterpreting the base VGPR, so just 1299 // insert trunc / bitcast / zext. 1300 1301 SDValue Src = ASC->getOperand(0); 1302 EVT DestVT = ASC->getValueType(0); 1303 EVT SrcVT = Src.getValueType(); 1304 1305 unsigned SrcSize = SrcVT.getSizeInBits(); 1306 unsigned DestSize = DestVT.getSizeInBits(); 1307 1308 if (SrcSize > DestSize) { 1309 assert(SrcSize == 64 && DestSize == 32); 1310 return CurDAG->getMachineNode( 1311 TargetOpcode::EXTRACT_SUBREG, 1312 DL, 1313 DestVT, 1314 Src, 1315 CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32)); 1316 } 1317 1318 1319 if (DestSize > SrcSize) { 1320 assert(SrcSize == 32 && DestSize == 64); 1321 1322 // FIXME: This is probably wrong, we should never be defining 1323 // a register class with both VGPRs and SGPRs 1324 SDValue RC = CurDAG->getTargetConstant(AMDGPU::VS_64RegClassID, DL, 1325 MVT::i32); 1326 1327 const SDValue Ops[] = { 1328 RC, 1329 Src, 1330 CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32), 1331 SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, 1332 CurDAG->getConstant(0, DL, MVT::i32)), 0), 1333 CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32) 1334 }; 1335 1336 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, 1337 DL, N->getValueType(0), Ops); 1338 } 1339 1340 assert(SrcSize == 64 && DestSize == 64); 1341 return CurDAG->getNode(ISD::BITCAST, DL, DestVT, Src).getNode(); 1342 } 1343 1344 SDNode *AMDGPUDAGToDAGISel::getS_BFE(unsigned Opcode, SDLoc DL, SDValue Val, 1345 uint32_t Offset, uint32_t Width) { 1346 // Transformation function, pack the offset and width of a BFE into 1347 // the format expected by the S_BFE_I32 / S_BFE_U32. In the second 1348 // source, bits [5:0] contain the offset and bits [22:16] the width. 1349 uint32_t PackedVal = Offset | (Width << 16); 1350 SDValue PackedConst = CurDAG->getTargetConstant(PackedVal, DL, MVT::i32); 1351 1352 return CurDAG->getMachineNode(Opcode, DL, MVT::i32, Val, PackedConst); 1353 } 1354 1355 SDNode *AMDGPUDAGToDAGISel::SelectS_BFEFromShifts(SDNode *N) { 1356 // "(a << b) srl c)" ---> "BFE_U32 a, (c-b), (32-c) 1357 // "(a << b) sra c)" ---> "BFE_I32 a, (c-b), (32-c) 1358 // Predicate: 0 < b <= c < 32 1359 1360 const SDValue &Shl = N->getOperand(0); 1361 ConstantSDNode *B = dyn_cast<ConstantSDNode>(Shl->getOperand(1)); 1362 ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)); 1363 1364 if (B && C) { 1365 uint32_t BVal = B->getZExtValue(); 1366 uint32_t CVal = C->getZExtValue(); 1367 1368 if (0 < BVal && BVal <= CVal && CVal < 32) { 1369 bool Signed = N->getOpcode() == ISD::SRA; 1370 unsigned Opcode = Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32; 1371 1372 return getS_BFE(Opcode, SDLoc(N), Shl.getOperand(0), 1373 CVal - BVal, 32 - CVal); 1374 } 1375 } 1376 return SelectCode(N); 1377 } 1378 1379 SDNode *AMDGPUDAGToDAGISel::SelectS_BFE(SDNode *N) { 1380 switch (N->getOpcode()) { 1381 case ISD::AND: 1382 if (N->getOperand(0).getOpcode() == ISD::SRL) { 1383 // "(a srl b) & mask" ---> "BFE_U32 a, b, popcount(mask)" 1384 // Predicate: isMask(mask) 1385 const SDValue &Srl = N->getOperand(0); 1386 ConstantSDNode *Shift = dyn_cast<ConstantSDNode>(Srl.getOperand(1)); 1387 ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(N->getOperand(1)); 1388 1389 if (Shift && Mask) { 1390 uint32_t ShiftVal = Shift->getZExtValue(); 1391 uint32_t MaskVal = Mask->getZExtValue(); 1392 1393 if (isMask_32(MaskVal)) { 1394 uint32_t WidthVal = countPopulation(MaskVal); 1395 1396 return getS_BFE(AMDGPU::S_BFE_U32, SDLoc(N), Srl.getOperand(0), 1397 ShiftVal, WidthVal); 1398 } 1399 } 1400 } 1401 break; 1402 case ISD::SRL: 1403 if (N->getOperand(0).getOpcode() == ISD::AND) { 1404 // "(a & mask) srl b)" ---> "BFE_U32 a, b, popcount(mask >> b)" 1405 // Predicate: isMask(mask >> b) 1406 const SDValue &And = N->getOperand(0); 1407 ConstantSDNode *Shift = dyn_cast<ConstantSDNode>(N->getOperand(1)); 1408 ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(And->getOperand(1)); 1409 1410 if (Shift && Mask) { 1411 uint32_t ShiftVal = Shift->getZExtValue(); 1412 uint32_t MaskVal = Mask->getZExtValue() >> ShiftVal; 1413 1414 if (isMask_32(MaskVal)) { 1415 uint32_t WidthVal = countPopulation(MaskVal); 1416 1417 return getS_BFE(AMDGPU::S_BFE_U32, SDLoc(N), And.getOperand(0), 1418 ShiftVal, WidthVal); 1419 } 1420 } 1421 } else if (N->getOperand(0).getOpcode() == ISD::SHL) 1422 return SelectS_BFEFromShifts(N); 1423 break; 1424 case ISD::SRA: 1425 if (N->getOperand(0).getOpcode() == ISD::SHL) 1426 return SelectS_BFEFromShifts(N); 1427 break; 1428 } 1429 1430 return SelectCode(N); 1431 } 1432 1433 bool AMDGPUDAGToDAGISel::SelectVOP3Mods(SDValue In, SDValue &Src, 1434 SDValue &SrcMods) const { 1435 1436 unsigned Mods = 0; 1437 1438 Src = In; 1439 1440 if (Src.getOpcode() == ISD::FNEG) { 1441 Mods |= SISrcMods::NEG; 1442 Src = Src.getOperand(0); 1443 } 1444 1445 if (Src.getOpcode() == ISD::FABS) { 1446 Mods |= SISrcMods::ABS; 1447 Src = Src.getOperand(0); 1448 } 1449 1450 SrcMods = CurDAG->getTargetConstant(Mods, SDLoc(In), MVT::i32); 1451 1452 return true; 1453 } 1454 1455 bool AMDGPUDAGToDAGISel::SelectVOP3NoMods(SDValue In, SDValue &Src, 1456 SDValue &SrcMods) const { 1457 bool Res = SelectVOP3Mods(In, Src, SrcMods); 1458 return Res && cast<ConstantSDNode>(SrcMods)->isNullValue(); 1459 } 1460 1461 bool AMDGPUDAGToDAGISel::SelectVOP3Mods0(SDValue In, SDValue &Src, 1462 SDValue &SrcMods, SDValue &Clamp, 1463 SDValue &Omod) const { 1464 SDLoc DL(In); 1465 // FIXME: Handle Clamp and Omod 1466 Clamp = CurDAG->getTargetConstant(0, DL, MVT::i32); 1467 Omod = CurDAG->getTargetConstant(0, DL, MVT::i32); 1468 1469 return SelectVOP3Mods(In, Src, SrcMods); 1470 } 1471 1472 bool AMDGPUDAGToDAGISel::SelectVOP3NoMods0(SDValue In, SDValue &Src, 1473 SDValue &SrcMods, SDValue &Clamp, 1474 SDValue &Omod) const { 1475 bool Res = SelectVOP3Mods0(In, Src, SrcMods, Clamp, Omod); 1476 1477 return Res && cast<ConstantSDNode>(SrcMods)->isNullValue() && 1478 cast<ConstantSDNode>(Clamp)->isNullValue() && 1479 cast<ConstantSDNode>(Omod)->isNullValue(); 1480 } 1481 1482 bool AMDGPUDAGToDAGISel::SelectVOP3Mods0Clamp(SDValue In, SDValue &Src, 1483 SDValue &SrcMods, 1484 SDValue &Omod) const { 1485 // FIXME: Handle Omod 1486 Omod = CurDAG->getTargetConstant(0, SDLoc(In), MVT::i32); 1487 1488 return SelectVOP3Mods(In, Src, SrcMods); 1489 } 1490 1491 bool AMDGPUDAGToDAGISel::SelectVOP3Mods0Clamp0OMod(SDValue In, SDValue &Src, 1492 SDValue &SrcMods, 1493 SDValue &Clamp, 1494 SDValue &Omod) const { 1495 Clamp = Omod = CurDAG->getTargetConstant(0, SDLoc(In), MVT::i32); 1496 return SelectVOP3Mods(In, Src, SrcMods); 1497 } 1498 1499 void AMDGPUDAGToDAGISel::PostprocessISelDAG() { 1500 const AMDGPUTargetLowering& Lowering = 1501 *static_cast<const AMDGPUTargetLowering*>(getTargetLowering()); 1502 bool IsModified = false; 1503 do { 1504 IsModified = false; 1505 // Go over all selected nodes and try to fold them a bit more 1506 for (SDNode &Node : CurDAG->allnodes()) { 1507 MachineSDNode *MachineNode = dyn_cast<MachineSDNode>(&Node); 1508 if (!MachineNode) 1509 continue; 1510 1511 SDNode *ResNode = Lowering.PostISelFolding(MachineNode, *CurDAG); 1512 if (ResNode != &Node) { 1513 ReplaceUses(&Node, ResNode); 1514 IsModified = true; 1515 } 1516 } 1517 CurDAG->RemoveDeadNodes(); 1518 } while (IsModified); 1519 } 1520