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