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