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 "AMDGPU.h" 16 #include "AMDGPUArgumentUsageInfo.h" 17 #include "AMDGPUISelLowering.h" // For AMDGPUISD 18 #include "AMDGPUInstrInfo.h" 19 #include "AMDGPURegisterInfo.h" 20 #include "AMDGPUSubtarget.h" 21 #include "SIDefines.h" 22 #include "SIISelLowering.h" 23 #include "SIInstrInfo.h" 24 #include "SIMachineFunctionInfo.h" 25 #include "SIRegisterInfo.h" 26 #include "llvm/ADT/APInt.h" 27 #include "llvm/ADT/SmallVector.h" 28 #include "llvm/ADT/StringRef.h" 29 #include "llvm/Analysis/ValueTracking.h" 30 #include "llvm/CodeGen/FunctionLoweringInfo.h" 31 #include "llvm/CodeGen/ISDOpcodes.h" 32 #include "llvm/CodeGen/MachineFunction.h" 33 #include "llvm/CodeGen/MachineRegisterInfo.h" 34 #include "llvm/CodeGen/MachineValueType.h" 35 #include "llvm/CodeGen/SelectionDAG.h" 36 #include "llvm/CodeGen/SelectionDAGISel.h" 37 #include "llvm/CodeGen/SelectionDAGNodes.h" 38 #include "llvm/CodeGen/ValueTypes.h" 39 #include "llvm/IR/BasicBlock.h" 40 #include "llvm/IR/Instruction.h" 41 #include "llvm/MC/MCInstrDesc.h" 42 #include "llvm/Support/Casting.h" 43 #include "llvm/Support/CodeGen.h" 44 #include "llvm/Support/ErrorHandling.h" 45 #include "llvm/Support/MathExtras.h" 46 #include <cassert> 47 #include <cstdint> 48 #include <new> 49 #include <vector> 50 51 using namespace llvm; 52 53 namespace llvm { 54 55 class R600InstrInfo; 56 57 } // end namespace llvm 58 59 //===----------------------------------------------------------------------===// 60 // Instruction Selector Implementation 61 //===----------------------------------------------------------------------===// 62 63 namespace { 64 65 /// AMDGPU specific code to select AMDGPU machine instructions for 66 /// SelectionDAG operations. 67 class AMDGPUDAGToDAGISel : public SelectionDAGISel { 68 // Subtarget - Keep a pointer to the AMDGPU Subtarget around so that we can 69 // make the right decision when generating code for different targets. 70 const AMDGPUSubtarget *Subtarget; 71 AMDGPUAS AMDGPUASI; 72 73 public: 74 explicit AMDGPUDAGToDAGISel(TargetMachine *TM = nullptr, 75 CodeGenOpt::Level OptLevel = CodeGenOpt::Default) 76 : SelectionDAGISel(*TM, OptLevel) { 77 AMDGPUASI = AMDGPU::getAMDGPUAS(*TM); 78 } 79 ~AMDGPUDAGToDAGISel() override = default; 80 81 void getAnalysisUsage(AnalysisUsage &AU) const override { 82 AU.addRequired<AMDGPUArgumentUsageInfo>(); 83 SelectionDAGISel::getAnalysisUsage(AU); 84 } 85 86 bool runOnMachineFunction(MachineFunction &MF) override; 87 void Select(SDNode *N) override; 88 StringRef getPassName() const override; 89 void PostprocessISelDAG() override; 90 91 protected: 92 void SelectBuildVector(SDNode *N, unsigned RegClassID); 93 94 private: 95 std::pair<SDValue, SDValue> foldFrameIndex(SDValue N) const; 96 bool isNoNanSrc(SDValue N) const; 97 bool isInlineImmediate(const SDNode *N) const; 98 bool FoldOperand(SDValue &Src, SDValue &Sel, SDValue &Neg, SDValue &Abs, 99 const R600InstrInfo *TII); 100 bool FoldOperands(unsigned, const R600InstrInfo *, std::vector<SDValue> &); 101 bool FoldDotOperands(unsigned, const R600InstrInfo *, std::vector<SDValue> &); 102 103 bool isConstantLoad(const MemSDNode *N, int cbID) const; 104 bool isUniformBr(const SDNode *N) const; 105 106 SDNode *glueCopyToM0(SDNode *N) const; 107 108 const TargetRegisterClass *getOperandRegClass(SDNode *N, unsigned OpNo) const; 109 bool SelectGlobalValueConstantOffset(SDValue Addr, SDValue& IntPtr); 110 bool SelectGlobalValueVariableOffset(SDValue Addr, SDValue &BaseReg, 111 SDValue& Offset); 112 virtual bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, SDValue &Offset); 113 virtual bool SelectADDRIndirect(SDValue Addr, SDValue &Base, SDValue &Offset); 114 bool isDSOffsetLegal(const SDValue &Base, unsigned Offset, 115 unsigned OffsetBits) const; 116 bool SelectDS1Addr1Offset(SDValue Ptr, SDValue &Base, SDValue &Offset) const; 117 bool SelectDS64Bit4ByteAligned(SDValue Ptr, SDValue &Base, SDValue &Offset0, 118 SDValue &Offset1) const; 119 bool SelectMUBUF(SDValue Addr, SDValue &SRsrc, SDValue &VAddr, 120 SDValue &SOffset, SDValue &Offset, SDValue &Offen, 121 SDValue &Idxen, SDValue &Addr64, SDValue &GLC, SDValue &SLC, 122 SDValue &TFE) const; 123 bool SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, SDValue &VAddr, 124 SDValue &SOffset, SDValue &Offset, SDValue &GLC, 125 SDValue &SLC, SDValue &TFE) const; 126 bool SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, 127 SDValue &VAddr, SDValue &SOffset, SDValue &Offset, 128 SDValue &SLC) const; 129 bool SelectMUBUFScratchOffen(SDNode *Parent, 130 SDValue Addr, SDValue &RSrc, SDValue &VAddr, 131 SDValue &SOffset, SDValue &ImmOffset) const; 132 bool SelectMUBUFScratchOffset(SDNode *Parent, 133 SDValue Addr, SDValue &SRsrc, SDValue &Soffset, 134 SDValue &Offset) const; 135 136 bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &SOffset, 137 SDValue &Offset, SDValue &GLC, SDValue &SLC, 138 SDValue &TFE) const; 139 bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &Soffset, 140 SDValue &Offset, SDValue &SLC) const; 141 bool SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, SDValue &Soffset, 142 SDValue &Offset) const; 143 bool SelectMUBUFConstant(SDValue Constant, 144 SDValue &SOffset, 145 SDValue &ImmOffset) const; 146 bool SelectMUBUFIntrinsicOffset(SDValue Offset, SDValue &SOffset, 147 SDValue &ImmOffset) const; 148 bool SelectMUBUFIntrinsicVOffset(SDValue Offset, SDValue &SOffset, 149 SDValue &ImmOffset, SDValue &VOffset) const; 150 151 bool SelectFlatAtomic(SDValue Addr, SDValue &VAddr, 152 SDValue &Offset, SDValue &SLC) const; 153 bool SelectFlatAtomicSigned(SDValue Addr, SDValue &VAddr, 154 SDValue &Offset, SDValue &SLC) const; 155 156 template <bool IsSigned> 157 bool SelectFlatOffset(SDValue Addr, SDValue &VAddr, 158 SDValue &Offset, SDValue &SLC) const; 159 160 bool SelectSMRDOffset(SDValue ByteOffsetNode, SDValue &Offset, 161 bool &Imm) const; 162 bool SelectSMRD(SDValue Addr, SDValue &SBase, SDValue &Offset, 163 bool &Imm) const; 164 bool SelectSMRDImm(SDValue Addr, SDValue &SBase, SDValue &Offset) const; 165 bool SelectSMRDImm32(SDValue Addr, SDValue &SBase, SDValue &Offset) const; 166 bool SelectSMRDSgpr(SDValue Addr, SDValue &SBase, SDValue &Offset) const; 167 bool SelectSMRDBufferImm(SDValue Addr, SDValue &Offset) const; 168 bool SelectSMRDBufferImm32(SDValue Addr, SDValue &Offset) const; 169 bool SelectSMRDBufferSgpr(SDValue Addr, SDValue &Offset) const; 170 bool SelectMOVRELOffset(SDValue Index, SDValue &Base, SDValue &Offset) const; 171 172 bool SelectVOP3Mods_NNaN(SDValue In, SDValue &Src, SDValue &SrcMods) const; 173 bool SelectVOP3ModsImpl(SDValue In, SDValue &Src, unsigned &SrcMods) const; 174 bool SelectVOP3Mods(SDValue In, SDValue &Src, SDValue &SrcMods) const; 175 bool SelectVOP3NoMods(SDValue In, SDValue &Src) const; 176 bool SelectVOP3Mods0(SDValue In, SDValue &Src, SDValue &SrcMods, 177 SDValue &Clamp, SDValue &Omod) const; 178 bool SelectVOP3NoMods0(SDValue In, SDValue &Src, SDValue &SrcMods, 179 SDValue &Clamp, SDValue &Omod) const; 180 181 bool SelectVOP3Mods0Clamp0OMod(SDValue In, SDValue &Src, SDValue &SrcMods, 182 SDValue &Clamp, 183 SDValue &Omod) const; 184 185 bool SelectVOP3OMods(SDValue In, SDValue &Src, 186 SDValue &Clamp, SDValue &Omod) const; 187 188 bool SelectVOP3PMods(SDValue In, SDValue &Src, SDValue &SrcMods) const; 189 bool SelectVOP3PMods0(SDValue In, SDValue &Src, SDValue &SrcMods, 190 SDValue &Clamp) const; 191 192 bool SelectVOP3OpSel(SDValue In, SDValue &Src, SDValue &SrcMods) const; 193 bool SelectVOP3OpSel0(SDValue In, SDValue &Src, SDValue &SrcMods, 194 SDValue &Clamp) const; 195 196 bool SelectVOP3OpSelMods(SDValue In, SDValue &Src, SDValue &SrcMods) const; 197 bool SelectVOP3OpSelMods0(SDValue In, SDValue &Src, SDValue &SrcMods, 198 SDValue &Clamp) const; 199 bool SelectVOP3PMadMixModsImpl(SDValue In, SDValue &Src, unsigned &Mods) const; 200 bool SelectVOP3PMadMixMods(SDValue In, SDValue &Src, SDValue &SrcMods) const; 201 202 void SelectADD_SUB_I64(SDNode *N); 203 void SelectUADDO_USUBO(SDNode *N); 204 void SelectDIV_SCALE(SDNode *N); 205 void SelectFMA_W_CHAIN(SDNode *N); 206 void SelectFMUL_W_CHAIN(SDNode *N); 207 208 SDNode *getS_BFE(unsigned Opcode, const SDLoc &DL, SDValue Val, 209 uint32_t Offset, uint32_t Width); 210 void SelectS_BFEFromShifts(SDNode *N); 211 void SelectS_BFE(SDNode *N); 212 bool isCBranchSCC(const SDNode *N) const; 213 void SelectBRCOND(SDNode *N); 214 void SelectFMAD(SDNode *N); 215 void SelectATOMIC_CMP_SWAP(SDNode *N); 216 217 protected: 218 // Include the pieces autogenerated from the target description. 219 #include "AMDGPUGenDAGISel.inc" 220 }; 221 222 class R600DAGToDAGISel : public AMDGPUDAGToDAGISel { 223 public: 224 explicit R600DAGToDAGISel(TargetMachine *TM, CodeGenOpt::Level OptLevel) : 225 AMDGPUDAGToDAGISel(TM, OptLevel) {} 226 227 void Select(SDNode *N) override; 228 229 bool SelectADDRIndirect(SDValue Addr, SDValue &Base, 230 SDValue &Offset) override; 231 bool SelectADDRVTX_READ(SDValue Addr, SDValue &Base, 232 SDValue &Offset) override; 233 }; 234 235 } // end anonymous namespace 236 237 INITIALIZE_PASS_BEGIN(AMDGPUDAGToDAGISel, "isel", 238 "AMDGPU DAG->DAG Pattern Instruction Selection", false, false) 239 INITIALIZE_PASS_DEPENDENCY(AMDGPUArgumentUsageInfo) 240 INITIALIZE_PASS_END(AMDGPUDAGToDAGISel, "isel", 241 "AMDGPU DAG->DAG Pattern Instruction Selection", false, false) 242 243 /// \brief This pass converts a legalized DAG into a AMDGPU-specific 244 // DAG, ready for instruction scheduling. 245 FunctionPass *llvm::createAMDGPUISelDag(TargetMachine *TM, 246 CodeGenOpt::Level OptLevel) { 247 return new AMDGPUDAGToDAGISel(TM, OptLevel); 248 } 249 250 /// \brief This pass converts a legalized DAG into a R600-specific 251 // DAG, ready for instruction scheduling. 252 FunctionPass *llvm::createR600ISelDag(TargetMachine *TM, 253 CodeGenOpt::Level OptLevel) { 254 return new R600DAGToDAGISel(TM, OptLevel); 255 } 256 257 bool AMDGPUDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { 258 Subtarget = &MF.getSubtarget<AMDGPUSubtarget>(); 259 return SelectionDAGISel::runOnMachineFunction(MF); 260 } 261 262 bool AMDGPUDAGToDAGISel::isNoNanSrc(SDValue N) const { 263 if (TM.Options.NoNaNsFPMath) 264 return true; 265 266 // TODO: Move into isKnownNeverNaN 267 if (N->getFlags().isDefined()) 268 return N->getFlags().hasNoNaNs(); 269 270 return CurDAG->isKnownNeverNaN(N); 271 } 272 273 bool AMDGPUDAGToDAGISel::isInlineImmediate(const SDNode *N) const { 274 const SIInstrInfo *TII 275 = static_cast<const SISubtarget *>(Subtarget)->getInstrInfo(); 276 277 if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) 278 return TII->isInlineConstant(C->getAPIntValue()); 279 280 if (const ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N)) 281 return TII->isInlineConstant(C->getValueAPF().bitcastToAPInt()); 282 283 return false; 284 } 285 286 /// \brief Determine the register class for \p OpNo 287 /// \returns The register class of the virtual register that will be used for 288 /// the given operand number \OpNo or NULL if the register class cannot be 289 /// determined. 290 const TargetRegisterClass *AMDGPUDAGToDAGISel::getOperandRegClass(SDNode *N, 291 unsigned OpNo) const { 292 if (!N->isMachineOpcode()) { 293 if (N->getOpcode() == ISD::CopyToReg) { 294 unsigned Reg = cast<RegisterSDNode>(N->getOperand(1))->getReg(); 295 if (TargetRegisterInfo::isVirtualRegister(Reg)) { 296 MachineRegisterInfo &MRI = CurDAG->getMachineFunction().getRegInfo(); 297 return MRI.getRegClass(Reg); 298 } 299 300 const SIRegisterInfo *TRI 301 = static_cast<const SISubtarget *>(Subtarget)->getRegisterInfo(); 302 return TRI->getPhysRegClass(Reg); 303 } 304 305 return nullptr; 306 } 307 308 switch (N->getMachineOpcode()) { 309 default: { 310 const MCInstrDesc &Desc = 311 Subtarget->getInstrInfo()->get(N->getMachineOpcode()); 312 unsigned OpIdx = Desc.getNumDefs() + OpNo; 313 if (OpIdx >= Desc.getNumOperands()) 314 return nullptr; 315 int RegClass = Desc.OpInfo[OpIdx].RegClass; 316 if (RegClass == -1) 317 return nullptr; 318 319 return Subtarget->getRegisterInfo()->getRegClass(RegClass); 320 } 321 case AMDGPU::REG_SEQUENCE: { 322 unsigned RCID = cast<ConstantSDNode>(N->getOperand(0))->getZExtValue(); 323 const TargetRegisterClass *SuperRC = 324 Subtarget->getRegisterInfo()->getRegClass(RCID); 325 326 SDValue SubRegOp = N->getOperand(OpNo + 1); 327 unsigned SubRegIdx = cast<ConstantSDNode>(SubRegOp)->getZExtValue(); 328 return Subtarget->getRegisterInfo()->getSubClassWithSubReg(SuperRC, 329 SubRegIdx); 330 } 331 } 332 } 333 334 SDNode *AMDGPUDAGToDAGISel::glueCopyToM0(SDNode *N) const { 335 if (cast<MemSDNode>(N)->getAddressSpace() != AMDGPUASI.LOCAL_ADDRESS) 336 return N; 337 338 const SITargetLowering& Lowering = 339 *static_cast<const SITargetLowering*>(getTargetLowering()); 340 341 // Write max value to m0 before each load operation 342 343 SDValue M0 = Lowering.copyToM0(*CurDAG, CurDAG->getEntryNode(), SDLoc(N), 344 CurDAG->getTargetConstant(-1, SDLoc(N), MVT::i32)); 345 346 SDValue Glue = M0.getValue(1); 347 348 SmallVector <SDValue, 8> Ops; 349 for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { 350 Ops.push_back(N->getOperand(i)); 351 } 352 Ops.push_back(Glue); 353 CurDAG->MorphNodeTo(N, N->getOpcode(), N->getVTList(), Ops); 354 355 return N; 356 } 357 358 static unsigned selectSGPRVectorRegClassID(unsigned NumVectorElts) { 359 switch (NumVectorElts) { 360 case 1: 361 return AMDGPU::SReg_32_XM0RegClassID; 362 case 2: 363 return AMDGPU::SReg_64RegClassID; 364 case 4: 365 return AMDGPU::SReg_128RegClassID; 366 case 8: 367 return AMDGPU::SReg_256RegClassID; 368 case 16: 369 return AMDGPU::SReg_512RegClassID; 370 } 371 372 llvm_unreachable("invalid vector size"); 373 } 374 375 static bool getConstantValue(SDValue N, uint32_t &Out) { 376 if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(N)) { 377 Out = C->getAPIntValue().getZExtValue(); 378 return true; 379 } 380 381 if (const ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N)) { 382 Out = C->getValueAPF().bitcastToAPInt().getZExtValue(); 383 return true; 384 } 385 386 return false; 387 } 388 389 void AMDGPUDAGToDAGISel::SelectBuildVector(SDNode *N, unsigned RegClassID) { 390 EVT VT = N->getValueType(0); 391 unsigned NumVectorElts = VT.getVectorNumElements(); 392 EVT EltVT = VT.getVectorElementType(); 393 const AMDGPURegisterInfo *TRI = Subtarget->getRegisterInfo(); 394 SDLoc DL(N); 395 SDValue RegClass = CurDAG->getTargetConstant(RegClassID, DL, MVT::i32); 396 397 if (NumVectorElts == 1) { 398 CurDAG->SelectNodeTo(N, AMDGPU::COPY_TO_REGCLASS, EltVT, N->getOperand(0), 399 RegClass); 400 return; 401 } 402 403 assert(NumVectorElts <= 16 && "Vectors with more than 16 elements not " 404 "supported yet"); 405 // 16 = Max Num Vector Elements 406 // 2 = 2 REG_SEQUENCE operands per element (value, subreg index) 407 // 1 = Vector Register Class 408 SmallVector<SDValue, 16 * 2 + 1> RegSeqArgs(NumVectorElts * 2 + 1); 409 410 RegSeqArgs[0] = CurDAG->getTargetConstant(RegClassID, DL, MVT::i32); 411 bool IsRegSeq = true; 412 unsigned NOps = N->getNumOperands(); 413 for (unsigned i = 0; i < NOps; i++) { 414 // XXX: Why is this here? 415 if (isa<RegisterSDNode>(N->getOperand(i))) { 416 IsRegSeq = false; 417 break; 418 } 419 RegSeqArgs[1 + (2 * i)] = N->getOperand(i); 420 RegSeqArgs[1 + (2 * i) + 1] = 421 CurDAG->getTargetConstant(TRI->getSubRegFromChannel(i), DL, 422 MVT::i32); 423 } 424 if (NOps != NumVectorElts) { 425 // Fill in the missing undef elements if this was a scalar_to_vector. 426 assert(N->getOpcode() == ISD::SCALAR_TO_VECTOR && NOps < NumVectorElts); 427 MachineSDNode *ImpDef = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF, 428 DL, EltVT); 429 for (unsigned i = NOps; i < NumVectorElts; ++i) { 430 RegSeqArgs[1 + (2 * i)] = SDValue(ImpDef, 0); 431 RegSeqArgs[1 + (2 * i) + 1] = 432 CurDAG->getTargetConstant(TRI->getSubRegFromChannel(i), DL, MVT::i32); 433 } 434 } 435 436 if (!IsRegSeq) 437 SelectCode(N); 438 CurDAG->SelectNodeTo(N, AMDGPU::REG_SEQUENCE, N->getVTList(), RegSeqArgs); 439 } 440 441 void AMDGPUDAGToDAGISel::Select(SDNode *N) { 442 unsigned int Opc = N->getOpcode(); 443 if (N->isMachineOpcode()) { 444 N->setNodeId(-1); 445 return; // Already selected. 446 } 447 448 if (isa<AtomicSDNode>(N) || 449 (Opc == AMDGPUISD::ATOMIC_INC || Opc == AMDGPUISD::ATOMIC_DEC)) 450 N = glueCopyToM0(N); 451 452 switch (Opc) { 453 default: break; 454 // We are selecting i64 ADD here instead of custom lower it during 455 // DAG legalization, so we can fold some i64 ADDs used for address 456 // calculation into the LOAD and STORE instructions. 457 case ISD::ADD: 458 case ISD::ADDC: 459 case ISD::ADDE: 460 case ISD::SUB: 461 case ISD::SUBC: 462 case ISD::SUBE: { 463 if (N->getValueType(0) != MVT::i64) 464 break; 465 466 SelectADD_SUB_I64(N); 467 return; 468 } 469 case ISD::UADDO: 470 case ISD::USUBO: { 471 SelectUADDO_USUBO(N); 472 return; 473 } 474 case AMDGPUISD::FMUL_W_CHAIN: { 475 SelectFMUL_W_CHAIN(N); 476 return; 477 } 478 case AMDGPUISD::FMA_W_CHAIN: { 479 SelectFMA_W_CHAIN(N); 480 return; 481 } 482 483 case ISD::SCALAR_TO_VECTOR: 484 case ISD::BUILD_VECTOR: { 485 EVT VT = N->getValueType(0); 486 unsigned NumVectorElts = VT.getVectorNumElements(); 487 488 if (VT == MVT::v2i16 || VT == MVT::v2f16) { 489 if (Opc == ISD::BUILD_VECTOR) { 490 uint32_t LHSVal, RHSVal; 491 if (getConstantValue(N->getOperand(0), LHSVal) && 492 getConstantValue(N->getOperand(1), RHSVal)) { 493 uint32_t K = LHSVal | (RHSVal << 16); 494 CurDAG->SelectNodeTo(N, AMDGPU::S_MOV_B32, VT, 495 CurDAG->getTargetConstant(K, SDLoc(N), MVT::i32)); 496 return; 497 } 498 } 499 500 break; 501 } 502 503 assert(VT.getVectorElementType().bitsEq(MVT::i32)); 504 unsigned RegClassID = selectSGPRVectorRegClassID(NumVectorElts); 505 SelectBuildVector(N, RegClassID); 506 return; 507 } 508 case ISD::BUILD_PAIR: { 509 SDValue RC, SubReg0, SubReg1; 510 SDLoc DL(N); 511 if (N->getValueType(0) == MVT::i128) { 512 RC = CurDAG->getTargetConstant(AMDGPU::SReg_128RegClassID, DL, MVT::i32); 513 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0_sub1, DL, MVT::i32); 514 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub2_sub3, DL, MVT::i32); 515 } else if (N->getValueType(0) == MVT::i64) { 516 RC = CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32); 517 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32); 518 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32); 519 } else { 520 llvm_unreachable("Unhandled value type for BUILD_PAIR"); 521 } 522 const SDValue Ops[] = { RC, N->getOperand(0), SubReg0, 523 N->getOperand(1), SubReg1 }; 524 ReplaceNode(N, CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, 525 N->getValueType(0), Ops)); 526 return; 527 } 528 529 case ISD::Constant: 530 case ISD::ConstantFP: { 531 if (N->getValueType(0).getSizeInBits() != 64 || isInlineImmediate(N)) 532 break; 533 534 uint64_t Imm; 535 if (ConstantFPSDNode *FP = dyn_cast<ConstantFPSDNode>(N)) 536 Imm = FP->getValueAPF().bitcastToAPInt().getZExtValue(); 537 else { 538 ConstantSDNode *C = cast<ConstantSDNode>(N); 539 Imm = C->getZExtValue(); 540 } 541 542 SDLoc DL(N); 543 SDNode *Lo = CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, 544 CurDAG->getConstant(Imm & 0xFFFFFFFF, DL, 545 MVT::i32)); 546 SDNode *Hi = CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, 547 CurDAG->getConstant(Imm >> 32, DL, MVT::i32)); 548 const SDValue Ops[] = { 549 CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32), 550 SDValue(Lo, 0), CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32), 551 SDValue(Hi, 0), CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32) 552 }; 553 554 ReplaceNode(N, CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, 555 N->getValueType(0), Ops)); 556 return; 557 } 558 case ISD::LOAD: 559 case ISD::STORE: { 560 N = glueCopyToM0(N); 561 break; 562 } 563 564 case AMDGPUISD::BFE_I32: 565 case AMDGPUISD::BFE_U32: { 566 // There is a scalar version available, but unlike the vector version which 567 // has a separate operand for the offset and width, the scalar version packs 568 // the width and offset into a single operand. Try to move to the scalar 569 // version if the offsets are constant, so that we can try to keep extended 570 // loads of kernel arguments in SGPRs. 571 572 // TODO: Technically we could try to pattern match scalar bitshifts of 573 // dynamic values, but it's probably not useful. 574 ConstantSDNode *Offset = dyn_cast<ConstantSDNode>(N->getOperand(1)); 575 if (!Offset) 576 break; 577 578 ConstantSDNode *Width = dyn_cast<ConstantSDNode>(N->getOperand(2)); 579 if (!Width) 580 break; 581 582 bool Signed = Opc == AMDGPUISD::BFE_I32; 583 584 uint32_t OffsetVal = Offset->getZExtValue(); 585 uint32_t WidthVal = Width->getZExtValue(); 586 587 ReplaceNode(N, getS_BFE(Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32, 588 SDLoc(N), N->getOperand(0), OffsetVal, WidthVal)); 589 return; 590 } 591 case AMDGPUISD::DIV_SCALE: { 592 SelectDIV_SCALE(N); 593 return; 594 } 595 case ISD::CopyToReg: { 596 const SITargetLowering& Lowering = 597 *static_cast<const SITargetLowering*>(getTargetLowering()); 598 N = Lowering.legalizeTargetIndependentNode(N, *CurDAG); 599 break; 600 } 601 case ISD::AND: 602 case ISD::SRL: 603 case ISD::SRA: 604 case ISD::SIGN_EXTEND_INREG: 605 if (N->getValueType(0) != MVT::i32) 606 break; 607 608 SelectS_BFE(N); 609 return; 610 case ISD::BRCOND: 611 SelectBRCOND(N); 612 return; 613 case ISD::FMAD: 614 SelectFMAD(N); 615 return; 616 case AMDGPUISD::ATOMIC_CMP_SWAP: 617 SelectATOMIC_CMP_SWAP(N); 618 return; 619 } 620 621 SelectCode(N); 622 } 623 624 bool AMDGPUDAGToDAGISel::isConstantLoad(const MemSDNode *N, int CbId) const { 625 if (!N->readMem()) 626 return false; 627 if (CbId == -1) 628 return N->getAddressSpace() == AMDGPUASI.CONSTANT_ADDRESS; 629 630 return N->getAddressSpace() == AMDGPUASI.CONSTANT_BUFFER_0 + CbId; 631 } 632 633 bool AMDGPUDAGToDAGISel::isUniformBr(const SDNode *N) const { 634 const BasicBlock *BB = FuncInfo->MBB->getBasicBlock(); 635 const Instruction *Term = BB->getTerminator(); 636 return Term->getMetadata("amdgpu.uniform") || 637 Term->getMetadata("structurizecfg.uniform"); 638 } 639 640 StringRef AMDGPUDAGToDAGISel::getPassName() const { 641 return "AMDGPU DAG->DAG Pattern Instruction Selection"; 642 } 643 644 //===----------------------------------------------------------------------===// 645 // Complex Patterns 646 //===----------------------------------------------------------------------===// 647 648 bool AMDGPUDAGToDAGISel::SelectGlobalValueConstantOffset(SDValue Addr, 649 SDValue& IntPtr) { 650 if (ConstantSDNode *Cst = dyn_cast<ConstantSDNode>(Addr)) { 651 IntPtr = CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4, SDLoc(Addr), 652 true); 653 return true; 654 } 655 return false; 656 } 657 658 bool AMDGPUDAGToDAGISel::SelectGlobalValueVariableOffset(SDValue Addr, 659 SDValue& BaseReg, SDValue &Offset) { 660 if (!isa<ConstantSDNode>(Addr)) { 661 BaseReg = Addr; 662 Offset = CurDAG->getIntPtrConstant(0, SDLoc(Addr), true); 663 return true; 664 } 665 return false; 666 } 667 668 bool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, 669 SDValue &Offset) { 670 return false; 671 } 672 673 bool AMDGPUDAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base, 674 SDValue &Offset) { 675 ConstantSDNode *C; 676 SDLoc DL(Addr); 677 678 if ((C = dyn_cast<ConstantSDNode>(Addr))) { 679 Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32); 680 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32); 681 } else if ((Addr.getOpcode() == AMDGPUISD::DWORDADDR) && 682 (C = dyn_cast<ConstantSDNode>(Addr.getOperand(0)))) { 683 Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32); 684 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32); 685 } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) && 686 (C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) { 687 Base = Addr.getOperand(0); 688 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32); 689 } else { 690 Base = Addr; 691 Offset = CurDAG->getTargetConstant(0, DL, MVT::i32); 692 } 693 694 return true; 695 } 696 697 void AMDGPUDAGToDAGISel::SelectADD_SUB_I64(SDNode *N) { 698 SDLoc DL(N); 699 SDValue LHS = N->getOperand(0); 700 SDValue RHS = N->getOperand(1); 701 702 unsigned Opcode = N->getOpcode(); 703 bool ConsumeCarry = (Opcode == ISD::ADDE || Opcode == ISD::SUBE); 704 bool ProduceCarry = 705 ConsumeCarry || Opcode == ISD::ADDC || Opcode == ISD::SUBC; 706 bool IsAdd = 707 (Opcode == ISD::ADD || Opcode == ISD::ADDC || Opcode == ISD::ADDE); 708 709 SDValue Sub0 = CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32); 710 SDValue Sub1 = CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32); 711 712 SDNode *Lo0 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 713 DL, MVT::i32, LHS, Sub0); 714 SDNode *Hi0 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 715 DL, MVT::i32, LHS, Sub1); 716 717 SDNode *Lo1 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 718 DL, MVT::i32, RHS, Sub0); 719 SDNode *Hi1 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG, 720 DL, MVT::i32, RHS, Sub1); 721 722 SDVTList VTList = CurDAG->getVTList(MVT::i32, MVT::Glue); 723 724 unsigned Opc = IsAdd ? AMDGPU::S_ADD_U32 : AMDGPU::S_SUB_U32; 725 unsigned CarryOpc = IsAdd ? AMDGPU::S_ADDC_U32 : AMDGPU::S_SUBB_U32; 726 727 SDNode *AddLo; 728 if (!ConsumeCarry) { 729 SDValue Args[] = { SDValue(Lo0, 0), SDValue(Lo1, 0) }; 730 AddLo = CurDAG->getMachineNode(Opc, DL, VTList, Args); 731 } else { 732 SDValue Args[] = { SDValue(Lo0, 0), SDValue(Lo1, 0), N->getOperand(2) }; 733 AddLo = CurDAG->getMachineNode(CarryOpc, DL, VTList, Args); 734 } 735 SDValue AddHiArgs[] = { 736 SDValue(Hi0, 0), 737 SDValue(Hi1, 0), 738 SDValue(AddLo, 1) 739 }; 740 SDNode *AddHi = CurDAG->getMachineNode(CarryOpc, DL, VTList, AddHiArgs); 741 742 SDValue RegSequenceArgs[] = { 743 CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32), 744 SDValue(AddLo,0), 745 Sub0, 746 SDValue(AddHi,0), 747 Sub1, 748 }; 749 SDNode *RegSequence = CurDAG->getMachineNode(AMDGPU::REG_SEQUENCE, DL, 750 MVT::i64, RegSequenceArgs); 751 752 if (ProduceCarry) { 753 // Replace the carry-use 754 CurDAG->ReplaceAllUsesOfValueWith(SDValue(N, 1), SDValue(AddHi, 1)); 755 } 756 757 // Replace the remaining uses. 758 CurDAG->ReplaceAllUsesWith(N, RegSequence); 759 CurDAG->RemoveDeadNode(N); 760 } 761 762 void AMDGPUDAGToDAGISel::SelectUADDO_USUBO(SDNode *N) { 763 // The name of the opcodes are misleading. v_add_i32/v_sub_i32 have unsigned 764 // carry out despite the _i32 name. These were renamed in VI to _U32. 765 // FIXME: We should probably rename the opcodes here. 766 unsigned Opc = N->getOpcode() == ISD::UADDO ? 767 AMDGPU::V_ADD_I32_e64 : AMDGPU::V_SUB_I32_e64; 768 769 CurDAG->SelectNodeTo(N, Opc, N->getVTList(), 770 { N->getOperand(0), N->getOperand(1) }); 771 } 772 773 void AMDGPUDAGToDAGISel::SelectFMA_W_CHAIN(SDNode *N) { 774 SDLoc SL(N); 775 // src0_modifiers, src0, src1_modifiers, src1, src2_modifiers, src2, clamp, omod 776 SDValue Ops[10]; 777 778 SelectVOP3Mods0(N->getOperand(1), Ops[1], Ops[0], Ops[6], Ops[7]); 779 SelectVOP3Mods(N->getOperand(2), Ops[3], Ops[2]); 780 SelectVOP3Mods(N->getOperand(3), Ops[5], Ops[4]); 781 Ops[8] = N->getOperand(0); 782 Ops[9] = N->getOperand(4); 783 784 CurDAG->SelectNodeTo(N, AMDGPU::V_FMA_F32, N->getVTList(), Ops); 785 } 786 787 void AMDGPUDAGToDAGISel::SelectFMUL_W_CHAIN(SDNode *N) { 788 SDLoc SL(N); 789 // src0_modifiers, src0, src1_modifiers, src1, clamp, omod 790 SDValue Ops[8]; 791 792 SelectVOP3Mods0(N->getOperand(1), Ops[1], Ops[0], Ops[4], Ops[5]); 793 SelectVOP3Mods(N->getOperand(2), Ops[3], Ops[2]); 794 Ops[6] = N->getOperand(0); 795 Ops[7] = N->getOperand(3); 796 797 CurDAG->SelectNodeTo(N, AMDGPU::V_MUL_F32_e64, N->getVTList(), Ops); 798 } 799 800 // We need to handle this here because tablegen doesn't support matching 801 // instructions with multiple outputs. 802 void AMDGPUDAGToDAGISel::SelectDIV_SCALE(SDNode *N) { 803 SDLoc SL(N); 804 EVT VT = N->getValueType(0); 805 806 assert(VT == MVT::f32 || VT == MVT::f64); 807 808 unsigned Opc 809 = (VT == MVT::f64) ? AMDGPU::V_DIV_SCALE_F64 : AMDGPU::V_DIV_SCALE_F32; 810 811 SDValue Ops[] = { N->getOperand(0), N->getOperand(1), N->getOperand(2) }; 812 CurDAG->SelectNodeTo(N, Opc, N->getVTList(), Ops); 813 } 814 815 bool AMDGPUDAGToDAGISel::isDSOffsetLegal(const SDValue &Base, unsigned Offset, 816 unsigned OffsetBits) const { 817 if ((OffsetBits == 16 && !isUInt<16>(Offset)) || 818 (OffsetBits == 8 && !isUInt<8>(Offset))) 819 return false; 820 821 if (Subtarget->getGeneration() >= AMDGPUSubtarget::SEA_ISLANDS || 822 Subtarget->unsafeDSOffsetFoldingEnabled()) 823 return true; 824 825 // On Southern Islands instruction with a negative base value and an offset 826 // don't seem to work. 827 return CurDAG->SignBitIsZero(Base); 828 } 829 830 bool AMDGPUDAGToDAGISel::SelectDS1Addr1Offset(SDValue Addr, SDValue &Base, 831 SDValue &Offset) const { 832 SDLoc DL(Addr); 833 if (CurDAG->isBaseWithConstantOffset(Addr)) { 834 SDValue N0 = Addr.getOperand(0); 835 SDValue N1 = Addr.getOperand(1); 836 ConstantSDNode *C1 = cast<ConstantSDNode>(N1); 837 if (isDSOffsetLegal(N0, C1->getSExtValue(), 16)) { 838 // (add n0, c0) 839 Base = N0; 840 Offset = CurDAG->getTargetConstant(C1->getZExtValue(), DL, MVT::i16); 841 return true; 842 } 843 } else if (Addr.getOpcode() == ISD::SUB) { 844 // sub C, x -> add (sub 0, x), C 845 if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(Addr.getOperand(0))) { 846 int64_t ByteOffset = C->getSExtValue(); 847 if (isUInt<16>(ByteOffset)) { 848 SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32); 849 850 // XXX - This is kind of hacky. Create a dummy sub node so we can check 851 // the known bits in isDSOffsetLegal. We need to emit the selected node 852 // here, so this is thrown away. 853 SDValue Sub = CurDAG->getNode(ISD::SUB, DL, MVT::i32, 854 Zero, Addr.getOperand(1)); 855 856 if (isDSOffsetLegal(Sub, ByteOffset, 16)) { 857 MachineSDNode *MachineSub 858 = CurDAG->getMachineNode(AMDGPU::V_SUB_I32_e32, DL, MVT::i32, 859 Zero, Addr.getOperand(1)); 860 861 Base = SDValue(MachineSub, 0); 862 Offset = CurDAG->getTargetConstant(ByteOffset, DL, MVT::i16); 863 return true; 864 } 865 } 866 } 867 } else if (const ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) { 868 // If we have a constant address, prefer to put the constant into the 869 // offset. This can save moves to load the constant address since multiple 870 // operations can share the zero base address register, and enables merging 871 // into read2 / write2 instructions. 872 873 SDLoc DL(Addr); 874 875 if (isUInt<16>(CAddr->getZExtValue())) { 876 SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32); 877 MachineSDNode *MovZero = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32, 878 DL, MVT::i32, Zero); 879 Base = SDValue(MovZero, 0); 880 Offset = CurDAG->getTargetConstant(CAddr->getZExtValue(), DL, MVT::i16); 881 return true; 882 } 883 } 884 885 // default case 886 Base = Addr; 887 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i16); 888 return true; 889 } 890 891 // TODO: If offset is too big, put low 16-bit into offset. 892 bool AMDGPUDAGToDAGISel::SelectDS64Bit4ByteAligned(SDValue Addr, SDValue &Base, 893 SDValue &Offset0, 894 SDValue &Offset1) const { 895 SDLoc DL(Addr); 896 897 if (CurDAG->isBaseWithConstantOffset(Addr)) { 898 SDValue N0 = Addr.getOperand(0); 899 SDValue N1 = Addr.getOperand(1); 900 ConstantSDNode *C1 = cast<ConstantSDNode>(N1); 901 unsigned DWordOffset0 = C1->getZExtValue() / 4; 902 unsigned DWordOffset1 = DWordOffset0 + 1; 903 // (add n0, c0) 904 if (isDSOffsetLegal(N0, DWordOffset1, 8)) { 905 Base = N0; 906 Offset0 = CurDAG->getTargetConstant(DWordOffset0, DL, MVT::i8); 907 Offset1 = CurDAG->getTargetConstant(DWordOffset1, DL, MVT::i8); 908 return true; 909 } 910 } else if (Addr.getOpcode() == ISD::SUB) { 911 // sub C, x -> add (sub 0, x), C 912 if (const ConstantSDNode *C = dyn_cast<ConstantSDNode>(Addr.getOperand(0))) { 913 unsigned DWordOffset0 = C->getZExtValue() / 4; 914 unsigned DWordOffset1 = DWordOffset0 + 1; 915 916 if (isUInt<8>(DWordOffset0)) { 917 SDLoc DL(Addr); 918 SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32); 919 920 // XXX - This is kind of hacky. Create a dummy sub node so we can check 921 // the known bits in isDSOffsetLegal. We need to emit the selected node 922 // here, so this is thrown away. 923 SDValue Sub = CurDAG->getNode(ISD::SUB, DL, MVT::i32, 924 Zero, Addr.getOperand(1)); 925 926 if (isDSOffsetLegal(Sub, DWordOffset1, 8)) { 927 MachineSDNode *MachineSub 928 = CurDAG->getMachineNode(AMDGPU::V_SUB_I32_e32, DL, MVT::i32, 929 Zero, Addr.getOperand(1)); 930 931 Base = SDValue(MachineSub, 0); 932 Offset0 = CurDAG->getTargetConstant(DWordOffset0, DL, MVT::i8); 933 Offset1 = CurDAG->getTargetConstant(DWordOffset1, DL, MVT::i8); 934 return true; 935 } 936 } 937 } 938 } else if (const ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) { 939 unsigned DWordOffset0 = CAddr->getZExtValue() / 4; 940 unsigned DWordOffset1 = DWordOffset0 + 1; 941 assert(4 * DWordOffset0 == CAddr->getZExtValue()); 942 943 if (isUInt<8>(DWordOffset0) && isUInt<8>(DWordOffset1)) { 944 SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32); 945 MachineSDNode *MovZero 946 = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32, 947 DL, MVT::i32, Zero); 948 Base = SDValue(MovZero, 0); 949 Offset0 = CurDAG->getTargetConstant(DWordOffset0, DL, MVT::i8); 950 Offset1 = CurDAG->getTargetConstant(DWordOffset1, DL, MVT::i8); 951 return true; 952 } 953 } 954 955 // default case 956 957 // FIXME: This is broken on SI where we still need to check if the base 958 // pointer is positive here. 959 Base = Addr; 960 Offset0 = CurDAG->getTargetConstant(0, DL, MVT::i8); 961 Offset1 = CurDAG->getTargetConstant(1, DL, MVT::i8); 962 return true; 963 } 964 965 static bool isLegalMUBUFImmOffset(unsigned Imm) { 966 return isUInt<12>(Imm); 967 } 968 969 static bool isLegalMUBUFImmOffset(const ConstantSDNode *Imm) { 970 return isLegalMUBUFImmOffset(Imm->getZExtValue()); 971 } 972 973 bool AMDGPUDAGToDAGISel::SelectMUBUF(SDValue Addr, SDValue &Ptr, 974 SDValue &VAddr, SDValue &SOffset, 975 SDValue &Offset, SDValue &Offen, 976 SDValue &Idxen, SDValue &Addr64, 977 SDValue &GLC, SDValue &SLC, 978 SDValue &TFE) const { 979 // Subtarget prefers to use flat instruction 980 if (Subtarget->useFlatForGlobal()) 981 return false; 982 983 SDLoc DL(Addr); 984 985 if (!GLC.getNode()) 986 GLC = CurDAG->getTargetConstant(0, DL, MVT::i1); 987 if (!SLC.getNode()) 988 SLC = CurDAG->getTargetConstant(0, DL, MVT::i1); 989 TFE = CurDAG->getTargetConstant(0, DL, MVT::i1); 990 991 Idxen = CurDAG->getTargetConstant(0, DL, MVT::i1); 992 Offen = CurDAG->getTargetConstant(0, DL, MVT::i1); 993 Addr64 = CurDAG->getTargetConstant(0, DL, MVT::i1); 994 SOffset = CurDAG->getTargetConstant(0, DL, MVT::i32); 995 996 if (CurDAG->isBaseWithConstantOffset(Addr)) { 997 SDValue N0 = Addr.getOperand(0); 998 SDValue N1 = Addr.getOperand(1); 999 ConstantSDNode *C1 = cast<ConstantSDNode>(N1); 1000 1001 if (N0.getOpcode() == ISD::ADD) { 1002 // (add (add N2, N3), C1) -> addr64 1003 SDValue N2 = N0.getOperand(0); 1004 SDValue N3 = N0.getOperand(1); 1005 Addr64 = CurDAG->getTargetConstant(1, DL, MVT::i1); 1006 Ptr = N2; 1007 VAddr = N3; 1008 } else { 1009 // (add N0, C1) -> offset 1010 VAddr = CurDAG->getTargetConstant(0, DL, MVT::i32); 1011 Ptr = N0; 1012 } 1013 1014 if (isLegalMUBUFImmOffset(C1)) { 1015 Offset = CurDAG->getTargetConstant(C1->getZExtValue(), DL, MVT::i16); 1016 return true; 1017 } 1018 1019 if (isUInt<32>(C1->getZExtValue())) { 1020 // Illegal offset, store it in soffset. 1021 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16); 1022 SOffset = SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, 1023 CurDAG->getTargetConstant(C1->getZExtValue(), DL, MVT::i32)), 1024 0); 1025 return true; 1026 } 1027 } 1028 1029 if (Addr.getOpcode() == ISD::ADD) { 1030 // (add N0, N1) -> addr64 1031 SDValue N0 = Addr.getOperand(0); 1032 SDValue N1 = Addr.getOperand(1); 1033 Addr64 = CurDAG->getTargetConstant(1, DL, MVT::i1); 1034 Ptr = N0; 1035 VAddr = N1; 1036 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16); 1037 return true; 1038 } 1039 1040 // default case -> offset 1041 VAddr = CurDAG->getTargetConstant(0, DL, MVT::i32); 1042 Ptr = Addr; 1043 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16); 1044 1045 return true; 1046 } 1047 1048 bool AMDGPUDAGToDAGISel::SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, 1049 SDValue &VAddr, SDValue &SOffset, 1050 SDValue &Offset, SDValue &GLC, 1051 SDValue &SLC, SDValue &TFE) const { 1052 SDValue Ptr, Offen, Idxen, Addr64; 1053 1054 // addr64 bit was removed for volcanic islands. 1055 if (Subtarget->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS) 1056 return false; 1057 1058 if (!SelectMUBUF(Addr, Ptr, VAddr, SOffset, Offset, Offen, Idxen, Addr64, 1059 GLC, SLC, TFE)) 1060 return false; 1061 1062 ConstantSDNode *C = cast<ConstantSDNode>(Addr64); 1063 if (C->getSExtValue()) { 1064 SDLoc DL(Addr); 1065 1066 const SITargetLowering& Lowering = 1067 *static_cast<const SITargetLowering*>(getTargetLowering()); 1068 1069 SRsrc = SDValue(Lowering.wrapAddr64Rsrc(*CurDAG, DL, Ptr), 0); 1070 return true; 1071 } 1072 1073 return false; 1074 } 1075 1076 bool AMDGPUDAGToDAGISel::SelectMUBUFAddr64(SDValue Addr, SDValue &SRsrc, 1077 SDValue &VAddr, SDValue &SOffset, 1078 SDValue &Offset, 1079 SDValue &SLC) const { 1080 SLC = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i1); 1081 SDValue GLC, TFE; 1082 1083 return SelectMUBUFAddr64(Addr, SRsrc, VAddr, SOffset, Offset, GLC, SLC, TFE); 1084 } 1085 1086 static bool isStackPtrRelative(const MachinePointerInfo &PtrInfo) { 1087 auto PSV = PtrInfo.V.dyn_cast<const PseudoSourceValue *>(); 1088 return PSV && PSV->isStack(); 1089 } 1090 1091 std::pair<SDValue, SDValue> AMDGPUDAGToDAGISel::foldFrameIndex(SDValue N) const { 1092 const MachineFunction &MF = CurDAG->getMachineFunction(); 1093 const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>(); 1094 1095 if (auto FI = dyn_cast<FrameIndexSDNode>(N)) { 1096 SDValue TFI = CurDAG->getTargetFrameIndex(FI->getIndex(), 1097 FI->getValueType(0)); 1098 1099 // If we can resolve this to a frame index access, this is relative to the 1100 // frame pointer SGPR. 1101 return std::make_pair(TFI, CurDAG->getRegister(Info->getFrameOffsetReg(), 1102 MVT::i32)); 1103 } 1104 1105 // If we don't know this private access is a local stack object, it needs to 1106 // be relative to the entry point's scratch wave offset register. 1107 return std::make_pair(N, CurDAG->getRegister(Info->getScratchWaveOffsetReg(), 1108 MVT::i32)); 1109 } 1110 1111 bool AMDGPUDAGToDAGISel::SelectMUBUFScratchOffen(SDNode *Parent, 1112 SDValue Addr, SDValue &Rsrc, 1113 SDValue &VAddr, SDValue &SOffset, 1114 SDValue &ImmOffset) const { 1115 1116 SDLoc DL(Addr); 1117 MachineFunction &MF = CurDAG->getMachineFunction(); 1118 const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>(); 1119 1120 Rsrc = CurDAG->getRegister(Info->getScratchRSrcReg(), MVT::v4i32); 1121 1122 if (ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) { 1123 unsigned Imm = CAddr->getZExtValue(); 1124 assert(!isLegalMUBUFImmOffset(Imm) && 1125 "should have been selected by other pattern"); 1126 1127 SDValue HighBits = CurDAG->getTargetConstant(Imm & ~4095, DL, MVT::i32); 1128 MachineSDNode *MovHighBits = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32, 1129 DL, MVT::i32, HighBits); 1130 VAddr = SDValue(MovHighBits, 0); 1131 1132 // In a call sequence, stores to the argument stack area are relative to the 1133 // stack pointer. 1134 const MachinePointerInfo &PtrInfo = cast<MemSDNode>(Parent)->getPointerInfo(); 1135 unsigned SOffsetReg = isStackPtrRelative(PtrInfo) ? 1136 Info->getStackPtrOffsetReg() : Info->getScratchWaveOffsetReg(); 1137 1138 SOffset = CurDAG->getRegister(SOffsetReg, MVT::i32); 1139 ImmOffset = CurDAG->getTargetConstant(Imm & 4095, DL, MVT::i16); 1140 return true; 1141 } 1142 1143 if (CurDAG->isBaseWithConstantOffset(Addr)) { 1144 // (add n0, c1) 1145 1146 SDValue N0 = Addr.getOperand(0); 1147 SDValue N1 = Addr.getOperand(1); 1148 1149 // Offsets in vaddr must be positive. 1150 ConstantSDNode *C1 = cast<ConstantSDNode>(N1); 1151 if (isLegalMUBUFImmOffset(C1)) { 1152 std::tie(VAddr, SOffset) = foldFrameIndex(N0); 1153 ImmOffset = CurDAG->getTargetConstant(C1->getZExtValue(), DL, MVT::i16); 1154 return true; 1155 } 1156 } 1157 1158 // (node) 1159 std::tie(VAddr, SOffset) = foldFrameIndex(Addr); 1160 ImmOffset = CurDAG->getTargetConstant(0, DL, MVT::i16); 1161 return true; 1162 } 1163 1164 bool AMDGPUDAGToDAGISel::SelectMUBUFScratchOffset(SDNode *Parent, 1165 SDValue Addr, 1166 SDValue &SRsrc, 1167 SDValue &SOffset, 1168 SDValue &Offset) const { 1169 ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr); 1170 if (!CAddr || !isLegalMUBUFImmOffset(CAddr)) 1171 return false; 1172 1173 SDLoc DL(Addr); 1174 MachineFunction &MF = CurDAG->getMachineFunction(); 1175 const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>(); 1176 1177 SRsrc = CurDAG->getRegister(Info->getScratchRSrcReg(), MVT::v4i32); 1178 1179 const MachinePointerInfo &PtrInfo = cast<MemSDNode>(Parent)->getPointerInfo(); 1180 unsigned SOffsetReg = isStackPtrRelative(PtrInfo) ? 1181 Info->getStackPtrOffsetReg() : Info->getScratchWaveOffsetReg(); 1182 1183 // FIXME: Get from MachinePointerInfo? We should only be using the frame 1184 // offset if we know this is in a call sequence. 1185 SOffset = CurDAG->getRegister(SOffsetReg, MVT::i32); 1186 1187 Offset = CurDAG->getTargetConstant(CAddr->getZExtValue(), DL, MVT::i16); 1188 return true; 1189 } 1190 1191 bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, 1192 SDValue &SOffset, SDValue &Offset, 1193 SDValue &GLC, SDValue &SLC, 1194 SDValue &TFE) const { 1195 SDValue Ptr, VAddr, Offen, Idxen, Addr64; 1196 const SIInstrInfo *TII = 1197 static_cast<const SIInstrInfo *>(Subtarget->getInstrInfo()); 1198 1199 if (!SelectMUBUF(Addr, Ptr, VAddr, SOffset, Offset, Offen, Idxen, Addr64, 1200 GLC, SLC, TFE)) 1201 return false; 1202 1203 if (!cast<ConstantSDNode>(Offen)->getSExtValue() && 1204 !cast<ConstantSDNode>(Idxen)->getSExtValue() && 1205 !cast<ConstantSDNode>(Addr64)->getSExtValue()) { 1206 uint64_t Rsrc = TII->getDefaultRsrcDataFormat() | 1207 APInt::getAllOnesValue(32).getZExtValue(); // Size 1208 SDLoc DL(Addr); 1209 1210 const SITargetLowering& Lowering = 1211 *static_cast<const SITargetLowering*>(getTargetLowering()); 1212 1213 SRsrc = SDValue(Lowering.buildRSRC(*CurDAG, DL, Ptr, 0, Rsrc), 0); 1214 return true; 1215 } 1216 return false; 1217 } 1218 1219 bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, 1220 SDValue &Soffset, SDValue &Offset 1221 ) const { 1222 SDValue GLC, SLC, TFE; 1223 1224 return SelectMUBUFOffset(Addr, SRsrc, Soffset, Offset, GLC, SLC, TFE); 1225 } 1226 bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(SDValue Addr, SDValue &SRsrc, 1227 SDValue &Soffset, SDValue &Offset, 1228 SDValue &SLC) const { 1229 SDValue GLC, TFE; 1230 1231 return SelectMUBUFOffset(Addr, SRsrc, Soffset, Offset, GLC, SLC, TFE); 1232 } 1233 1234 bool AMDGPUDAGToDAGISel::SelectMUBUFConstant(SDValue Constant, 1235 SDValue &SOffset, 1236 SDValue &ImmOffset) const { 1237 SDLoc DL(Constant); 1238 uint32_t Imm = cast<ConstantSDNode>(Constant)->getZExtValue(); 1239 uint32_t Overflow = 0; 1240 1241 if (Imm >= 4096) { 1242 if (Imm <= 4095 + 64) { 1243 // Use an SOffset inline constant for 1..64 1244 Overflow = Imm - 4095; 1245 Imm = 4095; 1246 } else { 1247 // Try to keep the same value in SOffset for adjacent loads, so that 1248 // the corresponding register contents can be re-used. 1249 // 1250 // Load values with all low-bits set into SOffset, so that a larger 1251 // range of values can be covered using s_movk_i32 1252 uint32_t High = (Imm + 1) & ~4095; 1253 uint32_t Low = (Imm + 1) & 4095; 1254 Imm = Low; 1255 Overflow = High - 1; 1256 } 1257 } 1258 1259 // There is a hardware bug in SI and CI which prevents address clamping in 1260 // MUBUF instructions from working correctly with SOffsets. The immediate 1261 // offset is unaffected. 1262 if (Overflow > 0 && 1263 Subtarget->getGeneration() <= AMDGPUSubtarget::SEA_ISLANDS) 1264 return false; 1265 1266 ImmOffset = CurDAG->getTargetConstant(Imm, DL, MVT::i16); 1267 1268 if (Overflow <= 64) 1269 SOffset = CurDAG->getTargetConstant(Overflow, DL, MVT::i32); 1270 else 1271 SOffset = SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, 1272 CurDAG->getTargetConstant(Overflow, DL, MVT::i32)), 1273 0); 1274 1275 return true; 1276 } 1277 1278 bool AMDGPUDAGToDAGISel::SelectMUBUFIntrinsicOffset(SDValue Offset, 1279 SDValue &SOffset, 1280 SDValue &ImmOffset) const { 1281 SDLoc DL(Offset); 1282 1283 if (!isa<ConstantSDNode>(Offset)) 1284 return false; 1285 1286 return SelectMUBUFConstant(Offset, SOffset, ImmOffset); 1287 } 1288 1289 bool AMDGPUDAGToDAGISel::SelectMUBUFIntrinsicVOffset(SDValue Offset, 1290 SDValue &SOffset, 1291 SDValue &ImmOffset, 1292 SDValue &VOffset) const { 1293 SDLoc DL(Offset); 1294 1295 // Don't generate an unnecessary voffset for constant offsets. 1296 if (isa<ConstantSDNode>(Offset)) { 1297 SDValue Tmp1, Tmp2; 1298 1299 // When necessary, use a voffset in <= CI anyway to work around a hardware 1300 // bug. 1301 if (Subtarget->getGeneration() > AMDGPUSubtarget::SEA_ISLANDS || 1302 SelectMUBUFConstant(Offset, Tmp1, Tmp2)) 1303 return false; 1304 } 1305 1306 if (CurDAG->isBaseWithConstantOffset(Offset)) { 1307 SDValue N0 = Offset.getOperand(0); 1308 SDValue N1 = Offset.getOperand(1); 1309 if (cast<ConstantSDNode>(N1)->getSExtValue() >= 0 && 1310 SelectMUBUFConstant(N1, SOffset, ImmOffset)) { 1311 VOffset = N0; 1312 return true; 1313 } 1314 } 1315 1316 SOffset = CurDAG->getTargetConstant(0, DL, MVT::i32); 1317 ImmOffset = CurDAG->getTargetConstant(0, DL, MVT::i16); 1318 VOffset = Offset; 1319 1320 return true; 1321 } 1322 1323 template <bool IsSigned> 1324 bool AMDGPUDAGToDAGISel::SelectFlatOffset(SDValue Addr, 1325 SDValue &VAddr, 1326 SDValue &Offset, 1327 SDValue &SLC) const { 1328 int64_t OffsetVal = 0; 1329 1330 if (Subtarget->hasFlatInstOffsets() && 1331 CurDAG->isBaseWithConstantOffset(Addr)) { 1332 SDValue N0 = Addr.getOperand(0); 1333 SDValue N1 = Addr.getOperand(1); 1334 int64_t COffsetVal = cast<ConstantSDNode>(N1)->getSExtValue(); 1335 1336 if ((IsSigned && isInt<13>(COffsetVal)) || 1337 (!IsSigned && isUInt<12>(COffsetVal))) { 1338 Addr = N0; 1339 OffsetVal = COffsetVal; 1340 } 1341 } 1342 1343 VAddr = Addr; 1344 Offset = CurDAG->getTargetConstant(OffsetVal, SDLoc(), MVT::i16); 1345 SLC = CurDAG->getTargetConstant(0, SDLoc(), MVT::i1); 1346 1347 return true; 1348 } 1349 1350 bool AMDGPUDAGToDAGISel::SelectFlatAtomic(SDValue Addr, 1351 SDValue &VAddr, 1352 SDValue &Offset, 1353 SDValue &SLC) const { 1354 return SelectFlatOffset<false>(Addr, VAddr, Offset, SLC); 1355 } 1356 1357 bool AMDGPUDAGToDAGISel::SelectFlatAtomicSigned(SDValue Addr, 1358 SDValue &VAddr, 1359 SDValue &Offset, 1360 SDValue &SLC) const { 1361 return SelectFlatOffset<true>(Addr, VAddr, Offset, SLC); 1362 } 1363 1364 bool AMDGPUDAGToDAGISel::SelectSMRDOffset(SDValue ByteOffsetNode, 1365 SDValue &Offset, bool &Imm) const { 1366 1367 // FIXME: Handle non-constant offsets. 1368 ConstantSDNode *C = dyn_cast<ConstantSDNode>(ByteOffsetNode); 1369 if (!C) 1370 return false; 1371 1372 SDLoc SL(ByteOffsetNode); 1373 AMDGPUSubtarget::Generation Gen = Subtarget->getGeneration(); 1374 int64_t ByteOffset = C->getSExtValue(); 1375 int64_t EncodedOffset = AMDGPU::getSMRDEncodedOffset(*Subtarget, ByteOffset); 1376 1377 if (AMDGPU::isLegalSMRDImmOffset(*Subtarget, ByteOffset)) { 1378 Offset = CurDAG->getTargetConstant(EncodedOffset, SL, MVT::i32); 1379 Imm = true; 1380 return true; 1381 } 1382 1383 if (!isUInt<32>(EncodedOffset) || !isUInt<32>(ByteOffset)) 1384 return false; 1385 1386 if (Gen == AMDGPUSubtarget::SEA_ISLANDS && isUInt<32>(EncodedOffset)) { 1387 // 32-bit Immediates are supported on Sea Islands. 1388 Offset = CurDAG->getTargetConstant(EncodedOffset, SL, MVT::i32); 1389 } else { 1390 SDValue C32Bit = CurDAG->getTargetConstant(ByteOffset, SL, MVT::i32); 1391 Offset = SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, SL, MVT::i32, 1392 C32Bit), 0); 1393 } 1394 Imm = false; 1395 return true; 1396 } 1397 1398 bool AMDGPUDAGToDAGISel::SelectSMRD(SDValue Addr, SDValue &SBase, 1399 SDValue &Offset, bool &Imm) const { 1400 SDLoc SL(Addr); 1401 if (CurDAG->isBaseWithConstantOffset(Addr)) { 1402 SDValue N0 = Addr.getOperand(0); 1403 SDValue N1 = Addr.getOperand(1); 1404 1405 if (SelectSMRDOffset(N1, Offset, Imm)) { 1406 SBase = N0; 1407 return true; 1408 } 1409 } 1410 SBase = Addr; 1411 Offset = CurDAG->getTargetConstant(0, SL, MVT::i32); 1412 Imm = true; 1413 return true; 1414 } 1415 1416 bool AMDGPUDAGToDAGISel::SelectSMRDImm(SDValue Addr, SDValue &SBase, 1417 SDValue &Offset) const { 1418 bool Imm; 1419 return SelectSMRD(Addr, SBase, Offset, Imm) && Imm; 1420 } 1421 1422 bool AMDGPUDAGToDAGISel::SelectSMRDImm32(SDValue Addr, SDValue &SBase, 1423 SDValue &Offset) const { 1424 1425 if (Subtarget->getGeneration() != AMDGPUSubtarget::SEA_ISLANDS) 1426 return false; 1427 1428 bool Imm; 1429 if (!SelectSMRD(Addr, SBase, Offset, Imm)) 1430 return false; 1431 1432 return !Imm && isa<ConstantSDNode>(Offset); 1433 } 1434 1435 bool AMDGPUDAGToDAGISel::SelectSMRDSgpr(SDValue Addr, SDValue &SBase, 1436 SDValue &Offset) const { 1437 bool Imm; 1438 return SelectSMRD(Addr, SBase, Offset, Imm) && !Imm && 1439 !isa<ConstantSDNode>(Offset); 1440 } 1441 1442 bool AMDGPUDAGToDAGISel::SelectSMRDBufferImm(SDValue Addr, 1443 SDValue &Offset) const { 1444 bool Imm; 1445 return SelectSMRDOffset(Addr, Offset, Imm) && Imm; 1446 } 1447 1448 bool AMDGPUDAGToDAGISel::SelectSMRDBufferImm32(SDValue Addr, 1449 SDValue &Offset) const { 1450 if (Subtarget->getGeneration() != AMDGPUSubtarget::SEA_ISLANDS) 1451 return false; 1452 1453 bool Imm; 1454 if (!SelectSMRDOffset(Addr, Offset, Imm)) 1455 return false; 1456 1457 return !Imm && isa<ConstantSDNode>(Offset); 1458 } 1459 1460 bool AMDGPUDAGToDAGISel::SelectSMRDBufferSgpr(SDValue Addr, 1461 SDValue &Offset) const { 1462 bool Imm; 1463 return SelectSMRDOffset(Addr, Offset, Imm) && !Imm && 1464 !isa<ConstantSDNode>(Offset); 1465 } 1466 1467 bool AMDGPUDAGToDAGISel::SelectMOVRELOffset(SDValue Index, 1468 SDValue &Base, 1469 SDValue &Offset) const { 1470 SDLoc DL(Index); 1471 1472 if (CurDAG->isBaseWithConstantOffset(Index)) { 1473 SDValue N0 = Index.getOperand(0); 1474 SDValue N1 = Index.getOperand(1); 1475 ConstantSDNode *C1 = cast<ConstantSDNode>(N1); 1476 1477 // (add n0, c0) 1478 Base = N0; 1479 Offset = CurDAG->getTargetConstant(C1->getZExtValue(), DL, MVT::i32); 1480 return true; 1481 } 1482 1483 if (isa<ConstantSDNode>(Index)) 1484 return false; 1485 1486 Base = Index; 1487 Offset = CurDAG->getTargetConstant(0, DL, MVT::i32); 1488 return true; 1489 } 1490 1491 SDNode *AMDGPUDAGToDAGISel::getS_BFE(unsigned Opcode, const SDLoc &DL, 1492 SDValue Val, uint32_t Offset, 1493 uint32_t Width) { 1494 // Transformation function, pack the offset and width of a BFE into 1495 // the format expected by the S_BFE_I32 / S_BFE_U32. In the second 1496 // source, bits [5:0] contain the offset and bits [22:16] the width. 1497 uint32_t PackedVal = Offset | (Width << 16); 1498 SDValue PackedConst = CurDAG->getTargetConstant(PackedVal, DL, MVT::i32); 1499 1500 return CurDAG->getMachineNode(Opcode, DL, MVT::i32, Val, PackedConst); 1501 } 1502 1503 void AMDGPUDAGToDAGISel::SelectS_BFEFromShifts(SDNode *N) { 1504 // "(a << b) srl c)" ---> "BFE_U32 a, (c-b), (32-c) 1505 // "(a << b) sra c)" ---> "BFE_I32 a, (c-b), (32-c) 1506 // Predicate: 0 < b <= c < 32 1507 1508 const SDValue &Shl = N->getOperand(0); 1509 ConstantSDNode *B = dyn_cast<ConstantSDNode>(Shl->getOperand(1)); 1510 ConstantSDNode *C = dyn_cast<ConstantSDNode>(N->getOperand(1)); 1511 1512 if (B && C) { 1513 uint32_t BVal = B->getZExtValue(); 1514 uint32_t CVal = C->getZExtValue(); 1515 1516 if (0 < BVal && BVal <= CVal && CVal < 32) { 1517 bool Signed = N->getOpcode() == ISD::SRA; 1518 unsigned Opcode = Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32; 1519 1520 ReplaceNode(N, getS_BFE(Opcode, SDLoc(N), Shl.getOperand(0), CVal - BVal, 1521 32 - CVal)); 1522 return; 1523 } 1524 } 1525 SelectCode(N); 1526 } 1527 1528 void AMDGPUDAGToDAGISel::SelectS_BFE(SDNode *N) { 1529 switch (N->getOpcode()) { 1530 case ISD::AND: 1531 if (N->getOperand(0).getOpcode() == ISD::SRL) { 1532 // "(a srl b) & mask" ---> "BFE_U32 a, b, popcount(mask)" 1533 // Predicate: isMask(mask) 1534 const SDValue &Srl = N->getOperand(0); 1535 ConstantSDNode *Shift = dyn_cast<ConstantSDNode>(Srl.getOperand(1)); 1536 ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(N->getOperand(1)); 1537 1538 if (Shift && Mask) { 1539 uint32_t ShiftVal = Shift->getZExtValue(); 1540 uint32_t MaskVal = Mask->getZExtValue(); 1541 1542 if (isMask_32(MaskVal)) { 1543 uint32_t WidthVal = countPopulation(MaskVal); 1544 1545 ReplaceNode(N, getS_BFE(AMDGPU::S_BFE_U32, SDLoc(N), 1546 Srl.getOperand(0), ShiftVal, WidthVal)); 1547 return; 1548 } 1549 } 1550 } 1551 break; 1552 case ISD::SRL: 1553 if (N->getOperand(0).getOpcode() == ISD::AND) { 1554 // "(a & mask) srl b)" ---> "BFE_U32 a, b, popcount(mask >> b)" 1555 // Predicate: isMask(mask >> b) 1556 const SDValue &And = N->getOperand(0); 1557 ConstantSDNode *Shift = dyn_cast<ConstantSDNode>(N->getOperand(1)); 1558 ConstantSDNode *Mask = dyn_cast<ConstantSDNode>(And->getOperand(1)); 1559 1560 if (Shift && Mask) { 1561 uint32_t ShiftVal = Shift->getZExtValue(); 1562 uint32_t MaskVal = Mask->getZExtValue() >> ShiftVal; 1563 1564 if (isMask_32(MaskVal)) { 1565 uint32_t WidthVal = countPopulation(MaskVal); 1566 1567 ReplaceNode(N, getS_BFE(AMDGPU::S_BFE_U32, SDLoc(N), 1568 And.getOperand(0), ShiftVal, WidthVal)); 1569 return; 1570 } 1571 } 1572 } else if (N->getOperand(0).getOpcode() == ISD::SHL) { 1573 SelectS_BFEFromShifts(N); 1574 return; 1575 } 1576 break; 1577 case ISD::SRA: 1578 if (N->getOperand(0).getOpcode() == ISD::SHL) { 1579 SelectS_BFEFromShifts(N); 1580 return; 1581 } 1582 break; 1583 1584 case ISD::SIGN_EXTEND_INREG: { 1585 // sext_inreg (srl x, 16), i8 -> bfe_i32 x, 16, 8 1586 SDValue Src = N->getOperand(0); 1587 if (Src.getOpcode() != ISD::SRL) 1588 break; 1589 1590 const ConstantSDNode *Amt = dyn_cast<ConstantSDNode>(Src.getOperand(1)); 1591 if (!Amt) 1592 break; 1593 1594 unsigned Width = cast<VTSDNode>(N->getOperand(1))->getVT().getSizeInBits(); 1595 ReplaceNode(N, getS_BFE(AMDGPU::S_BFE_I32, SDLoc(N), Src.getOperand(0), 1596 Amt->getZExtValue(), Width)); 1597 return; 1598 } 1599 } 1600 1601 SelectCode(N); 1602 } 1603 1604 bool AMDGPUDAGToDAGISel::isCBranchSCC(const SDNode *N) const { 1605 assert(N->getOpcode() == ISD::BRCOND); 1606 if (!N->hasOneUse()) 1607 return false; 1608 1609 SDValue Cond = N->getOperand(1); 1610 if (Cond.getOpcode() == ISD::CopyToReg) 1611 Cond = Cond.getOperand(2); 1612 1613 if (Cond.getOpcode() != ISD::SETCC || !Cond.hasOneUse()) 1614 return false; 1615 1616 MVT VT = Cond.getOperand(0).getSimpleValueType(); 1617 if (VT == MVT::i32) 1618 return true; 1619 1620 if (VT == MVT::i64) { 1621 auto ST = static_cast<const SISubtarget *>(Subtarget); 1622 1623 ISD::CondCode CC = cast<CondCodeSDNode>(Cond.getOperand(2))->get(); 1624 return (CC == ISD::SETEQ || CC == ISD::SETNE) && ST->hasScalarCompareEq64(); 1625 } 1626 1627 return false; 1628 } 1629 1630 void AMDGPUDAGToDAGISel::SelectBRCOND(SDNode *N) { 1631 SDValue Cond = N->getOperand(1); 1632 1633 if (Cond.isUndef()) { 1634 CurDAG->SelectNodeTo(N, AMDGPU::SI_BR_UNDEF, MVT::Other, 1635 N->getOperand(2), N->getOperand(0)); 1636 return; 1637 } 1638 1639 if (isCBranchSCC(N)) { 1640 // This brcond will use S_CBRANCH_SCC*, so let tablegen handle it. 1641 SelectCode(N); 1642 return; 1643 } 1644 1645 SDLoc SL(N); 1646 1647 SDValue VCC = CurDAG->getCopyToReg(N->getOperand(0), SL, AMDGPU::VCC, Cond); 1648 CurDAG->SelectNodeTo(N, AMDGPU::S_CBRANCH_VCCNZ, MVT::Other, 1649 N->getOperand(2), // Basic Block 1650 VCC.getValue(0)); 1651 } 1652 1653 void AMDGPUDAGToDAGISel::SelectFMAD(SDNode *N) { 1654 MVT VT = N->getSimpleValueType(0); 1655 if (VT != MVT::f32 || !Subtarget->hasMadMixInsts()) { 1656 SelectCode(N); 1657 return; 1658 } 1659 1660 SDValue Src0 = N->getOperand(0); 1661 SDValue Src1 = N->getOperand(1); 1662 SDValue Src2 = N->getOperand(2); 1663 unsigned Src0Mods, Src1Mods, Src2Mods; 1664 1665 // Avoid using v_mad_mix_f32 unless there is actually an operand using the 1666 // conversion from f16. 1667 bool Sel0 = SelectVOP3PMadMixModsImpl(Src0, Src0, Src0Mods); 1668 bool Sel1 = SelectVOP3PMadMixModsImpl(Src1, Src1, Src1Mods); 1669 bool Sel2 = SelectVOP3PMadMixModsImpl(Src2, Src2, Src2Mods); 1670 1671 assert(!Subtarget->hasFP32Denormals() && 1672 "fmad selected with denormals enabled"); 1673 // TODO: We can select this with f32 denormals enabled if all the sources are 1674 // converted from f16 (in which case fmad isn't legal). 1675 1676 if (Sel0 || Sel1 || Sel2) { 1677 // For dummy operands. 1678 SDValue Zero = CurDAG->getTargetConstant(0, SDLoc(), MVT::i32); 1679 SDValue Ops[] = { 1680 CurDAG->getTargetConstant(Src0Mods, SDLoc(), MVT::i32), Src0, 1681 CurDAG->getTargetConstant(Src1Mods, SDLoc(), MVT::i32), Src1, 1682 CurDAG->getTargetConstant(Src2Mods, SDLoc(), MVT::i32), Src2, 1683 CurDAG->getTargetConstant(0, SDLoc(), MVT::i1), 1684 Zero, Zero 1685 }; 1686 1687 CurDAG->SelectNodeTo(N, AMDGPU::V_MAD_MIX_F32, MVT::f32, Ops); 1688 } else { 1689 SelectCode(N); 1690 } 1691 } 1692 1693 // This is here because there isn't a way to use the generated sub0_sub1 as the 1694 // subreg index to EXTRACT_SUBREG in tablegen. 1695 void AMDGPUDAGToDAGISel::SelectATOMIC_CMP_SWAP(SDNode *N) { 1696 MemSDNode *Mem = cast<MemSDNode>(N); 1697 unsigned AS = Mem->getAddressSpace(); 1698 if (AS == AMDGPUASI.FLAT_ADDRESS) { 1699 SelectCode(N); 1700 return; 1701 } 1702 1703 MVT VT = N->getSimpleValueType(0); 1704 bool Is32 = (VT == MVT::i32); 1705 SDLoc SL(N); 1706 1707 MachineSDNode *CmpSwap = nullptr; 1708 if (Subtarget->hasAddr64()) { 1709 SDValue SRsrc, VAddr, SOffset, Offset, GLC, SLC; 1710 1711 if (SelectMUBUFAddr64(Mem->getBasePtr(), SRsrc, VAddr, SOffset, Offset, SLC)) { 1712 unsigned Opcode = Is32 ? AMDGPU::BUFFER_ATOMIC_CMPSWAP_ADDR64_RTN : 1713 AMDGPU::BUFFER_ATOMIC_CMPSWAP_X2_ADDR64_RTN; 1714 SDValue CmpVal = Mem->getOperand(2); 1715 1716 // XXX - Do we care about glue operands? 1717 1718 SDValue Ops[] = { 1719 CmpVal, VAddr, SRsrc, SOffset, Offset, SLC, Mem->getChain() 1720 }; 1721 1722 CmpSwap = CurDAG->getMachineNode(Opcode, SL, Mem->getVTList(), Ops); 1723 } 1724 } 1725 1726 if (!CmpSwap) { 1727 SDValue SRsrc, SOffset, Offset, SLC; 1728 if (SelectMUBUFOffset(Mem->getBasePtr(), SRsrc, SOffset, Offset, SLC)) { 1729 unsigned Opcode = Is32 ? AMDGPU::BUFFER_ATOMIC_CMPSWAP_OFFSET_RTN : 1730 AMDGPU::BUFFER_ATOMIC_CMPSWAP_X2_OFFSET_RTN; 1731 1732 SDValue CmpVal = Mem->getOperand(2); 1733 SDValue Ops[] = { 1734 CmpVal, SRsrc, SOffset, Offset, SLC, Mem->getChain() 1735 }; 1736 1737 CmpSwap = CurDAG->getMachineNode(Opcode, SL, Mem->getVTList(), Ops); 1738 } 1739 } 1740 1741 if (!CmpSwap) { 1742 SelectCode(N); 1743 return; 1744 } 1745 1746 MachineSDNode::mmo_iterator MMOs = MF->allocateMemRefsArray(1); 1747 *MMOs = Mem->getMemOperand(); 1748 CmpSwap->setMemRefs(MMOs, MMOs + 1); 1749 1750 unsigned SubReg = Is32 ? AMDGPU::sub0 : AMDGPU::sub0_sub1; 1751 SDValue Extract 1752 = CurDAG->getTargetExtractSubreg(SubReg, SL, VT, SDValue(CmpSwap, 0)); 1753 1754 ReplaceUses(SDValue(N, 0), Extract); 1755 ReplaceUses(SDValue(N, 1), SDValue(CmpSwap, 1)); 1756 CurDAG->RemoveDeadNode(N); 1757 } 1758 1759 bool AMDGPUDAGToDAGISel::SelectVOP3ModsImpl(SDValue In, SDValue &Src, 1760 unsigned &Mods) const { 1761 Mods = 0; 1762 Src = In; 1763 1764 if (Src.getOpcode() == ISD::FNEG) { 1765 Mods |= SISrcMods::NEG; 1766 Src = Src.getOperand(0); 1767 } 1768 1769 if (Src.getOpcode() == ISD::FABS) { 1770 Mods |= SISrcMods::ABS; 1771 Src = Src.getOperand(0); 1772 } 1773 1774 return true; 1775 } 1776 1777 bool AMDGPUDAGToDAGISel::SelectVOP3Mods(SDValue In, SDValue &Src, 1778 SDValue &SrcMods) const { 1779 unsigned Mods; 1780 if (SelectVOP3ModsImpl(In, Src, Mods)) { 1781 SrcMods = CurDAG->getTargetConstant(Mods, SDLoc(In), MVT::i32); 1782 return true; 1783 } 1784 1785 return false; 1786 } 1787 1788 bool AMDGPUDAGToDAGISel::SelectVOP3Mods_NNaN(SDValue In, SDValue &Src, 1789 SDValue &SrcMods) const { 1790 SelectVOP3Mods(In, Src, SrcMods); 1791 return isNoNanSrc(Src); 1792 } 1793 1794 bool AMDGPUDAGToDAGISel::SelectVOP3NoMods(SDValue In, SDValue &Src) const { 1795 if (In.getOpcode() == ISD::FABS || In.getOpcode() == ISD::FNEG) 1796 return false; 1797 1798 Src = In; 1799 return true; 1800 } 1801 1802 bool AMDGPUDAGToDAGISel::SelectVOP3Mods0(SDValue In, SDValue &Src, 1803 SDValue &SrcMods, SDValue &Clamp, 1804 SDValue &Omod) const { 1805 SDLoc DL(In); 1806 Clamp = CurDAG->getTargetConstant(0, DL, MVT::i1); 1807 Omod = CurDAG->getTargetConstant(0, DL, MVT::i1); 1808 1809 return SelectVOP3Mods(In, Src, SrcMods); 1810 } 1811 1812 bool AMDGPUDAGToDAGISel::SelectVOP3Mods0Clamp0OMod(SDValue In, SDValue &Src, 1813 SDValue &SrcMods, 1814 SDValue &Clamp, 1815 SDValue &Omod) const { 1816 Clamp = Omod = CurDAG->getTargetConstant(0, SDLoc(In), MVT::i32); 1817 return SelectVOP3Mods(In, Src, SrcMods); 1818 } 1819 1820 bool AMDGPUDAGToDAGISel::SelectVOP3OMods(SDValue In, SDValue &Src, 1821 SDValue &Clamp, SDValue &Omod) const { 1822 Src = In; 1823 1824 SDLoc DL(In); 1825 Clamp = CurDAG->getTargetConstant(0, DL, MVT::i1); 1826 Omod = CurDAG->getTargetConstant(0, DL, MVT::i1); 1827 1828 return true; 1829 } 1830 1831 static SDValue stripBitcast(SDValue Val) { 1832 return Val.getOpcode() == ISD::BITCAST ? Val.getOperand(0) : Val; 1833 } 1834 1835 // Figure out if this is really an extract of the high 16-bits of a dword. 1836 static bool isExtractHiElt(SDValue In, SDValue &Out) { 1837 In = stripBitcast(In); 1838 if (In.getOpcode() != ISD::TRUNCATE) 1839 return false; 1840 1841 SDValue Srl = In.getOperand(0); 1842 if (Srl.getOpcode() == ISD::SRL) { 1843 if (ConstantSDNode *ShiftAmt = dyn_cast<ConstantSDNode>(Srl.getOperand(1))) { 1844 if (ShiftAmt->getZExtValue() == 16) { 1845 Out = stripBitcast(Srl.getOperand(0)); 1846 return true; 1847 } 1848 } 1849 } 1850 1851 return false; 1852 } 1853 1854 // Look through operations that obscure just looking at the low 16-bits of the 1855 // same register. 1856 static SDValue stripExtractLoElt(SDValue In) { 1857 if (In.getOpcode() == ISD::TRUNCATE) { 1858 SDValue Src = In.getOperand(0); 1859 if (Src.getValueType().getSizeInBits() == 32) 1860 return stripBitcast(Src); 1861 } 1862 1863 return In; 1864 } 1865 1866 bool AMDGPUDAGToDAGISel::SelectVOP3PMods(SDValue In, SDValue &Src, 1867 SDValue &SrcMods) const { 1868 unsigned Mods = 0; 1869 Src = In; 1870 1871 if (Src.getOpcode() == ISD::FNEG) { 1872 Mods ^= (SISrcMods::NEG | SISrcMods::NEG_HI); 1873 Src = Src.getOperand(0); 1874 } 1875 1876 if (Src.getOpcode() == ISD::BUILD_VECTOR) { 1877 unsigned VecMods = Mods; 1878 1879 SDValue Lo = stripBitcast(Src.getOperand(0)); 1880 SDValue Hi = stripBitcast(Src.getOperand(1)); 1881 1882 if (Lo.getOpcode() == ISD::FNEG) { 1883 Lo = stripBitcast(Lo.getOperand(0)); 1884 Mods ^= SISrcMods::NEG; 1885 } 1886 1887 if (Hi.getOpcode() == ISD::FNEG) { 1888 Hi = stripBitcast(Hi.getOperand(0)); 1889 Mods ^= SISrcMods::NEG_HI; 1890 } 1891 1892 if (isExtractHiElt(Lo, Lo)) 1893 Mods |= SISrcMods::OP_SEL_0; 1894 1895 if (isExtractHiElt(Hi, Hi)) 1896 Mods |= SISrcMods::OP_SEL_1; 1897 1898 Lo = stripExtractLoElt(Lo); 1899 Hi = stripExtractLoElt(Hi); 1900 1901 if (Lo == Hi && !isInlineImmediate(Lo.getNode())) { 1902 // Really a scalar input. Just select from the low half of the register to 1903 // avoid packing. 1904 1905 Src = Lo; 1906 SrcMods = CurDAG->getTargetConstant(Mods, SDLoc(In), MVT::i32); 1907 return true; 1908 } 1909 1910 Mods = VecMods; 1911 } 1912 1913 // Packed instructions do not have abs modifiers. 1914 Mods |= SISrcMods::OP_SEL_1; 1915 1916 SrcMods = CurDAG->getTargetConstant(Mods, SDLoc(In), MVT::i32); 1917 return true; 1918 } 1919 1920 bool AMDGPUDAGToDAGISel::SelectVOP3PMods0(SDValue In, SDValue &Src, 1921 SDValue &SrcMods, 1922 SDValue &Clamp) const { 1923 SDLoc SL(In); 1924 1925 // FIXME: Handle clamp and op_sel 1926 Clamp = CurDAG->getTargetConstant(0, SL, MVT::i32); 1927 1928 return SelectVOP3PMods(In, Src, SrcMods); 1929 } 1930 1931 bool AMDGPUDAGToDAGISel::SelectVOP3OpSel(SDValue In, SDValue &Src, 1932 SDValue &SrcMods) const { 1933 Src = In; 1934 // FIXME: Handle op_sel 1935 SrcMods = CurDAG->getTargetConstant(0, SDLoc(In), MVT::i32); 1936 return true; 1937 } 1938 1939 bool AMDGPUDAGToDAGISel::SelectVOP3OpSel0(SDValue In, SDValue &Src, 1940 SDValue &SrcMods, 1941 SDValue &Clamp) const { 1942 SDLoc SL(In); 1943 1944 // FIXME: Handle clamp 1945 Clamp = CurDAG->getTargetConstant(0, SL, MVT::i32); 1946 1947 return SelectVOP3OpSel(In, Src, SrcMods); 1948 } 1949 1950 bool AMDGPUDAGToDAGISel::SelectVOP3OpSelMods(SDValue In, SDValue &Src, 1951 SDValue &SrcMods) const { 1952 // FIXME: Handle op_sel 1953 return SelectVOP3Mods(In, Src, SrcMods); 1954 } 1955 1956 bool AMDGPUDAGToDAGISel::SelectVOP3OpSelMods0(SDValue In, SDValue &Src, 1957 SDValue &SrcMods, 1958 SDValue &Clamp) const { 1959 SDLoc SL(In); 1960 1961 // FIXME: Handle clamp 1962 Clamp = CurDAG->getTargetConstant(0, SL, MVT::i32); 1963 1964 return SelectVOP3OpSelMods(In, Src, SrcMods); 1965 } 1966 1967 // The return value is not whether the match is possible (which it always is), 1968 // but whether or not it a conversion is really used. 1969 bool AMDGPUDAGToDAGISel::SelectVOP3PMadMixModsImpl(SDValue In, SDValue &Src, 1970 unsigned &Mods) const { 1971 Mods = 0; 1972 SelectVOP3ModsImpl(In, Src, Mods); 1973 1974 if (Src.getOpcode() == ISD::FP_EXTEND) { 1975 Src = Src.getOperand(0); 1976 assert(Src.getValueType() == MVT::f16); 1977 Src = stripBitcast(Src); 1978 1979 // op_sel/op_sel_hi decide the source type and source. 1980 // If the source's op_sel_hi is set, it indicates to do a conversion from fp16. 1981 // If the sources's op_sel is set, it picks the high half of the source 1982 // register. 1983 1984 Mods |= SISrcMods::OP_SEL_1; 1985 if (isExtractHiElt(Src, Src)) 1986 Mods |= SISrcMods::OP_SEL_0; 1987 1988 return true; 1989 } 1990 1991 return false; 1992 } 1993 1994 bool AMDGPUDAGToDAGISel::SelectVOP3PMadMixMods(SDValue In, SDValue &Src, 1995 SDValue &SrcMods) const { 1996 unsigned Mods = 0; 1997 SelectVOP3PMadMixModsImpl(In, Src, Mods); 1998 SrcMods = CurDAG->getTargetConstant(Mods, SDLoc(In), MVT::i32); 1999 return true; 2000 } 2001 2002 void AMDGPUDAGToDAGISel::PostprocessISelDAG() { 2003 const AMDGPUTargetLowering& Lowering = 2004 *static_cast<const AMDGPUTargetLowering*>(getTargetLowering()); 2005 bool IsModified = false; 2006 do { 2007 IsModified = false; 2008 // Go over all selected nodes and try to fold them a bit more 2009 for (SDNode &Node : CurDAG->allnodes()) { 2010 MachineSDNode *MachineNode = dyn_cast<MachineSDNode>(&Node); 2011 if (!MachineNode) 2012 continue; 2013 2014 SDNode *ResNode = Lowering.PostISelFolding(MachineNode, *CurDAG); 2015 if (ResNode != &Node) { 2016 ReplaceUses(&Node, ResNode); 2017 IsModified = true; 2018 } 2019 } 2020 CurDAG->RemoveDeadNodes(); 2021 } while (IsModified); 2022 } 2023 2024 void R600DAGToDAGISel::Select(SDNode *N) { 2025 unsigned int Opc = N->getOpcode(); 2026 if (N->isMachineOpcode()) { 2027 N->setNodeId(-1); 2028 return; // Already selected. 2029 } 2030 2031 switch (Opc) { 2032 default: break; 2033 case AMDGPUISD::BUILD_VERTICAL_VECTOR: 2034 case ISD::SCALAR_TO_VECTOR: 2035 case ISD::BUILD_VECTOR: { 2036 EVT VT = N->getValueType(0); 2037 unsigned NumVectorElts = VT.getVectorNumElements(); 2038 unsigned RegClassID; 2039 // BUILD_VECTOR was lowered into an IMPLICIT_DEF + 4 INSERT_SUBREG 2040 // that adds a 128 bits reg copy when going through TwoAddressInstructions 2041 // pass. We want to avoid 128 bits copies as much as possible because they 2042 // can't be bundled by our scheduler. 2043 switch(NumVectorElts) { 2044 case 2: RegClassID = AMDGPU::R600_Reg64RegClassID; break; 2045 case 4: 2046 if (Opc == AMDGPUISD::BUILD_VERTICAL_VECTOR) 2047 RegClassID = AMDGPU::R600_Reg128VerticalRegClassID; 2048 else 2049 RegClassID = AMDGPU::R600_Reg128RegClassID; 2050 break; 2051 default: llvm_unreachable("Do not know how to lower this BUILD_VECTOR"); 2052 } 2053 SelectBuildVector(N, RegClassID); 2054 return; 2055 } 2056 } 2057 2058 SelectCode(N); 2059 } 2060 2061 bool R600DAGToDAGISel::SelectADDRIndirect(SDValue Addr, SDValue &Base, 2062 SDValue &Offset) { 2063 ConstantSDNode *C; 2064 SDLoc DL(Addr); 2065 2066 if ((C = dyn_cast<ConstantSDNode>(Addr))) { 2067 Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32); 2068 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32); 2069 } else if ((Addr.getOpcode() == AMDGPUISD::DWORDADDR) && 2070 (C = dyn_cast<ConstantSDNode>(Addr.getOperand(0)))) { 2071 Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32); 2072 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32); 2073 } else if ((Addr.getOpcode() == ISD::ADD || Addr.getOpcode() == ISD::OR) && 2074 (C = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))) { 2075 Base = Addr.getOperand(0); 2076 Offset = CurDAG->getTargetConstant(C->getZExtValue(), DL, MVT::i32); 2077 } else { 2078 Base = Addr; 2079 Offset = CurDAG->getTargetConstant(0, DL, MVT::i32); 2080 } 2081 2082 return true; 2083 } 2084 2085 bool R600DAGToDAGISel::SelectADDRVTX_READ(SDValue Addr, SDValue &Base, 2086 SDValue &Offset) { 2087 ConstantSDNode *IMMOffset; 2088 2089 if (Addr.getOpcode() == ISD::ADD 2090 && (IMMOffset = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) 2091 && isInt<16>(IMMOffset->getZExtValue())) { 2092 2093 Base = Addr.getOperand(0); 2094 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), SDLoc(Addr), 2095 MVT::i32); 2096 return true; 2097 // If the pointer address is constant, we can move it to the offset field. 2098 } else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr)) 2099 && isInt<16>(IMMOffset->getZExtValue())) { 2100 Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), 2101 SDLoc(CurDAG->getEntryNode()), 2102 AMDGPU::ZERO, MVT::i32); 2103 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(), SDLoc(Addr), 2104 MVT::i32); 2105 return true; 2106 } 2107 2108 // Default case, no offset 2109 Base = Addr; 2110 Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32); 2111 return true; 2112 } 2113