1 //===- AMDGPURegisterBankInfo.cpp -------------------------------*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements the targeting of the RegisterBankInfo class for 10 /// AMDGPU. 11 /// 12 /// \par 13 /// 14 /// AMDGPU has unique register bank constraints that require special high level 15 /// strategies to deal with. There are two main true physical register banks 16 /// VGPR (vector), and SGPR (scalar). Additionally the VCC register bank is a 17 /// sort of pseudo-register bank needed to represent SGPRs used in a vector 18 /// boolean context. There is also the AGPR bank, which is a special purpose 19 /// physical register bank present on some subtargets. 20 /// 21 /// Copying from VGPR to SGPR is generally illegal, unless the value is known to 22 /// be uniform. It is generally not valid to legalize operands by inserting 23 /// copies as on other targets. Operations which require uniform, SGPR operands 24 /// generally require scalarization by repeatedly executing the instruction, 25 /// activating each set of lanes using a unique set of input values. This is 26 /// referred to as a waterfall loop. 27 /// 28 /// \par Booleans 29 /// 30 /// Booleans (s1 values) requires special consideration. A vector compare result 31 /// is naturally a bitmask with one bit per lane, in a 32 or 64-bit 32 /// register. These are represented with the VCC bank. During selection, we need 33 /// to be able to unambiguously go back from a register class to a register 34 /// bank. To distinguish whether an SGPR should use the SGPR or VCC register 35 /// bank, we need to know the use context type. An SGPR s1 value always means a 36 /// VCC bank value, otherwise it will be the SGPR bank. A scalar compare sets 37 /// SCC, which is a 1-bit unaddressable register. This will need to be copied to 38 /// a 32-bit virtual register. Taken together, this means we need to adjust the 39 /// type of boolean operations to be regbank legal. All SALU booleans need to be 40 /// widened to 32-bits, and all VALU booleans need to be s1 values. 41 /// 42 /// A noteworthy exception to the s1-means-vcc rule is for legalization artifact 43 /// casts. G_TRUNC s1 results, and G_SEXT/G_ZEXT/G_ANYEXT sources are never vcc 44 /// bank. A non-boolean source (such as a truncate from a 1-bit load from 45 /// memory) will require a copy to the VCC bank which will require clearing the 46 /// high bits and inserting a compare. 47 /// 48 /// \par Constant bus restriction 49 /// 50 /// VALU instructions have a limitation known as the constant bus 51 /// restriction. Most VALU instructions can use SGPR operands, but may read at 52 /// most 1 SGPR or constant literal value (this to 2 in gfx10 for most 53 /// instructions). This is one unique SGPR, so the same SGPR may be used for 54 /// multiple operands. From a register bank perspective, any combination of 55 /// operands should be legal as an SGPR, but this is contextually dependent on 56 /// the SGPR operands all being the same register. There is therefore optimal to 57 /// choose the SGPR with the most uses to minimize the number of copies. 58 /// 59 /// We avoid trying to solve this problem in RegBankSelect. Any VALU G_* 60 /// operation should have its source operands all mapped to VGPRs (except for 61 /// VCC), inserting copies from any SGPR operands. This the most trival legal 62 /// mapping. Anything beyond the simplest 1:1 instruction selection would be too 63 /// complicated to solve here. Every optimization pattern or instruction 64 /// selected to multiple outputs would have to enforce this rule, and there 65 /// would be additional complexity in tracking this rule for every G_* 66 /// operation. By forcing all inputs to VGPRs, it also simplifies the task of 67 /// picking the optimal operand combination from a post-isel optimization pass. 68 /// 69 //===----------------------------------------------------------------------===// 70 71 #include "AMDGPURegisterBankInfo.h" 72 73 #include "AMDGPUGlobalISelUtils.h" 74 #include "AMDGPUInstrInfo.h" 75 #include "AMDGPUSubtarget.h" 76 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 77 #include "SIMachineFunctionInfo.h" 78 #include "SIRegisterInfo.h" 79 #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h" 80 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 81 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 82 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 83 #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 84 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 85 #include "llvm/CodeGen/TargetRegisterInfo.h" 86 #include "llvm/CodeGen/TargetSubtargetInfo.h" 87 #include "llvm/IR/Constants.h" 88 89 #define GET_TARGET_REGBANK_IMPL 90 #include "AMDGPUGenRegisterBank.inc" 91 92 // This file will be TableGen'ed at some point. 93 #include "AMDGPUGenRegisterBankInfo.def" 94 95 using namespace llvm; 96 using namespace MIPatternMatch; 97 98 namespace { 99 100 // Observer to apply a register bank to new registers created by LegalizerHelper. 101 class ApplyRegBankMapping final : public GISelChangeObserver { 102 private: 103 const AMDGPURegisterBankInfo &RBI; 104 MachineRegisterInfo &MRI; 105 const RegisterBank *NewBank; 106 SmallVector<MachineInstr *, 4> NewInsts; 107 108 public: 109 ApplyRegBankMapping(const AMDGPURegisterBankInfo &RBI_, 110 MachineRegisterInfo &MRI_, const RegisterBank *RB) 111 : RBI(RBI_), MRI(MRI_), NewBank(RB) {} 112 113 ~ApplyRegBankMapping() { 114 for (MachineInstr *MI : NewInsts) 115 applyBank(*MI); 116 } 117 118 /// Set any registers that don't have a set register class or bank to SALU. 119 void applyBank(MachineInstr &MI) { 120 const unsigned Opc = MI.getOpcode(); 121 if (Opc == AMDGPU::G_ANYEXT || Opc == AMDGPU::G_ZEXT || 122 Opc == AMDGPU::G_SEXT) { 123 // LegalizerHelper wants to use the basic legalization artifacts when 124 // widening etc. We don't handle selection with vcc in artifact sources, 125 // so we need to use a sslect instead to handle these properly. 126 Register DstReg = MI.getOperand(0).getReg(); 127 Register SrcReg = MI.getOperand(1).getReg(); 128 const RegisterBank *SrcBank = RBI.getRegBank(SrcReg, MRI, *RBI.TRI); 129 if (SrcBank == &AMDGPU::VCCRegBank) { 130 const LLT S32 = LLT::scalar(32); 131 assert(MRI.getType(SrcReg) == LLT::scalar(1)); 132 assert(MRI.getType(DstReg) == S32); 133 assert(NewBank == &AMDGPU::VGPRRegBank); 134 135 // Replace the extension with a select, which really uses the boolean 136 // source. 137 MachineIRBuilder B(MI); 138 auto True = B.buildConstant(S32, Opc == AMDGPU::G_SEXT ? -1 : 1); 139 auto False = B.buildConstant(S32, 0); 140 B.buildSelect(DstReg, SrcReg, True, False); 141 MRI.setRegBank(True.getReg(0), *NewBank); 142 MRI.setRegBank(False.getReg(0), *NewBank); 143 MI.eraseFromParent(); 144 } 145 146 assert(!MRI.getRegClassOrRegBank(DstReg)); 147 MRI.setRegBank(DstReg, *NewBank); 148 return; 149 } 150 151 #ifndef NDEBUG 152 if (Opc == AMDGPU::G_TRUNC) { 153 Register DstReg = MI.getOperand(0).getReg(); 154 const RegisterBank *DstBank = RBI.getRegBank(DstReg, MRI, *RBI.TRI); 155 assert(DstBank != &AMDGPU::VCCRegBank); 156 } 157 #endif 158 159 for (MachineOperand &Op : MI.operands()) { 160 if (!Op.isReg()) 161 continue; 162 163 Register Reg = Op.getReg(); 164 if (MRI.getRegClassOrRegBank(Reg)) 165 continue; 166 167 const RegisterBank *RB = NewBank; 168 if (MRI.getType(Reg) == LLT::scalar(1)) { 169 assert(NewBank == &AMDGPU::VGPRRegBank && 170 "s1 operands should only be used for vector bools"); 171 assert((MI.getOpcode() != AMDGPU::G_TRUNC && 172 MI.getOpcode() != AMDGPU::G_ANYEXT) && 173 "not expecting legalization artifacts here"); 174 RB = &AMDGPU::VCCRegBank; 175 } 176 177 MRI.setRegBank(Reg, *RB); 178 } 179 } 180 181 void erasingInstr(MachineInstr &MI) override {} 182 183 void createdInstr(MachineInstr &MI) override { 184 // At this point, the instruction was just inserted and has no operands. 185 NewInsts.push_back(&MI); 186 } 187 188 void changingInstr(MachineInstr &MI) override {} 189 void changedInstr(MachineInstr &MI) override {} 190 }; 191 192 } 193 AMDGPURegisterBankInfo::AMDGPURegisterBankInfo(const GCNSubtarget &ST) 194 : AMDGPUGenRegisterBankInfo(), 195 Subtarget(ST), 196 TRI(Subtarget.getRegisterInfo()), 197 TII(Subtarget.getInstrInfo()) { 198 199 // HACK: Until this is fully tablegen'd. 200 static bool AlreadyInit = false; 201 if (AlreadyInit) 202 return; 203 204 AlreadyInit = true; 205 206 assert(&getRegBank(AMDGPU::SGPRRegBankID) == &AMDGPU::SGPRRegBank && 207 &getRegBank(AMDGPU::VGPRRegBankID) == &AMDGPU::VGPRRegBank && 208 &getRegBank(AMDGPU::AGPRRegBankID) == &AMDGPU::AGPRRegBank); 209 } 210 211 static bool isVectorRegisterBank(const RegisterBank &Bank) { 212 unsigned BankID = Bank.getID(); 213 return BankID == AMDGPU::VGPRRegBankID || BankID == AMDGPU::AGPRRegBankID; 214 } 215 216 unsigned AMDGPURegisterBankInfo::copyCost(const RegisterBank &Dst, 217 const RegisterBank &Src, 218 unsigned Size) const { 219 // TODO: Should there be a UniformVGPRRegBank which can use readfirstlane? 220 if (Dst.getID() == AMDGPU::SGPRRegBankID && 221 isVectorRegisterBank(Src)) { 222 return std::numeric_limits<unsigned>::max(); 223 } 224 225 // Bool values are tricky, because the meaning is based on context. The SCC 226 // and VCC banks are for the natural scalar and vector conditions produced by 227 // a compare. 228 // 229 // Legalization doesn't know about the necessary context, so an s1 use may 230 // have been a truncate from an arbitrary value, in which case a copy (lowered 231 // as a compare with 0) needs to be inserted. 232 if (Size == 1 && 233 (Dst.getID() == AMDGPU::SGPRRegBankID) && 234 (isVectorRegisterBank(Src) || 235 Src.getID() == AMDGPU::SGPRRegBankID || 236 Src.getID() == AMDGPU::VCCRegBankID)) 237 return std::numeric_limits<unsigned>::max(); 238 239 if (Src.getID() == AMDGPU::VCCRegBankID) 240 return std::numeric_limits<unsigned>::max(); 241 242 // There is no direct copy between AGPRs. 243 if (Dst.getID() == AMDGPU::AGPRRegBankID && 244 Src.getID() == AMDGPU::AGPRRegBankID) 245 return 4; 246 247 return RegisterBankInfo::copyCost(Dst, Src, Size); 248 } 249 250 unsigned AMDGPURegisterBankInfo::getBreakDownCost( 251 const ValueMapping &ValMapping, 252 const RegisterBank *CurBank) const { 253 // Check if this is a breakdown for G_LOAD to move the pointer from SGPR to 254 // VGPR. 255 // FIXME: Is there a better way to do this? 256 if (ValMapping.NumBreakDowns >= 2 || ValMapping.BreakDown[0].Length >= 64) 257 return 10; // This is expensive. 258 259 assert(ValMapping.NumBreakDowns == 2 && 260 ValMapping.BreakDown[0].Length == 32 && 261 ValMapping.BreakDown[0].StartIdx == 0 && 262 ValMapping.BreakDown[1].Length == 32 && 263 ValMapping.BreakDown[1].StartIdx == 32 && 264 ValMapping.BreakDown[0].RegBank == ValMapping.BreakDown[1].RegBank); 265 266 // 32-bit extract of a 64-bit value is just access of a subregister, so free. 267 // TODO: Cost of 0 hits assert, though it's not clear it's what we really 268 // want. 269 270 // TODO: 32-bit insert to a 64-bit SGPR may incur a non-free copy due to SGPR 271 // alignment restrictions, but this probably isn't important. 272 return 1; 273 } 274 275 const RegisterBank & 276 AMDGPURegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, 277 LLT Ty) const { 278 if (&RC == &AMDGPU::SReg_1RegClass) 279 return AMDGPU::VCCRegBank; 280 281 // We promote real scalar booleans to SReg_32. Any SGPR using s1 is really a 282 // VCC-like use. 283 if (TRI->isSGPRClass(&RC)) { 284 // FIXME: This probably came from a copy from a physical register, which 285 // should be inferrrable from the copied to-type. We don't have many boolean 286 // physical register constraints so just assume a normal SGPR for now. 287 if (!Ty.isValid()) 288 return AMDGPU::SGPRRegBank; 289 290 return Ty == LLT::scalar(1) ? AMDGPU::VCCRegBank : AMDGPU::SGPRRegBank; 291 } 292 293 return TRI->isAGPRClass(&RC) ? AMDGPU::AGPRRegBank : AMDGPU::VGPRRegBank; 294 } 295 296 template <unsigned NumOps> 297 RegisterBankInfo::InstructionMappings 298 AMDGPURegisterBankInfo::addMappingFromTable( 299 const MachineInstr &MI, const MachineRegisterInfo &MRI, 300 const std::array<unsigned, NumOps> RegSrcOpIdx, 301 ArrayRef<OpRegBankEntry<NumOps>> Table) const { 302 303 InstructionMappings AltMappings; 304 305 SmallVector<const ValueMapping *, 10> Operands(MI.getNumOperands()); 306 307 unsigned Sizes[NumOps]; 308 for (unsigned I = 0; I < NumOps; ++I) { 309 Register Reg = MI.getOperand(RegSrcOpIdx[I]).getReg(); 310 Sizes[I] = getSizeInBits(Reg, MRI, *TRI); 311 } 312 313 for (unsigned I = 0, E = MI.getNumExplicitDefs(); I != E; ++I) { 314 unsigned SizeI = getSizeInBits(MI.getOperand(I).getReg(), MRI, *TRI); 315 Operands[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SizeI); 316 } 317 318 // getInstrMapping's default mapping uses ID 1, so start at 2. 319 unsigned MappingID = 2; 320 for (const auto &Entry : Table) { 321 for (unsigned I = 0; I < NumOps; ++I) { 322 int OpIdx = RegSrcOpIdx[I]; 323 Operands[OpIdx] = AMDGPU::getValueMapping(Entry.RegBanks[I], Sizes[I]); 324 } 325 326 AltMappings.push_back(&getInstructionMapping(MappingID++, Entry.Cost, 327 getOperandsMapping(Operands), 328 Operands.size())); 329 } 330 331 return AltMappings; 332 } 333 334 RegisterBankInfo::InstructionMappings 335 AMDGPURegisterBankInfo::getInstrAlternativeMappingsIntrinsic( 336 const MachineInstr &MI, const MachineRegisterInfo &MRI) const { 337 switch (MI.getIntrinsicID()) { 338 case Intrinsic::amdgcn_readlane: { 339 static const OpRegBankEntry<3> Table[2] = { 340 // Perfectly legal. 341 { { AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID }, 1 }, 342 343 // Need a readfirstlane for the index. 344 { { AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 2 } 345 }; 346 347 const std::array<unsigned, 3> RegSrcOpIdx = { { 0, 2, 3 } }; 348 return addMappingFromTable<3>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 349 } 350 case Intrinsic::amdgcn_writelane: { 351 static const OpRegBankEntry<4> Table[4] = { 352 // Perfectly legal. 353 { { AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID }, 1 }, 354 355 // Need readfirstlane of first op 356 { { AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID }, 2 }, 357 358 // Need readfirstlane of second op 359 { { AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 2 }, 360 361 // Need readfirstlane of both ops 362 { { AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 3 } 363 }; 364 365 // rsrc, voffset, offset 366 const std::array<unsigned, 4> RegSrcOpIdx = { { 0, 2, 3, 4 } }; 367 return addMappingFromTable<4>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 368 } 369 default: 370 return RegisterBankInfo::getInstrAlternativeMappings(MI); 371 } 372 } 373 374 RegisterBankInfo::InstructionMappings 375 AMDGPURegisterBankInfo::getInstrAlternativeMappingsIntrinsicWSideEffects( 376 const MachineInstr &MI, const MachineRegisterInfo &MRI) const { 377 378 switch (MI.getIntrinsicID()) { 379 case Intrinsic::amdgcn_s_buffer_load: { 380 static const OpRegBankEntry<2> Table[4] = { 381 // Perfectly legal. 382 { { AMDGPU::SGPRRegBankID, AMDGPU::SGPRRegBankID }, 1 }, 383 384 // Only need 1 register in loop 385 { { AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID }, 300 }, 386 387 // Have to waterfall the resource. 388 { { AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID }, 1000 }, 389 390 // Have to waterfall the resource, and the offset. 391 { { AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 1500 } 392 }; 393 394 // rsrc, offset 395 const std::array<unsigned, 2> RegSrcOpIdx = { { 2, 3 } }; 396 return addMappingFromTable<2>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 397 } 398 case Intrinsic::amdgcn_ds_ordered_add: 399 case Intrinsic::amdgcn_ds_ordered_swap: { 400 // VGPR = M0, VGPR 401 static const OpRegBankEntry<3> Table[2] = { 402 // Perfectly legal. 403 { { AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID }, 1 }, 404 405 // Need a readfirstlane for m0 406 { { AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 2 } 407 }; 408 409 const std::array<unsigned, 3> RegSrcOpIdx = { { 0, 2, 3 } }; 410 return addMappingFromTable<3>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 411 } 412 case Intrinsic::amdgcn_s_sendmsg: 413 case Intrinsic::amdgcn_s_sendmsghalt: { 414 // FIXME: Should have no register for immediate 415 static const OpRegBankEntry<1> Table[2] = { 416 // Perfectly legal. 417 { { AMDGPU::SGPRRegBankID }, 1 }, 418 419 // Need readlane 420 { { AMDGPU::VGPRRegBankID }, 3 } 421 }; 422 423 const std::array<unsigned, 1> RegSrcOpIdx = { { 2 } }; 424 return addMappingFromTable<1>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 425 } 426 default: 427 return RegisterBankInfo::getInstrAlternativeMappings(MI); 428 } 429 } 430 431 static bool memOpHasNoClobbered(const MachineMemOperand *MMO) { 432 const Instruction *I = dyn_cast_or_null<Instruction>(MMO->getValue()); 433 return I && I->getMetadata("amdgpu.noclobber"); 434 } 435 436 // FIXME: Returns uniform if there's no source value information. This is 437 // probably wrong. 438 static bool isScalarLoadLegal(const MachineInstr &MI) { 439 if (!MI.hasOneMemOperand()) 440 return false; 441 442 const MachineMemOperand *MMO = *MI.memoperands_begin(); 443 const unsigned AS = MMO->getAddrSpace(); 444 const bool IsConst = AS == AMDGPUAS::CONSTANT_ADDRESS || 445 AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT; 446 447 // There are no extending SMRD/SMEM loads, and they require 4-byte alignment. 448 return MMO->getSize() >= 4 && MMO->getAlignment() >= 4 && 449 // Can't do a scalar atomic load. 450 !MMO->isAtomic() && 451 // Don't use scalar loads for volatile accesses to non-constant address 452 // spaces. 453 (IsConst || !MMO->isVolatile()) && 454 // Memory must be known constant, or not written before this load. 455 (IsConst || MMO->isInvariant() || memOpHasNoClobbered(MMO)) && 456 AMDGPUInstrInfo::isUniformMMO(MMO); 457 } 458 459 RegisterBankInfo::InstructionMappings 460 AMDGPURegisterBankInfo::getInstrAlternativeMappings( 461 const MachineInstr &MI) const { 462 463 const MachineFunction &MF = *MI.getParent()->getParent(); 464 const MachineRegisterInfo &MRI = MF.getRegInfo(); 465 466 467 InstructionMappings AltMappings; 468 switch (MI.getOpcode()) { 469 case TargetOpcode::G_CONSTANT: { 470 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 471 if (Size == 1) { 472 static const OpRegBankEntry<1> Table[3] = { 473 { { AMDGPU::VGPRRegBankID }, 1 }, 474 { { AMDGPU::SGPRRegBankID }, 1 }, 475 { { AMDGPU::VCCRegBankID }, 1 } 476 }; 477 478 return addMappingFromTable<1>(MI, MRI, {{ 0 }}, Table); 479 } 480 481 LLVM_FALLTHROUGH; 482 } 483 case TargetOpcode::G_FCONSTANT: 484 case TargetOpcode::G_FRAME_INDEX: 485 case TargetOpcode::G_GLOBAL_VALUE: { 486 static const OpRegBankEntry<1> Table[2] = { 487 { { AMDGPU::VGPRRegBankID }, 1 }, 488 { { AMDGPU::SGPRRegBankID }, 1 } 489 }; 490 491 return addMappingFromTable<1>(MI, MRI, {{ 0 }}, Table); 492 } 493 case TargetOpcode::G_AND: 494 case TargetOpcode::G_OR: 495 case TargetOpcode::G_XOR: { 496 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 497 498 if (Size == 1) { 499 // s_{and|or|xor}_b32 set scc when the result of the 32-bit op is not 0. 500 const InstructionMapping &SCCMapping = getInstructionMapping( 501 1, 1, getOperandsMapping( 502 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32), 503 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32), 504 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32)}), 505 3); // Num Operands 506 AltMappings.push_back(&SCCMapping); 507 508 const InstructionMapping &VCCMapping0 = getInstructionMapping( 509 2, 1, getOperandsMapping( 510 {AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Size), 511 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Size), 512 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Size)}), 513 3); // Num Operands 514 AltMappings.push_back(&VCCMapping0); 515 return AltMappings; 516 } 517 518 if (Size != 64) 519 break; 520 521 const InstructionMapping &SSMapping = getInstructionMapping( 522 1, 1, getOperandsMapping( 523 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 524 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 525 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}), 526 3); // Num Operands 527 AltMappings.push_back(&SSMapping); 528 529 const InstructionMapping &VVMapping = getInstructionMapping( 530 2, 2, getOperandsMapping( 531 {AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size), 532 AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size), 533 AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size)}), 534 3); // Num Operands 535 AltMappings.push_back(&VVMapping); 536 break; 537 } 538 case TargetOpcode::G_LOAD: 539 case TargetOpcode::G_ZEXTLOAD: 540 case TargetOpcode::G_SEXTLOAD: { 541 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 542 LLT PtrTy = MRI.getType(MI.getOperand(1).getReg()); 543 unsigned PtrSize = PtrTy.getSizeInBits(); 544 unsigned AS = PtrTy.getAddressSpace(); 545 LLT LoadTy = MRI.getType(MI.getOperand(0).getReg()); 546 547 if ((AS != AMDGPUAS::LOCAL_ADDRESS && AS != AMDGPUAS::REGION_ADDRESS && 548 AS != AMDGPUAS::PRIVATE_ADDRESS) && 549 isScalarLoadLegal(MI)) { 550 const InstructionMapping &SSMapping = getInstructionMapping( 551 1, 1, getOperandsMapping( 552 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 553 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize)}), 554 2); // Num Operands 555 AltMappings.push_back(&SSMapping); 556 } 557 558 const InstructionMapping &VVMapping = getInstructionMapping( 559 2, 1, getOperandsMapping( 560 {AMDGPU::getValueMappingLoadSGPROnly(AMDGPU::VGPRRegBankID, LoadTy), 561 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize)}), 562 2); // Num Operands 563 AltMappings.push_back(&VVMapping); 564 565 // It may be possible to have a vgpr = load sgpr mapping here, because 566 // the mubuf instructions support this kind of load, but probably for only 567 // gfx7 and older. However, the addressing mode matching in the instruction 568 // selector should be able to do a better job of detecting and selecting 569 // these kinds of loads from the vgpr = load vgpr mapping. 570 571 return AltMappings; 572 573 } 574 case TargetOpcode::G_ICMP: { 575 // TODO: Should report 32-bit for scalar output type. 576 unsigned Size = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI); 577 const InstructionMapping &SSMapping = getInstructionMapping(1, 1, 578 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1), 579 nullptr, // Predicate operand. 580 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 581 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}), 582 4); // Num Operands 583 AltMappings.push_back(&SSMapping); 584 585 const InstructionMapping &VVMapping = getInstructionMapping(4, 1, 586 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), 587 nullptr, // Predicate operand. 588 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 589 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size)}), 590 4); // Num Operands 591 AltMappings.push_back(&VVMapping); 592 593 return AltMappings; 594 } 595 case TargetOpcode::G_SELECT: { 596 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 597 const InstructionMapping &SSMapping = getInstructionMapping(1, 1, 598 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 599 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1), 600 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 601 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}), 602 4); // Num Operands 603 AltMappings.push_back(&SSMapping); 604 605 const InstructionMapping &VVMapping = getInstructionMapping(2, 1, 606 getOperandsMapping({AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size), 607 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), 608 AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size), 609 AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size)}), 610 4); // Num Operands 611 AltMappings.push_back(&VVMapping); 612 613 return AltMappings; 614 } 615 case TargetOpcode::G_SMIN: 616 case TargetOpcode::G_SMAX: 617 case TargetOpcode::G_UMIN: 618 case TargetOpcode::G_UMAX: { 619 static const OpRegBankEntry<3> Table[2] = { 620 { { AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 1 }, 621 622 // Scalar requires cmp+select, and extends if 16-bit. 623 // FIXME: Should there be separate costs for 32 and 16-bit 624 { { AMDGPU::SGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::SGPRRegBankID }, 3 } 625 }; 626 627 const std::array<unsigned, 3> RegSrcOpIdx = { { 0, 1, 2 } }; 628 return addMappingFromTable<3>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 629 } 630 case TargetOpcode::G_UADDE: 631 case TargetOpcode::G_USUBE: 632 case TargetOpcode::G_SADDE: 633 case TargetOpcode::G_SSUBE: { 634 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 635 const InstructionMapping &SSMapping = getInstructionMapping(1, 1, 636 getOperandsMapping( 637 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 638 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1), 639 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 640 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 641 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1)}), 642 5); // Num Operands 643 AltMappings.push_back(&SSMapping); 644 645 const InstructionMapping &VVMapping = getInstructionMapping(2, 1, 646 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 647 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), 648 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 649 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 650 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1)}), 651 5); // Num Operands 652 AltMappings.push_back(&VVMapping); 653 return AltMappings; 654 } 655 case AMDGPU::G_BRCOND: { 656 assert(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 1); 657 658 // TODO: Change type to 32 for scalar 659 const InstructionMapping &SMapping = getInstructionMapping( 660 1, 1, getOperandsMapping( 661 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1), nullptr}), 662 2); // Num Operands 663 AltMappings.push_back(&SMapping); 664 665 const InstructionMapping &VMapping = getInstructionMapping( 666 1, 1, getOperandsMapping( 667 {AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), nullptr }), 668 2); // Num Operands 669 AltMappings.push_back(&VMapping); 670 return AltMappings; 671 } 672 case AMDGPU::G_INTRINSIC: 673 return getInstrAlternativeMappingsIntrinsic(MI, MRI); 674 case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: 675 return getInstrAlternativeMappingsIntrinsicWSideEffects(MI, MRI); 676 default: 677 break; 678 } 679 return RegisterBankInfo::getInstrAlternativeMappings(MI); 680 } 681 682 void AMDGPURegisterBankInfo::split64BitValueForMapping( 683 MachineIRBuilder &B, 684 SmallVector<Register, 2> &Regs, 685 LLT HalfTy, 686 Register Reg) const { 687 assert(HalfTy.getSizeInBits() == 32); 688 MachineRegisterInfo *MRI = B.getMRI(); 689 Register LoLHS = MRI->createGenericVirtualRegister(HalfTy); 690 Register HiLHS = MRI->createGenericVirtualRegister(HalfTy); 691 const RegisterBank *Bank = getRegBank(Reg, *MRI, *TRI); 692 MRI->setRegBank(LoLHS, *Bank); 693 MRI->setRegBank(HiLHS, *Bank); 694 695 Regs.push_back(LoLHS); 696 Regs.push_back(HiLHS); 697 698 B.buildInstr(AMDGPU::G_UNMERGE_VALUES) 699 .addDef(LoLHS) 700 .addDef(HiLHS) 701 .addUse(Reg); 702 } 703 704 /// Replace the current type each register in \p Regs has with \p NewTy 705 static void setRegsToType(MachineRegisterInfo &MRI, ArrayRef<Register> Regs, 706 LLT NewTy) { 707 for (Register Reg : Regs) { 708 assert(MRI.getType(Reg).getSizeInBits() == NewTy.getSizeInBits()); 709 MRI.setType(Reg, NewTy); 710 } 711 } 712 713 static LLT getHalfSizedType(LLT Ty) { 714 if (Ty.isVector()) { 715 assert(Ty.getNumElements() % 2 == 0); 716 return LLT::scalarOrVector(Ty.getNumElements() / 2, Ty.getElementType()); 717 } 718 719 assert(Ty.getSizeInBits() % 2 == 0); 720 return LLT::scalar(Ty.getSizeInBits() / 2); 721 } 722 723 /// Legalize instruction \p MI where operands in \p OpIndices must be SGPRs. If 724 /// any of the required SGPR operands are VGPRs, perform a waterfall loop to 725 /// execute the instruction for each unique combination of values in all lanes 726 /// in the wave. The block will be split such that rest of the instructions are 727 /// moved to a new block. 728 /// 729 /// Essentially performs this loop: 730 // 731 /// Save Execution Mask 732 /// For (Lane : Wavefront) { 733 /// Enable Lane, Disable all other lanes 734 /// SGPR = read SGPR value for current lane from VGPR 735 /// VGPRResult[Lane] = use_op SGPR 736 /// } 737 /// Restore Execution Mask 738 /// 739 /// There is additional complexity to try for compare values to identify the 740 /// unique values used. 741 bool AMDGPURegisterBankInfo::executeInWaterfallLoop( 742 MachineIRBuilder &B, 743 iterator_range<MachineBasicBlock::iterator> Range, 744 SmallSet<Register, 4> &SGPROperandRegs, 745 MachineRegisterInfo &MRI) const { 746 SmallVector<Register, 4> ResultRegs; 747 SmallVector<Register, 4> InitResultRegs; 748 SmallVector<Register, 4> PhiRegs; 749 750 MachineBasicBlock &MBB = B.getMBB(); 751 MachineFunction *MF = &B.getMF(); 752 753 const TargetRegisterClass *WaveRC = TRI->getWaveMaskRegClass(); 754 const unsigned WaveAndOpc = Subtarget.isWave32() ? 755 AMDGPU::S_AND_B32 : AMDGPU::S_AND_B64; 756 const unsigned MovTermOpc = Subtarget.isWave32() ? 757 AMDGPU::S_MOV_B32_term : AMDGPU::S_MOV_B64_term; 758 const unsigned XorTermOpc = Subtarget.isWave32() ? 759 AMDGPU::S_XOR_B32_term : AMDGPU::S_XOR_B64_term; 760 const unsigned AndSaveExecOpc = Subtarget.isWave32() ? 761 AMDGPU::S_AND_SAVEEXEC_B32 : AMDGPU::S_AND_SAVEEXEC_B64; 762 const unsigned ExecReg = Subtarget.isWave32() ? 763 AMDGPU::EXEC_LO : AMDGPU::EXEC; 764 765 for (MachineInstr &MI : Range) { 766 for (MachineOperand &Def : MI.defs()) { 767 LLT ResTy = MRI.getType(Def.getReg()); 768 const RegisterBank *DefBank = getRegBank(Def.getReg(), MRI, *TRI); 769 ResultRegs.push_back(Def.getReg()); 770 Register InitReg = B.buildUndef(ResTy).getReg(0); 771 Register PhiReg = MRI.createGenericVirtualRegister(ResTy); 772 InitResultRegs.push_back(InitReg); 773 PhiRegs.push_back(PhiReg); 774 MRI.setRegBank(PhiReg, *DefBank); 775 MRI.setRegBank(InitReg, *DefBank); 776 } 777 } 778 779 Register SaveExecReg = MRI.createVirtualRegister(WaveRC); 780 Register InitSaveExecReg = MRI.createVirtualRegister(WaveRC); 781 782 // Don't bother using generic instructions/registers for the exec mask. 783 B.buildInstr(TargetOpcode::IMPLICIT_DEF) 784 .addDef(InitSaveExecReg); 785 786 Register PhiExec = MRI.createVirtualRegister(WaveRC); 787 Register NewExec = MRI.createVirtualRegister(WaveRC); 788 789 // To insert the loop we need to split the block. Move everything before this 790 // point to a new block, and insert a new empty block before this instruction. 791 MachineBasicBlock *LoopBB = MF->CreateMachineBasicBlock(); 792 MachineBasicBlock *RemainderBB = MF->CreateMachineBasicBlock(); 793 MachineBasicBlock *RestoreExecBB = MF->CreateMachineBasicBlock(); 794 MachineFunction::iterator MBBI(MBB); 795 ++MBBI; 796 MF->insert(MBBI, LoopBB); 797 MF->insert(MBBI, RestoreExecBB); 798 MF->insert(MBBI, RemainderBB); 799 800 LoopBB->addSuccessor(RestoreExecBB); 801 LoopBB->addSuccessor(LoopBB); 802 803 // Move the rest of the block into a new block. 804 RemainderBB->transferSuccessorsAndUpdatePHIs(&MBB); 805 RemainderBB->splice(RemainderBB->begin(), &MBB, Range.end(), MBB.end()); 806 807 MBB.addSuccessor(LoopBB); 808 RestoreExecBB->addSuccessor(RemainderBB); 809 810 B.setInsertPt(*LoopBB, LoopBB->end()); 811 812 B.buildInstr(TargetOpcode::PHI) 813 .addDef(PhiExec) 814 .addReg(InitSaveExecReg) 815 .addMBB(&MBB) 816 .addReg(NewExec) 817 .addMBB(LoopBB); 818 819 for (auto Result : zip(InitResultRegs, ResultRegs, PhiRegs)) { 820 B.buildInstr(TargetOpcode::G_PHI) 821 .addDef(std::get<2>(Result)) 822 .addReg(std::get<0>(Result)) // Initial value / implicit_def 823 .addMBB(&MBB) 824 .addReg(std::get<1>(Result)) // Mid-loop value. 825 .addMBB(LoopBB); 826 } 827 828 const DebugLoc &DL = B.getDL(); 829 830 // Figure out the iterator range after splicing the instructions. 831 auto NewBegin = std::prev(LoopBB->end()); 832 833 // Move the instruction into the loop. Note we moved everything after 834 // Range.end() already into a new block, so Range.end() is no longer valid. 835 LoopBB->splice(LoopBB->end(), &MBB, Range.begin(), MBB.end()); 836 837 auto NewEnd = LoopBB->end(); 838 839 MachineBasicBlock::iterator I = Range.begin(); 840 B.setInsertPt(*LoopBB, I); 841 842 Register CondReg; 843 844 for (MachineInstr &MI : make_range(NewBegin, NewEnd)) { 845 for (MachineOperand &Op : MI.uses()) { 846 if (!Op.isReg() || Op.isDef()) 847 continue; 848 849 if (!SGPROperandRegs.count(Op.getReg())) 850 continue; 851 852 LLT OpTy = MRI.getType(Op.getReg()); 853 unsigned OpSize = OpTy.getSizeInBits(); 854 855 // Can only do a readlane of 32-bit pieces. 856 if (OpSize == 32) { 857 // Avoid extra copies in the simple case of one 32-bit register. 858 Register CurrentLaneOpReg 859 = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass); 860 MRI.setType(CurrentLaneOpReg, OpTy); 861 862 constrainGenericRegister(Op.getReg(), AMDGPU::VGPR_32RegClass, MRI); 863 // Read the next variant <- also loop target. 864 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), 865 CurrentLaneOpReg) 866 .addReg(Op.getReg()); 867 868 Register NewCondReg = MRI.createVirtualRegister(WaveRC); 869 bool First = CondReg == AMDGPU::NoRegister; 870 if (First) 871 CondReg = NewCondReg; 872 873 // Compare the just read M0 value to all possible Idx values. 874 B.buildInstr(AMDGPU::V_CMP_EQ_U32_e64) 875 .addDef(NewCondReg) 876 .addReg(CurrentLaneOpReg) 877 .addReg(Op.getReg()); 878 Op.setReg(CurrentLaneOpReg); 879 880 if (!First) { 881 Register AndReg = MRI.createVirtualRegister(WaveRC); 882 883 // If there are multiple operands to consider, and the conditions. 884 B.buildInstr(WaveAndOpc) 885 .addDef(AndReg) 886 .addReg(NewCondReg) 887 .addReg(CondReg); 888 CondReg = AndReg; 889 } 890 } else { 891 LLT S32 = LLT::scalar(32); 892 SmallVector<Register, 8> ReadlanePieces; 893 894 // The compares can be done as 64-bit, but the extract needs to be done 895 // in 32-bit pieces. 896 897 bool Is64 = OpSize % 64 == 0; 898 899 LLT UnmergeTy = OpSize % 64 == 0 ? LLT::scalar(64) : LLT::scalar(32); 900 unsigned CmpOp = OpSize % 64 == 0 ? AMDGPU::V_CMP_EQ_U64_e64 901 : AMDGPU::V_CMP_EQ_U32_e64; 902 903 // The compares can be done as 64-bit, but the extract needs to be done 904 // in 32-bit pieces. 905 906 // Insert the unmerge before the loop. 907 908 B.setMBB(MBB); 909 auto Unmerge = B.buildUnmerge(UnmergeTy, Op.getReg()); 910 B.setInstr(*I); 911 912 unsigned NumPieces = Unmerge->getNumOperands() - 1; 913 for (unsigned PieceIdx = 0; PieceIdx != NumPieces; ++PieceIdx) { 914 Register UnmergePiece = Unmerge.getReg(PieceIdx); 915 916 Register CurrentLaneOpReg; 917 if (Is64) { 918 Register CurrentLaneOpRegLo = MRI.createGenericVirtualRegister(S32); 919 Register CurrentLaneOpRegHi = MRI.createGenericVirtualRegister(S32); 920 921 MRI.setRegClass(UnmergePiece, &AMDGPU::VReg_64RegClass); 922 MRI.setRegClass(CurrentLaneOpRegLo, &AMDGPU::SReg_32_XM0RegClass); 923 MRI.setRegClass(CurrentLaneOpRegHi, &AMDGPU::SReg_32_XM0RegClass); 924 925 // Read the next variant <- also loop target. 926 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), 927 CurrentLaneOpRegLo) 928 .addReg(UnmergePiece, 0, AMDGPU::sub0); 929 930 // Read the next variant <- also loop target. 931 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), 932 CurrentLaneOpRegHi) 933 .addReg(UnmergePiece, 0, AMDGPU::sub1); 934 935 CurrentLaneOpReg = 936 B.buildMerge(LLT::scalar(64), 937 {CurrentLaneOpRegLo, CurrentLaneOpRegHi}) 938 .getReg(0); 939 940 MRI.setRegClass(CurrentLaneOpReg, &AMDGPU::SReg_64_XEXECRegClass); 941 942 if (OpTy.getScalarSizeInBits() == 64) { 943 // If we need to produce a 64-bit element vector, so use the 944 // merged pieces 945 ReadlanePieces.push_back(CurrentLaneOpReg); 946 } else { 947 // 32-bit element type. 948 ReadlanePieces.push_back(CurrentLaneOpRegLo); 949 ReadlanePieces.push_back(CurrentLaneOpRegHi); 950 } 951 } else { 952 CurrentLaneOpReg = MRI.createGenericVirtualRegister(S32); 953 MRI.setRegClass(UnmergePiece, &AMDGPU::VGPR_32RegClass); 954 MRI.setRegClass(CurrentLaneOpReg, &AMDGPU::SReg_32_XM0RegClass); 955 956 // Read the next variant <- also loop target. 957 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), 958 CurrentLaneOpReg) 959 .addReg(UnmergePiece); 960 ReadlanePieces.push_back(CurrentLaneOpReg); 961 } 962 963 Register NewCondReg = MRI.createVirtualRegister(WaveRC); 964 bool First = CondReg == AMDGPU::NoRegister; 965 if (First) 966 CondReg = NewCondReg; 967 968 B.buildInstr(CmpOp) 969 .addDef(NewCondReg) 970 .addReg(CurrentLaneOpReg) 971 .addReg(UnmergePiece); 972 973 if (!First) { 974 Register AndReg = MRI.createVirtualRegister(WaveRC); 975 976 // If there are multiple operands to consider, and the conditions. 977 B.buildInstr(WaveAndOpc) 978 .addDef(AndReg) 979 .addReg(NewCondReg) 980 .addReg(CondReg); 981 CondReg = AndReg; 982 } 983 } 984 985 // FIXME: Build merge seems to switch to CONCAT_VECTORS but not 986 // BUILD_VECTOR 987 if (OpTy.isVector()) { 988 auto Merge = B.buildBuildVector(OpTy, ReadlanePieces); 989 Op.setReg(Merge.getReg(0)); 990 } else { 991 auto Merge = B.buildMerge(OpTy, ReadlanePieces); 992 Op.setReg(Merge.getReg(0)); 993 } 994 995 MRI.setRegBank(Op.getReg(), AMDGPU::SGPRRegBank); 996 } 997 } 998 } 999 1000 B.setInsertPt(*LoopBB, LoopBB->end()); 1001 1002 // Update EXEC, save the original EXEC value to VCC. 1003 B.buildInstr(AndSaveExecOpc) 1004 .addDef(NewExec) 1005 .addReg(CondReg, RegState::Kill); 1006 1007 MRI.setSimpleHint(NewExec, CondReg); 1008 1009 // Update EXEC, switch all done bits to 0 and all todo bits to 1. 1010 B.buildInstr(XorTermOpc) 1011 .addDef(ExecReg) 1012 .addReg(ExecReg) 1013 .addReg(NewExec); 1014 1015 // XXX - s_xor_b64 sets scc to 1 if the result is nonzero, so can we use 1016 // s_cbranch_scc0? 1017 1018 // Loop back to V_READFIRSTLANE_B32 if there are still variants to cover. 1019 B.buildInstr(AMDGPU::S_CBRANCH_EXECNZ) 1020 .addMBB(LoopBB); 1021 1022 // Save the EXEC mask before the loop. 1023 BuildMI(MBB, MBB.end(), DL, TII->get(MovTermOpc), SaveExecReg) 1024 .addReg(ExecReg); 1025 1026 // Restore the EXEC mask after the loop. 1027 B.setMBB(*RestoreExecBB); 1028 B.buildInstr(MovTermOpc) 1029 .addDef(ExecReg) 1030 .addReg(SaveExecReg); 1031 1032 // Set the insert point after the original instruction, so any new 1033 // instructions will be in the remainder. 1034 B.setInsertPt(*RemainderBB, RemainderBB->begin()); 1035 1036 return true; 1037 } 1038 1039 // Return any unique registers used by \p MI at \p OpIndices that need to be 1040 // handled in a waterfall loop. Returns these registers in \p 1041 // SGPROperandRegs. Returns true if there are any operansd to handle and a 1042 // waterfall loop is necessary. 1043 bool AMDGPURegisterBankInfo::collectWaterfallOperands( 1044 SmallSet<Register, 4> &SGPROperandRegs, MachineInstr &MI, 1045 MachineRegisterInfo &MRI, ArrayRef<unsigned> OpIndices) const { 1046 for (unsigned Op : OpIndices) { 1047 assert(MI.getOperand(Op).isUse()); 1048 Register Reg = MI.getOperand(Op).getReg(); 1049 const RegisterBank *OpBank = getRegBank(Reg, MRI, *TRI); 1050 if (OpBank->getID() == AMDGPU::VGPRRegBankID) 1051 SGPROperandRegs.insert(Reg); 1052 } 1053 1054 // No operands need to be replaced, so no need to loop. 1055 return !SGPROperandRegs.empty(); 1056 } 1057 1058 bool AMDGPURegisterBankInfo::executeInWaterfallLoop( 1059 MachineIRBuilder &B, MachineInstr &MI, MachineRegisterInfo &MRI, 1060 ArrayRef<unsigned> OpIndices) const { 1061 // Use a set to avoid extra readfirstlanes in the case where multiple operands 1062 // are the same register. 1063 SmallSet<Register, 4> SGPROperandRegs; 1064 1065 if (!collectWaterfallOperands(SGPROperandRegs, MI, MRI, OpIndices)) 1066 return false; 1067 1068 MachineBasicBlock::iterator I = MI.getIterator(); 1069 return executeInWaterfallLoop(B, make_range(I, std::next(I)), 1070 SGPROperandRegs, MRI); 1071 } 1072 1073 bool AMDGPURegisterBankInfo::executeInWaterfallLoop( 1074 MachineInstr &MI, MachineRegisterInfo &MRI, 1075 ArrayRef<unsigned> OpIndices) const { 1076 MachineIRBuilder B(MI); 1077 return executeInWaterfallLoop(B, MI, MRI, OpIndices); 1078 } 1079 1080 // Legalize an operand that must be an SGPR by inserting a readfirstlane. 1081 void AMDGPURegisterBankInfo::constrainOpWithReadfirstlane( 1082 MachineInstr &MI, MachineRegisterInfo &MRI, unsigned OpIdx) const { 1083 Register Reg = MI.getOperand(OpIdx).getReg(); 1084 const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI); 1085 if (Bank != &AMDGPU::VGPRRegBank) 1086 return; 1087 1088 MachineIRBuilder B(MI); 1089 Register SGPR = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); 1090 B.buildInstr(AMDGPU::V_READFIRSTLANE_B32) 1091 .addDef(SGPR) 1092 .addReg(Reg); 1093 1094 MRI.setType(SGPR, MRI.getType(Reg)); 1095 1096 const TargetRegisterClass *Constrained = 1097 constrainGenericRegister(Reg, AMDGPU::VGPR_32RegClass, MRI); 1098 (void)Constrained; 1099 assert(Constrained && "Failed to constrain readfirstlane src reg"); 1100 1101 MI.getOperand(OpIdx).setReg(SGPR); 1102 } 1103 1104 // When regbankselect repairs registers, it will insert a repair instruction 1105 // which defines the repaired register. Then it calls applyMapping and expects 1106 // that the targets will either delete or rewrite the originally wrote to the 1107 // repaired registers. Beccause of this, we end up in a situation where 1108 // we have 2 instructions defining the same registers. 1109 static MachineInstr *getOtherVRegDef(const MachineRegisterInfo &MRI, 1110 Register Reg, 1111 const MachineInstr &MI) { 1112 // Is there some way we can assert that there are exactly 2 def instructions? 1113 for (MachineInstr &Other : MRI.def_instructions(Reg)) { 1114 if (&Other != &MI) 1115 return &Other; 1116 } 1117 1118 return nullptr; 1119 } 1120 1121 bool AMDGPURegisterBankInfo::applyMappingWideLoad(MachineInstr &MI, 1122 const AMDGPURegisterBankInfo::OperandsMapper &OpdMapper, 1123 MachineRegisterInfo &MRI) const { 1124 Register DstReg = MI.getOperand(0).getReg(); 1125 const LLT LoadTy = MRI.getType(DstReg); 1126 unsigned LoadSize = LoadTy.getSizeInBits(); 1127 const unsigned MaxNonSmrdLoadSize = 128; 1128 // 128-bit loads are supported for all instruction types. 1129 if (LoadSize <= MaxNonSmrdLoadSize) 1130 return false; 1131 1132 SmallVector<unsigned, 16> DefRegs(OpdMapper.getVRegs(0)); 1133 SmallVector<unsigned, 1> SrcRegs(OpdMapper.getVRegs(1)); 1134 1135 // If the pointer is an SGPR, we have nothing to do. 1136 if (SrcRegs.empty()) { 1137 const RegisterBank *PtrBank = 1138 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 1139 if (PtrBank == &AMDGPU::SGPRRegBank) 1140 return false; 1141 SrcRegs.push_back(MI.getOperand(1).getReg()); 1142 } 1143 1144 assert(LoadSize % MaxNonSmrdLoadSize == 0); 1145 1146 // We want to get the repair instruction now, because it will help us 1147 // determine which instruction the legalizer inserts that will also 1148 // write to DstReg. 1149 MachineInstr *RepairInst = getOtherVRegDef(MRI, DstReg, MI); 1150 1151 // RegBankSelect only emits scalar types, so we need to reset the pointer 1152 // operand to a pointer type. 1153 Register BasePtrReg = SrcRegs[0]; 1154 LLT PtrTy = MRI.getType(MI.getOperand(1).getReg()); 1155 MRI.setType(BasePtrReg, PtrTy); 1156 1157 MachineIRBuilder B(MI); 1158 1159 unsigned SplitElts = 1160 MaxNonSmrdLoadSize / LoadTy.getScalarType().getSizeInBits(); 1161 const LLT LoadSplitTy = LLT::vector(SplitElts, LoadTy.getScalarType()); 1162 ApplyRegBankMapping O(*this, MRI, &AMDGPU::VGPRRegBank); 1163 GISelObserverWrapper Observer(&O); 1164 B.setChangeObserver(Observer); 1165 LegalizerHelper Helper(B.getMF(), Observer, B); 1166 if (Helper.fewerElementsVector(MI, 0, LoadSplitTy) != LegalizerHelper::Legalized) 1167 return false; 1168 1169 // At this point, the legalizer has split the original load into smaller 1170 // loads. At the end of lowering, it inserts an instruction (LegalizedInst) 1171 // that combines the outputs of the lower loads and writes it to DstReg. 1172 // The register bank selector has also added the RepairInst which writes to 1173 // DstReg as well. 1174 1175 MachineInstr *LegalizedInst = getOtherVRegDef(MRI, DstReg, *RepairInst); 1176 1177 // Replace the output of the LegalizedInst with a temporary register, since 1178 // RepairInst already defines DstReg. 1179 Register TmpReg = MRI.createGenericVirtualRegister(MRI.getType(DstReg)); 1180 LegalizedInst->getOperand(0).setReg(TmpReg); 1181 B.setInsertPt(*RepairInst->getParent(), RepairInst); 1182 1183 for (unsigned DefIdx = 0, e = DefRegs.size(); DefIdx != e; ++DefIdx) { 1184 Register IdxReg = B.buildConstant(LLT::scalar(32), DefIdx).getReg(0); 1185 MRI.setRegBank(IdxReg, AMDGPU::VGPRRegBank); 1186 B.buildExtractVectorElement(DefRegs[DefIdx], TmpReg, IdxReg); 1187 } 1188 1189 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 1190 return true; 1191 } 1192 1193 bool AMDGPURegisterBankInfo::applyMappingImage( 1194 MachineInstr &MI, const AMDGPURegisterBankInfo::OperandsMapper &OpdMapper, 1195 MachineRegisterInfo &MRI, int RsrcIdx) const { 1196 const int NumDefs = MI.getNumExplicitDefs(); 1197 1198 // The reported argument index is relative to the IR intrinsic call arguments, 1199 // so we need to shift by the number of defs and the intrinsic ID. 1200 RsrcIdx += NumDefs + 1; 1201 1202 // Insert copies to VGPR arguments. 1203 applyDefaultMapping(OpdMapper); 1204 1205 // Fixup any SGPR arguments. 1206 SmallVector<unsigned, 4> SGPRIndexes; 1207 for (int I = NumDefs, NumOps = MI.getNumOperands(); I != NumOps; ++I) { 1208 if (!MI.getOperand(I).isReg()) 1209 continue; 1210 1211 // If this intrinsic has a sampler, it immediately follows rsrc. 1212 if (I == RsrcIdx || I == RsrcIdx + 1) 1213 SGPRIndexes.push_back(I); 1214 } 1215 1216 executeInWaterfallLoop(MI, MRI, SGPRIndexes); 1217 return true; 1218 } 1219 1220 // FIXME: Duplicated from LegalizerHelper 1221 static CmpInst::Predicate minMaxToCompare(unsigned Opc) { 1222 switch (Opc) { 1223 case TargetOpcode::G_SMIN: 1224 return CmpInst::ICMP_SLT; 1225 case TargetOpcode::G_SMAX: 1226 return CmpInst::ICMP_SGT; 1227 case TargetOpcode::G_UMIN: 1228 return CmpInst::ICMP_ULT; 1229 case TargetOpcode::G_UMAX: 1230 return CmpInst::ICMP_UGT; 1231 default: 1232 llvm_unreachable("not in integer min/max"); 1233 } 1234 } 1235 1236 // FIXME: Duplicated from LegalizerHelper, except changing the boolean type. 1237 void AMDGPURegisterBankInfo::lowerScalarMinMax(MachineIRBuilder &B, 1238 MachineInstr &MI) const { 1239 Register Dst = MI.getOperand(0).getReg(); 1240 Register Src0 = MI.getOperand(1).getReg(); 1241 Register Src1 = MI.getOperand(2).getReg(); 1242 1243 const CmpInst::Predicate Pred = minMaxToCompare(MI.getOpcode()); 1244 LLT CmpType = LLT::scalar(32); 1245 1246 auto Cmp = B.buildICmp(Pred, CmpType, Src0, Src1); 1247 B.buildSelect(Dst, Cmp, Src0, Src1); 1248 1249 B.getMRI()->setRegBank(Cmp.getReg(0), AMDGPU::SGPRRegBank); 1250 MI.eraseFromParent(); 1251 } 1252 1253 // For cases where only a single copy is inserted for matching register banks. 1254 // Replace the register in the instruction operand 1255 static bool substituteSimpleCopyRegs( 1256 const AMDGPURegisterBankInfo::OperandsMapper &OpdMapper, unsigned OpIdx) { 1257 SmallVector<unsigned, 1> SrcReg(OpdMapper.getVRegs(OpIdx)); 1258 if (!SrcReg.empty()) { 1259 assert(SrcReg.size() == 1); 1260 OpdMapper.getMI().getOperand(OpIdx).setReg(SrcReg[0]); 1261 return true; 1262 } 1263 1264 return false; 1265 } 1266 1267 /// Handle register layout difference for f16 images for some subtargets. 1268 Register AMDGPURegisterBankInfo::handleD16VData(MachineIRBuilder &B, 1269 MachineRegisterInfo &MRI, 1270 Register Reg) const { 1271 if (!Subtarget.hasUnpackedD16VMem()) 1272 return Reg; 1273 1274 const LLT S16 = LLT::scalar(16); 1275 LLT StoreVT = MRI.getType(Reg); 1276 if (!StoreVT.isVector() || StoreVT.getElementType() != S16) 1277 return Reg; 1278 1279 auto Unmerge = B.buildUnmerge(S16, Reg); 1280 1281 1282 SmallVector<Register, 4> WideRegs; 1283 for (int I = 0, E = Unmerge->getNumOperands() - 1; I != E; ++I) 1284 WideRegs.push_back(Unmerge.getReg(I)); 1285 1286 const LLT S32 = LLT::scalar(32); 1287 int NumElts = StoreVT.getNumElements(); 1288 1289 return B.buildMerge(LLT::vector(NumElts, S32), WideRegs).getReg(0); 1290 } 1291 1292 static std::pair<Register, unsigned> 1293 getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg) { 1294 int64_t Const; 1295 if (mi_match(Reg, MRI, m_ICst(Const))) 1296 return std::make_pair(Register(), Const); 1297 1298 Register Base; 1299 if (mi_match(Reg, MRI, m_GAdd(m_Reg(Base), m_ICst(Const)))) 1300 return std::make_pair(Base, Const); 1301 1302 // TODO: Handle G_OR used for add case 1303 return std::make_pair(Reg, 0); 1304 } 1305 1306 std::pair<Register, unsigned> 1307 AMDGPURegisterBankInfo::splitBufferOffsets(MachineIRBuilder &B, 1308 Register OrigOffset) const { 1309 const unsigned MaxImm = 4095; 1310 Register BaseReg; 1311 unsigned ImmOffset; 1312 const LLT S32 = LLT::scalar(32); 1313 1314 std::tie(BaseReg, ImmOffset) = getBaseWithConstantOffset(*B.getMRI(), 1315 OrigOffset); 1316 1317 unsigned C1 = 0; 1318 if (ImmOffset != 0) { 1319 // If the immediate value is too big for the immoffset field, put the value 1320 // and -4096 into the immoffset field so that the value that is copied/added 1321 // for the voffset field is a multiple of 4096, and it stands more chance 1322 // of being CSEd with the copy/add for another similar load/store. 1323 // However, do not do that rounding down to a multiple of 4096 if that is a 1324 // negative number, as it appears to be illegal to have a negative offset 1325 // in the vgpr, even if adding the immediate offset makes it positive. 1326 unsigned Overflow = ImmOffset & ~MaxImm; 1327 ImmOffset -= Overflow; 1328 if ((int32_t)Overflow < 0) { 1329 Overflow += ImmOffset; 1330 ImmOffset = 0; 1331 } 1332 1333 C1 = ImmOffset; 1334 if (Overflow != 0) { 1335 if (!BaseReg) 1336 BaseReg = B.buildConstant(S32, Overflow).getReg(0); 1337 else { 1338 auto OverflowVal = B.buildConstant(S32, Overflow); 1339 BaseReg = B.buildAdd(S32, BaseReg, OverflowVal).getReg(0); 1340 } 1341 } 1342 } 1343 1344 if (!BaseReg) 1345 BaseReg = B.buildConstant(S32, 0).getReg(0); 1346 1347 return {BaseReg, C1}; 1348 } 1349 1350 static bool isZero(Register Reg, MachineRegisterInfo &MRI) { 1351 int64_t C; 1352 return mi_match(Reg, MRI, m_ICst(C)) && C == 0; 1353 } 1354 1355 static unsigned extractGLC(unsigned CachePolicy) { 1356 return CachePolicy & 1; 1357 } 1358 1359 static unsigned extractSLC(unsigned CachePolicy) { 1360 return (CachePolicy >> 1) & 1; 1361 } 1362 1363 static unsigned extractDLC(unsigned CachePolicy) { 1364 return (CachePolicy >> 2) & 1; 1365 } 1366 1367 MachineInstr * 1368 AMDGPURegisterBankInfo::selectStoreIntrinsic(MachineIRBuilder &B, 1369 MachineInstr &MI) const { 1370 MachineRegisterInfo &MRI = *B.getMRI(); 1371 executeInWaterfallLoop(B, MI, MRI, {2, 4}); 1372 1373 // FIXME: DAG lowering brokenly changes opcode based on FP vs. integer. 1374 1375 Register VData = MI.getOperand(1).getReg(); 1376 LLT Ty = MRI.getType(VData); 1377 1378 int EltSize = Ty.getScalarSizeInBits(); 1379 int Size = Ty.getSizeInBits(); 1380 1381 // FIXME: Broken integer truncstore. 1382 if (EltSize != 32) 1383 report_fatal_error("unhandled intrinsic store"); 1384 1385 // FIXME: Verifier should enforce 1 MMO for these intrinsics. 1386 const int MemSize = (*MI.memoperands_begin())->getSize(); 1387 1388 1389 Register RSrc = MI.getOperand(2).getReg(); 1390 Register VOffset = MI.getOperand(3).getReg(); 1391 Register SOffset = MI.getOperand(4).getReg(); 1392 unsigned CachePolicy = MI.getOperand(5).getImm(); 1393 1394 unsigned ImmOffset; 1395 std::tie(VOffset, ImmOffset) = splitBufferOffsets(B, VOffset); 1396 1397 const bool Offen = !isZero(VOffset, MRI); 1398 1399 unsigned Opc = AMDGPU::BUFFER_STORE_DWORD_OFFEN_exact; 1400 switch (8 * MemSize) { 1401 case 8: 1402 Opc = Offen ? AMDGPU::BUFFER_STORE_BYTE_OFFEN_exact : 1403 AMDGPU::BUFFER_STORE_BYTE_OFFSET_exact; 1404 break; 1405 case 16: 1406 Opc = Offen ? AMDGPU::BUFFER_STORE_SHORT_OFFEN_exact : 1407 AMDGPU::BUFFER_STORE_SHORT_OFFSET_exact; 1408 break; 1409 default: 1410 Opc = Offen ? AMDGPU::BUFFER_STORE_DWORD_OFFEN_exact : 1411 AMDGPU::BUFFER_STORE_DWORD_OFFSET_exact; 1412 if (Size > 32) 1413 Opc = AMDGPU::getMUBUFOpcode(Opc, Size / 32); 1414 break; 1415 } 1416 1417 1418 // Set the insertion point back to the instruction in case it was moved into a 1419 // loop. 1420 B.setInstr(MI); 1421 1422 MachineInstrBuilder MIB = B.buildInstr(Opc) 1423 .addUse(VData); 1424 1425 if (Offen) 1426 MIB.addUse(VOffset); 1427 1428 MIB.addUse(RSrc) 1429 .addUse(SOffset) 1430 .addImm(ImmOffset) 1431 .addImm(extractGLC(CachePolicy)) 1432 .addImm(extractSLC(CachePolicy)) 1433 .addImm(0) // tfe: FIXME: Remove from inst 1434 .addImm(extractDLC(CachePolicy)) 1435 .cloneMemRefs(MI); 1436 1437 // FIXME: We need a way to report failure from applyMappingImpl. 1438 // Insert constrain copies before inserting the loop. 1439 if (!constrainSelectedInstRegOperands(*MIB, *TII, *TRI, *this)) 1440 report_fatal_error("failed to constrain selected store intrinsic"); 1441 1442 return MIB; 1443 } 1444 1445 bool AMDGPURegisterBankInfo::buildVCopy(MachineIRBuilder &B, Register DstReg, 1446 Register SrcReg) const { 1447 MachineRegisterInfo &MRI = *B.getMRI(); 1448 LLT SrcTy = MRI.getType(SrcReg); 1449 if (SrcTy.getSizeInBits() == 32) { 1450 // Use a v_mov_b32 here to make the exec dependency explicit. 1451 B.buildInstr(AMDGPU::V_MOV_B32_e32) 1452 .addDef(DstReg) 1453 .addUse(SrcReg); 1454 return constrainGenericRegister(DstReg, AMDGPU::VGPR_32RegClass, MRI) && 1455 constrainGenericRegister(SrcReg, AMDGPU::SReg_32RegClass, MRI); 1456 } 1457 1458 Register TmpReg0 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); 1459 Register TmpReg1 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); 1460 1461 B.buildInstr(AMDGPU::V_MOV_B32_e32) 1462 .addDef(TmpReg0) 1463 .addUse(SrcReg, 0, AMDGPU::sub0); 1464 B.buildInstr(AMDGPU::V_MOV_B32_e32) 1465 .addDef(TmpReg1) 1466 .addUse(SrcReg, 0, AMDGPU::sub1); 1467 B.buildInstr(AMDGPU::REG_SEQUENCE) 1468 .addDef(DstReg) 1469 .addUse(TmpReg0) 1470 .addImm(AMDGPU::sub0) 1471 .addUse(TmpReg1) 1472 .addImm(AMDGPU::sub1); 1473 1474 return constrainGenericRegister(SrcReg, AMDGPU::SReg_64RegClass, MRI) && 1475 constrainGenericRegister(DstReg, AMDGPU::VReg_64RegClass, MRI); 1476 } 1477 1478 /// Utility function for pushing dynamic vector indexes with a constant offset 1479 /// into waterwall loops. 1480 static void reinsertVectorIndexAdd(MachineIRBuilder &B, 1481 MachineInstr &IdxUseInstr, 1482 unsigned OpIdx, 1483 unsigned ConstOffset) { 1484 MachineRegisterInfo &MRI = *B.getMRI(); 1485 const LLT S32 = LLT::scalar(32); 1486 Register WaterfallIdx = IdxUseInstr.getOperand(OpIdx).getReg(); 1487 B.setInsertPt(*IdxUseInstr.getParent(), IdxUseInstr.getIterator()); 1488 1489 auto MaterializedOffset = B.buildConstant(S32, ConstOffset); 1490 1491 auto Add = B.buildAdd(S32, WaterfallIdx, MaterializedOffset); 1492 MRI.setRegBank(MaterializedOffset.getReg(0), AMDGPU::SGPRRegBank); 1493 MRI.setRegBank(Add.getReg(0), AMDGPU::SGPRRegBank); 1494 IdxUseInstr.getOperand(OpIdx).setReg(Add.getReg(0)); 1495 } 1496 1497 void AMDGPURegisterBankInfo::applyMappingImpl( 1498 const OperandsMapper &OpdMapper) const { 1499 MachineInstr &MI = OpdMapper.getMI(); 1500 unsigned Opc = MI.getOpcode(); 1501 MachineRegisterInfo &MRI = OpdMapper.getMRI(); 1502 switch (Opc) { 1503 case AMDGPU::G_PHI: { 1504 Register DstReg = MI.getOperand(0).getReg(); 1505 LLT DstTy = MRI.getType(DstReg); 1506 if (DstTy != LLT::scalar(1)) 1507 break; 1508 1509 const LLT S32 = LLT::scalar(32); 1510 const RegisterBank *DstBank = 1511 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1512 if (DstBank == &AMDGPU::VCCRegBank) { 1513 applyDefaultMapping(OpdMapper); 1514 // The standard handling only considers the result register bank for 1515 // phis. For VCC, blindly inserting a copy when the phi is lowered will 1516 // produce an invalid copy. We can only copy with some kind of compare to 1517 // get a vector boolean result. Insert a regitser bank copy that will be 1518 // correctly lowered to a compare. 1519 MachineIRBuilder B(*MI.getParent()->getParent()); 1520 1521 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) { 1522 Register SrcReg = MI.getOperand(I).getReg(); 1523 const RegisterBank *SrcBank = getRegBank(SrcReg, MRI, *TRI); 1524 1525 if (SrcBank != &AMDGPU::VCCRegBank) { 1526 MachineBasicBlock *SrcMBB = MI.getOperand(I + 1).getMBB(); 1527 B.setInsertPt(*SrcMBB, SrcMBB->getFirstTerminator()); 1528 1529 auto Copy = B.buildCopy(LLT::scalar(1), SrcReg); 1530 MRI.setRegBank(Copy.getReg(0), AMDGPU::VCCRegBank); 1531 MI.getOperand(I).setReg(Copy.getReg(0)); 1532 } 1533 } 1534 1535 return; 1536 } 1537 1538 // Phi handling is strange and only considers the bank of the destination. 1539 substituteSimpleCopyRegs(OpdMapper, 0); 1540 1541 // Promote SGPR/VGPR booleans to s32 1542 MachineFunction *MF = MI.getParent()->getParent(); 1543 ApplyRegBankMapping ApplyBank(*this, MRI, DstBank); 1544 GISelObserverWrapper Observer(&ApplyBank); 1545 MachineIRBuilder B(MI); 1546 LegalizerHelper Helper(*MF, Observer, B); 1547 1548 if (Helper.widenScalar(MI, 0, S32) != LegalizerHelper::Legalized) 1549 llvm_unreachable("widen scalar should have succeeded"); 1550 1551 return; 1552 } 1553 case AMDGPU::G_ICMP: 1554 case AMDGPU::G_UADDO: 1555 case AMDGPU::G_USUBO: 1556 case AMDGPU::G_UADDE: 1557 case AMDGPU::G_SADDE: 1558 case AMDGPU::G_USUBE: 1559 case AMDGPU::G_SSUBE: { 1560 unsigned BoolDstOp = Opc == AMDGPU::G_ICMP ? 0 : 1; 1561 Register DstReg = MI.getOperand(BoolDstOp).getReg(); 1562 1563 const RegisterBank *DstBank = 1564 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1565 if (DstBank != &AMDGPU::SGPRRegBank) 1566 break; 1567 1568 const bool HasCarryIn = MI.getNumOperands() == 5; 1569 1570 // If this is a scalar compare, promote the result to s32, as the selection 1571 // will end up using a copy to a 32-bit vreg. 1572 const LLT S32 = LLT::scalar(32); 1573 Register NewDstReg = MRI.createGenericVirtualRegister(S32); 1574 MRI.setRegBank(NewDstReg, AMDGPU::SGPRRegBank); 1575 MI.getOperand(BoolDstOp).setReg(NewDstReg); 1576 MachineIRBuilder B(MI); 1577 1578 if (HasCarryIn) { 1579 Register NewSrcReg = MRI.createGenericVirtualRegister(S32); 1580 MRI.setRegBank(NewSrcReg, AMDGPU::SGPRRegBank); 1581 B.buildZExt(NewSrcReg, MI.getOperand(4).getReg()); 1582 MI.getOperand(4).setReg(NewSrcReg); 1583 } 1584 1585 MachineBasicBlock *MBB = MI.getParent(); 1586 B.setInsertPt(*MBB, std::next(MI.getIterator())); 1587 B.buildTrunc(DstReg, NewDstReg); 1588 return; 1589 } 1590 case AMDGPU::G_SELECT: { 1591 Register DstReg = MI.getOperand(0).getReg(); 1592 LLT DstTy = MRI.getType(DstReg); 1593 1594 SmallVector<Register, 1> CondRegs(OpdMapper.getVRegs(1)); 1595 if (CondRegs.empty()) 1596 CondRegs.push_back(MI.getOperand(1).getReg()); 1597 else { 1598 assert(CondRegs.size() == 1); 1599 } 1600 1601 const RegisterBank *CondBank = getRegBank(CondRegs[0], MRI, *TRI); 1602 if (CondBank == &AMDGPU::SGPRRegBank) { 1603 MachineIRBuilder B(MI); 1604 const LLT S32 = LLT::scalar(32); 1605 Register NewCondReg = MRI.createGenericVirtualRegister(S32); 1606 MRI.setRegBank(NewCondReg, AMDGPU::SGPRRegBank); 1607 1608 MI.getOperand(1).setReg(NewCondReg); 1609 B.buildZExt(NewCondReg, CondRegs[0]); 1610 } 1611 1612 if (DstTy.getSizeInBits() != 64) 1613 break; 1614 1615 MachineIRBuilder B(MI); 1616 LLT HalfTy = getHalfSizedType(DstTy); 1617 1618 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 1619 SmallVector<Register, 2> Src1Regs(OpdMapper.getVRegs(2)); 1620 SmallVector<Register, 2> Src2Regs(OpdMapper.getVRegs(3)); 1621 1622 // All inputs are SGPRs, nothing special to do. 1623 if (DefRegs.empty()) { 1624 assert(Src1Regs.empty() && Src2Regs.empty()); 1625 break; 1626 } 1627 1628 if (Src1Regs.empty()) 1629 split64BitValueForMapping(B, Src1Regs, HalfTy, MI.getOperand(2).getReg()); 1630 else { 1631 setRegsToType(MRI, Src1Regs, HalfTy); 1632 } 1633 1634 if (Src2Regs.empty()) 1635 split64BitValueForMapping(B, Src2Regs, HalfTy, MI.getOperand(3).getReg()); 1636 else 1637 setRegsToType(MRI, Src2Regs, HalfTy); 1638 1639 setRegsToType(MRI, DefRegs, HalfTy); 1640 1641 B.buildSelect(DefRegs[0], CondRegs[0], Src1Regs[0], Src2Regs[0]); 1642 B.buildSelect(DefRegs[1], CondRegs[0], Src1Regs[1], Src2Regs[1]); 1643 1644 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 1645 MI.eraseFromParent(); 1646 return; 1647 } 1648 case AMDGPU::G_BRCOND: { 1649 Register CondReg = MI.getOperand(0).getReg(); 1650 // FIXME: Should use legalizer helper, but should change bool ext type. 1651 const RegisterBank *CondBank = 1652 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1653 1654 if (CondBank == &AMDGPU::SGPRRegBank) { 1655 MachineIRBuilder B(MI); 1656 const LLT S32 = LLT::scalar(32); 1657 Register NewCondReg = MRI.createGenericVirtualRegister(S32); 1658 MRI.setRegBank(NewCondReg, AMDGPU::SGPRRegBank); 1659 1660 MI.getOperand(0).setReg(NewCondReg); 1661 B.buildZExt(NewCondReg, CondReg); 1662 return; 1663 } 1664 1665 break; 1666 } 1667 case AMDGPU::G_AND: 1668 case AMDGPU::G_OR: 1669 case AMDGPU::G_XOR: { 1670 // 64-bit and is only available on the SALU, so split into 2 32-bit ops if 1671 // there is a VGPR input. 1672 Register DstReg = MI.getOperand(0).getReg(); 1673 LLT DstTy = MRI.getType(DstReg); 1674 1675 if (DstTy.getSizeInBits() == 1) { 1676 const RegisterBank *DstBank = 1677 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1678 if (DstBank == &AMDGPU::VCCRegBank) 1679 break; 1680 1681 MachineFunction *MF = MI.getParent()->getParent(); 1682 ApplyRegBankMapping ApplyBank(*this, MRI, DstBank); 1683 GISelObserverWrapper Observer(&ApplyBank); 1684 MachineIRBuilder B(MI); 1685 LegalizerHelper Helper(*MF, Observer, B); 1686 1687 if (Helper.widenScalar(MI, 0, LLT::scalar(32)) != 1688 LegalizerHelper::Legalized) 1689 llvm_unreachable("widen scalar should have succeeded"); 1690 return; 1691 } 1692 1693 if (DstTy.getSizeInBits() != 64) 1694 break; 1695 1696 LLT HalfTy = getHalfSizedType(DstTy); 1697 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 1698 SmallVector<Register, 2> Src0Regs(OpdMapper.getVRegs(1)); 1699 SmallVector<Register, 2> Src1Regs(OpdMapper.getVRegs(2)); 1700 1701 // All inputs are SGPRs, nothing special to do. 1702 if (DefRegs.empty()) { 1703 assert(Src0Regs.empty() && Src1Regs.empty()); 1704 break; 1705 } 1706 1707 assert(DefRegs.size() == 2); 1708 assert(Src0Regs.size() == Src1Regs.size() && 1709 (Src0Regs.empty() || Src0Regs.size() == 2)); 1710 1711 // Depending on where the source registers came from, the generic code may 1712 // have decided to split the inputs already or not. If not, we still need to 1713 // extract the values. 1714 MachineIRBuilder B(MI); 1715 1716 if (Src0Regs.empty()) 1717 split64BitValueForMapping(B, Src0Regs, HalfTy, MI.getOperand(1).getReg()); 1718 else 1719 setRegsToType(MRI, Src0Regs, HalfTy); 1720 1721 if (Src1Regs.empty()) 1722 split64BitValueForMapping(B, Src1Regs, HalfTy, MI.getOperand(2).getReg()); 1723 else 1724 setRegsToType(MRI, Src1Regs, HalfTy); 1725 1726 setRegsToType(MRI, DefRegs, HalfTy); 1727 1728 B.buildInstr(Opc) 1729 .addDef(DefRegs[0]) 1730 .addUse(Src0Regs[0]) 1731 .addUse(Src1Regs[0]); 1732 1733 B.buildInstr(Opc) 1734 .addDef(DefRegs[1]) 1735 .addUse(Src0Regs[1]) 1736 .addUse(Src1Regs[1]); 1737 1738 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 1739 MI.eraseFromParent(); 1740 return; 1741 } 1742 case AMDGPU::G_ADD: 1743 case AMDGPU::G_SUB: 1744 case AMDGPU::G_MUL: { 1745 Register DstReg = MI.getOperand(0).getReg(); 1746 LLT DstTy = MRI.getType(DstReg); 1747 if (DstTy != LLT::scalar(16)) 1748 break; 1749 1750 const RegisterBank *DstBank = 1751 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1752 if (DstBank == &AMDGPU::VGPRRegBank) 1753 break; 1754 1755 // 16-bit operations are VALU only, but can be promoted to 32-bit SALU. 1756 MachineFunction *MF = MI.getParent()->getParent(); 1757 MachineIRBuilder B(MI); 1758 ApplyRegBankMapping ApplySALU(*this, MRI, &AMDGPU::SGPRRegBank); 1759 GISelObserverWrapper Observer(&ApplySALU); 1760 LegalizerHelper Helper(*MF, Observer, B); 1761 1762 if (Helper.widenScalar(MI, 0, LLT::scalar(32)) != 1763 LegalizerHelper::Legalized) 1764 llvm_unreachable("widen scalar should have succeeded"); 1765 return; 1766 } 1767 case AMDGPU::G_SMIN: 1768 case AMDGPU::G_SMAX: 1769 case AMDGPU::G_UMIN: 1770 case AMDGPU::G_UMAX: { 1771 Register DstReg = MI.getOperand(0).getReg(); 1772 const RegisterBank *DstBank = 1773 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1774 if (DstBank == &AMDGPU::VGPRRegBank) 1775 break; 1776 1777 MachineFunction *MF = MI.getParent()->getParent(); 1778 MachineIRBuilder B(MI); 1779 1780 // Turn scalar min/max into a compare and select. 1781 LLT Ty = MRI.getType(DstReg); 1782 LLT S32 = LLT::scalar(32); 1783 LLT S16 = LLT::scalar(16); 1784 1785 if (Ty == S16) { 1786 ApplyRegBankMapping ApplySALU(*this, MRI, &AMDGPU::SGPRRegBank); 1787 GISelObserverWrapper Observer(&ApplySALU); 1788 LegalizerHelper Helper(*MF, Observer, B); 1789 1790 // Need to widen to s32, and expand as cmp + select. 1791 if (Helper.widenScalar(MI, 0, S32) != LegalizerHelper::Legalized) 1792 llvm_unreachable("widenScalar should have succeeded"); 1793 1794 // FIXME: This is relying on widenScalar leaving MI in place. 1795 lowerScalarMinMax(B, MI); 1796 } else 1797 lowerScalarMinMax(B, MI); 1798 1799 return; 1800 } 1801 case AMDGPU::G_SEXT: 1802 case AMDGPU::G_ZEXT: { 1803 Register SrcReg = MI.getOperand(1).getReg(); 1804 LLT SrcTy = MRI.getType(SrcReg); 1805 bool Signed = Opc == AMDGPU::G_SEXT; 1806 1807 MachineIRBuilder B(MI); 1808 const RegisterBank *SrcBank = 1809 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 1810 1811 Register DstReg = MI.getOperand(0).getReg(); 1812 LLT DstTy = MRI.getType(DstReg); 1813 if (DstTy.isScalar() && 1814 SrcBank != &AMDGPU::SGPRRegBank && 1815 SrcBank != &AMDGPU::VCCRegBank && 1816 // FIXME: Should handle any type that round to s64 when irregular 1817 // breakdowns supported. 1818 DstTy.getSizeInBits() == 64 && 1819 SrcTy.getSizeInBits() <= 32) { 1820 const LLT S32 = LLT::scalar(32); 1821 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 1822 1823 // Extend to 32-bit, and then extend the low half. 1824 if (Signed) { 1825 // TODO: Should really be buildSExtOrCopy 1826 B.buildSExtOrTrunc(DefRegs[0], SrcReg); 1827 1828 // Replicate sign bit from 32-bit extended part. 1829 auto ShiftAmt = B.buildConstant(S32, 31); 1830 MRI.setRegBank(ShiftAmt.getReg(0), *SrcBank); 1831 B.buildAShr(DefRegs[1], DefRegs[0], ShiftAmt); 1832 } else { 1833 B.buildZExtOrTrunc(DefRegs[0], SrcReg); 1834 B.buildConstant(DefRegs[1], 0); 1835 } 1836 1837 MRI.setRegBank(DstReg, *SrcBank); 1838 MI.eraseFromParent(); 1839 return; 1840 } 1841 1842 if (SrcTy != LLT::scalar(1)) 1843 return; 1844 1845 if (SrcBank == &AMDGPU::VCCRegBank) { 1846 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 1847 1848 const RegisterBank *DstBank = &AMDGPU::VGPRRegBank; 1849 1850 unsigned DstSize = DstTy.getSizeInBits(); 1851 // 64-bit select is SGPR only 1852 const bool UseSel64 = DstSize > 32 && 1853 SrcBank->getID() == AMDGPU::SGPRRegBankID; 1854 1855 // TODO: Should s16 select be legal? 1856 LLT SelType = UseSel64 ? LLT::scalar(64) : LLT::scalar(32); 1857 auto True = B.buildConstant(SelType, Signed ? -1 : 1); 1858 auto False = B.buildConstant(SelType, 0); 1859 1860 MRI.setRegBank(True.getReg(0), *DstBank); 1861 MRI.setRegBank(False.getReg(0), *DstBank); 1862 MRI.setRegBank(DstReg, *DstBank); 1863 1864 if (DstSize > 32) { 1865 B.buildSelect(DefRegs[0], SrcReg, True, False); 1866 B.buildCopy(DefRegs[1], DefRegs[0]); 1867 } else if (DstSize < 32) { 1868 auto Sel = B.buildSelect(SelType, SrcReg, True, False); 1869 MRI.setRegBank(Sel.getReg(0), *DstBank); 1870 B.buildTrunc(DstReg, Sel); 1871 } else { 1872 B.buildSelect(DstReg, SrcReg, True, False); 1873 } 1874 1875 MI.eraseFromParent(); 1876 return; 1877 } 1878 1879 // Fixup the case with an s1 src that isn't a condition register. Use shifts 1880 // instead of introducing a compare to avoid an unnecessary condition 1881 // register (and since there's no scalar 16-bit compares). 1882 auto Ext = B.buildAnyExt(DstTy, SrcReg); 1883 auto ShiftAmt = B.buildConstant(LLT::scalar(32), DstTy.getSizeInBits() - 1); 1884 auto Shl = B.buildShl(DstTy, Ext, ShiftAmt); 1885 1886 if (MI.getOpcode() == AMDGPU::G_SEXT) 1887 B.buildAShr(DstReg, Shl, ShiftAmt); 1888 else 1889 B.buildLShr(DstReg, Shl, ShiftAmt); 1890 1891 MRI.setRegBank(DstReg, *SrcBank); 1892 MRI.setRegBank(Ext.getReg(0), *SrcBank); 1893 MRI.setRegBank(ShiftAmt.getReg(0), *SrcBank); 1894 MRI.setRegBank(Shl.getReg(0), *SrcBank); 1895 MI.eraseFromParent(); 1896 return; 1897 } 1898 case AMDGPU::G_BUILD_VECTOR: 1899 case AMDGPU::G_BUILD_VECTOR_TRUNC: { 1900 Register DstReg = MI.getOperand(0).getReg(); 1901 LLT DstTy = MRI.getType(DstReg); 1902 if (DstTy != LLT::vector(2, 16)) 1903 break; 1904 1905 assert(MI.getNumOperands() == 3 && OpdMapper.getVRegs(0).empty()); 1906 substituteSimpleCopyRegs(OpdMapper, 1); 1907 substituteSimpleCopyRegs(OpdMapper, 2); 1908 1909 const RegisterBank *DstBank = 1910 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1911 if (DstBank == &AMDGPU::SGPRRegBank) 1912 break; // Can use S_PACK_* instructions. 1913 1914 MachineIRBuilder B(MI); 1915 1916 Register Lo = MI.getOperand(1).getReg(); 1917 Register Hi = MI.getOperand(2).getReg(); 1918 const LLT S32 = LLT::scalar(32); 1919 1920 const RegisterBank *BankLo = 1921 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 1922 const RegisterBank *BankHi = 1923 OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 1924 1925 Register ZextLo; 1926 Register ShiftHi; 1927 1928 if (Opc == AMDGPU::G_BUILD_VECTOR) { 1929 ZextLo = B.buildZExt(S32, Lo).getReg(0); 1930 MRI.setRegBank(ZextLo, *BankLo); 1931 1932 Register ZextHi = B.buildZExt(S32, Hi).getReg(0); 1933 MRI.setRegBank(ZextHi, *BankHi); 1934 1935 auto ShiftAmt = B.buildConstant(S32, 16); 1936 MRI.setRegBank(ShiftAmt.getReg(0), *BankHi); 1937 1938 ShiftHi = B.buildShl(S32, ZextHi, ShiftAmt).getReg(0); 1939 MRI.setRegBank(ShiftHi, *BankHi); 1940 } else { 1941 Register MaskLo = B.buildConstant(S32, 0xffff).getReg(0); 1942 MRI.setRegBank(MaskLo, *BankLo); 1943 1944 auto ShiftAmt = B.buildConstant(S32, 16); 1945 MRI.setRegBank(ShiftAmt.getReg(0), *BankHi); 1946 1947 ShiftHi = B.buildShl(S32, Hi, ShiftAmt).getReg(0); 1948 MRI.setRegBank(ShiftHi, *BankHi); 1949 1950 ZextLo = B.buildAnd(S32, Lo, MaskLo).getReg(0); 1951 MRI.setRegBank(ZextLo, *BankLo); 1952 } 1953 1954 auto Or = B.buildOr(S32, ZextLo, ShiftHi); 1955 MRI.setRegBank(Or.getReg(0), *DstBank); 1956 1957 B.buildBitcast(DstReg, Or); 1958 MI.eraseFromParent(); 1959 return; 1960 } 1961 case AMDGPU::G_EXTRACT_VECTOR_ELT: { 1962 SmallVector<Register, 2> DstRegs(OpdMapper.getVRegs(0)); 1963 1964 assert(OpdMapper.getVRegs(1).empty() && OpdMapper.getVRegs(2).empty()); 1965 1966 Register DstReg = MI.getOperand(0).getReg(); 1967 Register SrcReg = MI.getOperand(1).getReg(); 1968 1969 const LLT S32 = LLT::scalar(32); 1970 LLT DstTy = MRI.getType(DstReg); 1971 LLT SrcTy = MRI.getType(SrcReg); 1972 1973 MachineIRBuilder B(MI); 1974 1975 const ValueMapping &DstMapping 1976 = OpdMapper.getInstrMapping().getOperandMapping(0); 1977 const RegisterBank *DstBank = DstMapping.BreakDown[0].RegBank; 1978 const RegisterBank *SrcBank = 1979 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 1980 const RegisterBank *IdxBank = 1981 OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 1982 1983 Register BaseIdxReg; 1984 unsigned ConstOffset; 1985 MachineInstr *OffsetDef; 1986 std::tie(BaseIdxReg, ConstOffset, OffsetDef) = 1987 AMDGPU::getBaseWithConstantOffset(MRI, MI.getOperand(2).getReg()); 1988 1989 // See if the index is an add of a constant which will be foldable by moving 1990 // the base register of the index later if this is going to be executed in a 1991 // waterfall loop. This is essentially to reassociate the add of a constant 1992 // with the readfirstlane. 1993 bool ShouldMoveIndexIntoLoop = IdxBank != &AMDGPU::SGPRRegBank && 1994 ConstOffset > 0 && 1995 ConstOffset < SrcTy.getNumElements(); 1996 1997 // Move the base register. We'll re-insert the add later. 1998 if (ShouldMoveIndexIntoLoop) 1999 MI.getOperand(2).setReg(BaseIdxReg); 2000 2001 // If this is a VGPR result only because the index was a VGPR result, the 2002 // actual indexing will be done on the SGPR source vector, which will 2003 // produce a scalar result. We need to copy to the VGPR result inside the 2004 // waterfall loop. 2005 const bool NeedCopyToVGPR = DstBank == &AMDGPU::VGPRRegBank && 2006 SrcBank == &AMDGPU::SGPRRegBank; 2007 if (DstRegs.empty()) { 2008 applyDefaultMapping(OpdMapper); 2009 2010 executeInWaterfallLoop(MI, MRI, { 2 }); 2011 2012 if (NeedCopyToVGPR) { 2013 // We don't want a phi for this temporary reg. 2014 Register TmpReg = MRI.createGenericVirtualRegister(DstTy); 2015 MRI.setRegBank(TmpReg, AMDGPU::SGPRRegBank); 2016 MI.getOperand(0).setReg(TmpReg); 2017 B.setInsertPt(*MI.getParent(), ++MI.getIterator()); 2018 2019 // Use a v_mov_b32 here to make the exec dependency explicit. 2020 buildVCopy(B, DstReg, TmpReg); 2021 } 2022 2023 // Re-insert the constant offset add inside the waterfall loop. 2024 if (ShouldMoveIndexIntoLoop) 2025 reinsertVectorIndexAdd(B, MI, 2, ConstOffset); 2026 2027 return; 2028 } 2029 2030 assert(DstTy.getSizeInBits() == 64); 2031 2032 LLT Vec32 = LLT::vector(2 * SrcTy.getNumElements(), 32); 2033 2034 auto CastSrc = B.buildBitcast(Vec32, SrcReg); 2035 auto One = B.buildConstant(S32, 1); 2036 2037 MachineBasicBlock::iterator MII = MI.getIterator(); 2038 2039 // Split the vector index into 32-bit pieces. Prepare to move all of the 2040 // new instructions into a waterfall loop if necessary. 2041 // 2042 // Don't put the bitcast or constant in the loop. 2043 MachineInstrSpan Span(MII, &B.getMBB()); 2044 2045 // Compute 32-bit element indices, (2 * OrigIdx, 2 * OrigIdx + 1). 2046 auto IdxLo = B.buildShl(S32, BaseIdxReg, One); 2047 auto IdxHi = B.buildAdd(S32, IdxLo, One); 2048 2049 auto Extract0 = B.buildExtractVectorElement(DstRegs[0], CastSrc, IdxLo); 2050 auto Extract1 = B.buildExtractVectorElement(DstRegs[1], CastSrc, IdxHi); 2051 2052 MRI.setRegBank(DstReg, *DstBank); 2053 MRI.setRegBank(CastSrc.getReg(0), *SrcBank); 2054 MRI.setRegBank(One.getReg(0), AMDGPU::SGPRRegBank); 2055 MRI.setRegBank(IdxLo.getReg(0), AMDGPU::SGPRRegBank); 2056 MRI.setRegBank(IdxHi.getReg(0), AMDGPU::SGPRRegBank); 2057 2058 SmallSet<Register, 4> OpsToWaterfall; 2059 if (!collectWaterfallOperands(OpsToWaterfall, MI, MRI, { 2 })) { 2060 MI.eraseFromParent(); 2061 return; 2062 } 2063 2064 // Remove the original instruction to avoid potentially confusing the 2065 // waterfall loop logic. 2066 B.setInstr(*Span.begin()); 2067 MI.eraseFromParent(); 2068 executeInWaterfallLoop(B, make_range(Span.begin(), Span.end()), 2069 OpsToWaterfall, MRI); 2070 2071 if (NeedCopyToVGPR) { 2072 MachineBasicBlock *LoopBB = Extract1->getParent(); 2073 Register TmpReg0 = MRI.createGenericVirtualRegister(S32); 2074 Register TmpReg1 = MRI.createGenericVirtualRegister(S32); 2075 MRI.setRegBank(TmpReg0, AMDGPU::SGPRRegBank); 2076 MRI.setRegBank(TmpReg1, AMDGPU::SGPRRegBank); 2077 2078 Extract0->getOperand(0).setReg(TmpReg0); 2079 Extract1->getOperand(0).setReg(TmpReg1); 2080 2081 B.setInsertPt(*LoopBB, ++Extract1->getIterator()); 2082 2083 buildVCopy(B, DstRegs[0], TmpReg0); 2084 buildVCopy(B, DstRegs[1], TmpReg1); 2085 } 2086 2087 if (ShouldMoveIndexIntoLoop) 2088 reinsertVectorIndexAdd(B, *IdxLo, 1, ConstOffset); 2089 2090 return; 2091 } 2092 case AMDGPU::G_INSERT_VECTOR_ELT: { 2093 SmallVector<Register, 2> InsRegs(OpdMapper.getVRegs(2)); 2094 2095 Register DstReg = MI.getOperand(0).getReg(); 2096 LLT VecTy = MRI.getType(DstReg); 2097 2098 assert(OpdMapper.getVRegs(0).empty()); 2099 assert(OpdMapper.getVRegs(3).empty()); 2100 2101 const RegisterBank *IdxBank = 2102 OpdMapper.getInstrMapping().getOperandMapping(3).BreakDown[0].RegBank; 2103 2104 if (substituteSimpleCopyRegs(OpdMapper, 1)) 2105 MRI.setType(MI.getOperand(1).getReg(), VecTy); 2106 2107 Register SrcReg = MI.getOperand(1).getReg(); 2108 Register InsReg = MI.getOperand(2).getReg(); 2109 LLT InsTy = MRI.getType(InsReg); 2110 (void)InsTy; 2111 2112 Register BaseIdxReg; 2113 unsigned ConstOffset; 2114 MachineInstr *OffsetDef; 2115 std::tie(BaseIdxReg, ConstOffset, OffsetDef) = 2116 AMDGPU::getBaseWithConstantOffset(MRI, MI.getOperand(3).getReg()); 2117 2118 // See if the index is an add of a constant which will be foldable by moving 2119 // the base register of the index later if this is going to be executed in a 2120 // waterfall loop. This is essentially to reassociate the add of a constant 2121 // with the readfirstlane. 2122 bool ShouldMoveIndexIntoLoop = IdxBank != &AMDGPU::SGPRRegBank && 2123 ConstOffset > 0 && 2124 ConstOffset < VecTy.getNumElements(); 2125 2126 // Move the base register. We'll re-insert the add later. 2127 if (ShouldMoveIndexIntoLoop) 2128 MI.getOperand(3).setReg(BaseIdxReg); 2129 2130 2131 if (InsRegs.empty()) { 2132 executeInWaterfallLoop(MI, MRI, { 3 }); 2133 2134 // Re-insert the constant offset add inside the waterfall loop. 2135 if (ShouldMoveIndexIntoLoop) { 2136 MachineIRBuilder B(MI); 2137 reinsertVectorIndexAdd(B, MI, 3, ConstOffset); 2138 } 2139 2140 return; 2141 } 2142 2143 2144 assert(InsTy.getSizeInBits() == 64); 2145 2146 const LLT S32 = LLT::scalar(32); 2147 LLT Vec32 = LLT::vector(2 * VecTy.getNumElements(), 32); 2148 2149 MachineIRBuilder B(MI); 2150 auto CastSrc = B.buildBitcast(Vec32, SrcReg); 2151 auto One = B.buildConstant(S32, 1); 2152 2153 // Split the vector index into 32-bit pieces. Prepare to move all of the 2154 // new instructions into a waterfall loop if necessary. 2155 // 2156 // Don't put the bitcast or constant in the loop. 2157 MachineInstrSpan Span(MachineBasicBlock::iterator(&MI), &B.getMBB()); 2158 2159 // Compute 32-bit element indices, (2 * OrigIdx, 2 * OrigIdx + 1). 2160 auto IdxLo = B.buildShl(S32, BaseIdxReg, One); 2161 auto IdxHi = B.buildAdd(S32, IdxLo, One); 2162 2163 auto InsLo = B.buildInsertVectorElement(Vec32, CastSrc, InsRegs[0], IdxLo); 2164 auto InsHi = B.buildInsertVectorElement(Vec32, InsLo, InsRegs[1], IdxHi); 2165 2166 const RegisterBank *DstBank = 2167 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2168 const RegisterBank *SrcBank = 2169 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 2170 const RegisterBank *InsSrcBank = 2171 OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 2172 2173 MRI.setRegBank(InsReg, *InsSrcBank); 2174 MRI.setRegBank(CastSrc.getReg(0), *SrcBank); 2175 MRI.setRegBank(InsLo.getReg(0), *DstBank); 2176 MRI.setRegBank(InsHi.getReg(0), *DstBank); 2177 MRI.setRegBank(One.getReg(0), AMDGPU::SGPRRegBank); 2178 MRI.setRegBank(IdxLo.getReg(0), AMDGPU::SGPRRegBank); 2179 MRI.setRegBank(IdxHi.getReg(0), AMDGPU::SGPRRegBank); 2180 2181 2182 SmallSet<Register, 4> OpsToWaterfall; 2183 if (!collectWaterfallOperands(OpsToWaterfall, MI, MRI, { 3 })) { 2184 B.setInsertPt(B.getMBB(), MI); 2185 B.buildBitcast(DstReg, InsHi); 2186 MI.eraseFromParent(); 2187 return; 2188 } 2189 2190 B.setInstr(*Span.begin()); 2191 MI.eraseFromParent(); 2192 2193 // Figure out the point after the waterfall loop before mangling the control 2194 // flow. 2195 executeInWaterfallLoop(B, make_range(Span.begin(), Span.end()), 2196 OpsToWaterfall, MRI); 2197 2198 // The insertion point is now right after the original instruction. 2199 // 2200 // Keep the bitcast to the original vector type out of the loop. Doing this 2201 // saved an extra phi we don't need inside the loop. 2202 B.buildBitcast(DstReg, InsHi); 2203 2204 // Re-insert the constant offset add inside the waterfall loop. 2205 if (ShouldMoveIndexIntoLoop) 2206 reinsertVectorIndexAdd(B, *IdxLo, 1, ConstOffset); 2207 2208 return; 2209 } 2210 case AMDGPU::G_AMDGPU_BUFFER_LOAD: 2211 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT: 2212 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT: 2213 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE: 2214 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE: 2215 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT: 2216 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT_D16: 2217 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT: 2218 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT_D16: 2219 case AMDGPU::G_AMDGPU_BUFFER_STORE: 2220 case AMDGPU::G_AMDGPU_BUFFER_STORE_BYTE: 2221 case AMDGPU::G_AMDGPU_BUFFER_STORE_SHORT: 2222 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT: 2223 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT_D16: 2224 case AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT: 2225 case AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT_D16: { 2226 applyDefaultMapping(OpdMapper); 2227 executeInWaterfallLoop(MI, MRI, {1, 4}); 2228 return; 2229 } 2230 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SWAP: 2231 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_ADD: 2232 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SUB: 2233 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMIN: 2234 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMIN: 2235 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMAX: 2236 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMAX: 2237 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_AND: 2238 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_OR: 2239 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_XOR: 2240 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_INC: 2241 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_DEC: { 2242 applyDefaultMapping(OpdMapper); 2243 executeInWaterfallLoop(MI, MRI, {2, 5}); 2244 return; 2245 } 2246 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_CMPSWAP: { 2247 applyDefaultMapping(OpdMapper); 2248 executeInWaterfallLoop(MI, MRI, {3, 6}); 2249 return; 2250 } 2251 case AMDGPU::G_INTRINSIC: { 2252 switch (MI.getIntrinsicID()) { 2253 case Intrinsic::amdgcn_s_buffer_load: { 2254 // FIXME: Move to G_INTRINSIC_W_SIDE_EFFECTS 2255 executeInWaterfallLoop(MI, MRI, { 2, 3 }); 2256 return; 2257 } 2258 case Intrinsic::amdgcn_readlane: { 2259 substituteSimpleCopyRegs(OpdMapper, 2); 2260 2261 assert(OpdMapper.getVRegs(0).empty()); 2262 assert(OpdMapper.getVRegs(3).empty()); 2263 2264 // Make sure the index is an SGPR. It doesn't make sense to run this in a 2265 // waterfall loop, so assume it's a uniform value. 2266 constrainOpWithReadfirstlane(MI, MRI, 3); // Index 2267 return; 2268 } 2269 case Intrinsic::amdgcn_writelane: { 2270 assert(OpdMapper.getVRegs(0).empty()); 2271 assert(OpdMapper.getVRegs(2).empty()); 2272 assert(OpdMapper.getVRegs(3).empty()); 2273 2274 substituteSimpleCopyRegs(OpdMapper, 4); // VGPR input val 2275 constrainOpWithReadfirstlane(MI, MRI, 2); // Source value 2276 constrainOpWithReadfirstlane(MI, MRI, 3); // Index 2277 return; 2278 } 2279 case Intrinsic::amdgcn_interp_p1: 2280 case Intrinsic::amdgcn_interp_p2: 2281 case Intrinsic::amdgcn_interp_mov: 2282 case Intrinsic::amdgcn_interp_p1_f16: 2283 case Intrinsic::amdgcn_interp_p2_f16: { 2284 applyDefaultMapping(OpdMapper); 2285 2286 // Readlane for m0 value, which is always the last operand. 2287 // FIXME: Should this be a waterfall loop instead? 2288 constrainOpWithReadfirstlane(MI, MRI, MI.getNumOperands() - 1); // Index 2289 return; 2290 } 2291 case Intrinsic::amdgcn_permlane16: 2292 case Intrinsic::amdgcn_permlanex16: { 2293 // Doing a waterfall loop over these wouldn't make any sense. 2294 substituteSimpleCopyRegs(OpdMapper, 2); 2295 substituteSimpleCopyRegs(OpdMapper, 3); 2296 constrainOpWithReadfirstlane(MI, MRI, 4); 2297 constrainOpWithReadfirstlane(MI, MRI, 5); 2298 return; 2299 } 2300 default: 2301 break; 2302 } 2303 break; 2304 } 2305 case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: { 2306 auto IntrID = MI.getIntrinsicID(); 2307 switch (IntrID) { 2308 case Intrinsic::amdgcn_ds_ordered_add: 2309 case Intrinsic::amdgcn_ds_ordered_swap: { 2310 // This is only allowed to execute with 1 lane, so readfirstlane is safe. 2311 assert(OpdMapper.getVRegs(0).empty()); 2312 substituteSimpleCopyRegs(OpdMapper, 3); 2313 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 2314 return; 2315 } 2316 case Intrinsic::amdgcn_ds_gws_init: 2317 case Intrinsic::amdgcn_ds_gws_barrier: 2318 case Intrinsic::amdgcn_ds_gws_sema_br: { 2319 // Only the first lane is executes, so readfirstlane is safe. 2320 substituteSimpleCopyRegs(OpdMapper, 1); 2321 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 2322 return; 2323 } 2324 case Intrinsic::amdgcn_ds_gws_sema_v: 2325 case Intrinsic::amdgcn_ds_gws_sema_p: 2326 case Intrinsic::amdgcn_ds_gws_sema_release_all: { 2327 // Only the first lane is executes, so readfirstlane is safe. 2328 constrainOpWithReadfirstlane(MI, MRI, 1); // M0 2329 return; 2330 } 2331 case Intrinsic::amdgcn_ds_append: 2332 case Intrinsic::amdgcn_ds_consume: { 2333 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 2334 return; 2335 } 2336 case Intrinsic::amdgcn_s_sendmsg: 2337 case Intrinsic::amdgcn_s_sendmsghalt: { 2338 // FIXME: Should this use a waterfall loop? 2339 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 2340 return; 2341 } 2342 default: { 2343 if (const AMDGPU::RsrcIntrinsic *RSrcIntrin = 2344 AMDGPU::lookupRsrcIntrinsic(IntrID)) { 2345 // Non-images can have complications from operands that allow both SGPR 2346 // and VGPR. For now it's too complicated to figure out the final opcode 2347 // to derive the register bank from the MCInstrDesc. 2348 if (RSrcIntrin->IsImage) { 2349 applyMappingImage(MI, OpdMapper, MRI, RSrcIntrin->RsrcArg); 2350 return; 2351 } 2352 } 2353 2354 break; 2355 } 2356 } 2357 break; 2358 } 2359 case AMDGPU::G_LOAD: 2360 case AMDGPU::G_ZEXTLOAD: 2361 case AMDGPU::G_SEXTLOAD: { 2362 if (applyMappingWideLoad(MI, OpdMapper, MRI)) 2363 return; 2364 break; 2365 } 2366 default: 2367 break; 2368 } 2369 2370 return applyDefaultMapping(OpdMapper); 2371 } 2372 2373 bool AMDGPURegisterBankInfo::isSALUMapping(const MachineInstr &MI) const { 2374 const MachineFunction &MF = *MI.getParent()->getParent(); 2375 const MachineRegisterInfo &MRI = MF.getRegInfo(); 2376 for (unsigned i = 0, e = MI.getNumOperands();i != e; ++i) { 2377 if (!MI.getOperand(i).isReg()) 2378 continue; 2379 Register Reg = MI.getOperand(i).getReg(); 2380 if (const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI)) { 2381 if (Bank->getID() != AMDGPU::SGPRRegBankID) 2382 return false; 2383 } 2384 } 2385 return true; 2386 } 2387 2388 const RegisterBankInfo::InstructionMapping & 2389 AMDGPURegisterBankInfo::getDefaultMappingSOP(const MachineInstr &MI) const { 2390 const MachineFunction &MF = *MI.getParent()->getParent(); 2391 const MachineRegisterInfo &MRI = MF.getRegInfo(); 2392 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 2393 2394 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 2395 unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI); 2396 OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 2397 } 2398 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), 2399 MI.getNumOperands()); 2400 } 2401 2402 const RegisterBankInfo::InstructionMapping & 2403 AMDGPURegisterBankInfo::getDefaultMappingVOP(const MachineInstr &MI) const { 2404 const MachineFunction &MF = *MI.getParent()->getParent(); 2405 const MachineRegisterInfo &MRI = MF.getRegInfo(); 2406 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 2407 2408 // Even though we technically could use SGPRs, this would require knowledge of 2409 // the constant bus restriction. Force all sources to VGPR (except for VCC). 2410 // 2411 // TODO: Unary ops are trivially OK, so accept SGPRs? 2412 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 2413 const MachineOperand &Src = MI.getOperand(i); 2414 if (!Src.isReg()) 2415 continue; 2416 2417 unsigned Size = getSizeInBits(Src.getReg(), MRI, *TRI); 2418 unsigned BankID = Size == 1 ? AMDGPU::VCCRegBankID : AMDGPU::VGPRRegBankID; 2419 OpdsMapping[i] = AMDGPU::getValueMapping(BankID, Size); 2420 } 2421 2422 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), 2423 MI.getNumOperands()); 2424 } 2425 2426 const RegisterBankInfo::InstructionMapping & 2427 AMDGPURegisterBankInfo::getDefaultMappingAllVGPR(const MachineInstr &MI) const { 2428 const MachineFunction &MF = *MI.getParent()->getParent(); 2429 const MachineRegisterInfo &MRI = MF.getRegInfo(); 2430 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 2431 2432 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) { 2433 const MachineOperand &Op = MI.getOperand(I); 2434 if (!Op.isReg()) 2435 continue; 2436 2437 unsigned Size = getSizeInBits(Op.getReg(), MRI, *TRI); 2438 OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 2439 } 2440 2441 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), 2442 MI.getNumOperands()); 2443 } 2444 2445 const RegisterBankInfo::InstructionMapping & 2446 AMDGPURegisterBankInfo::getImageMapping(const MachineRegisterInfo &MRI, 2447 const MachineInstr &MI, 2448 int RsrcIdx) const { 2449 // The reported argument index is relative to the IR intrinsic call arguments, 2450 // so we need to shift by the number of defs and the intrinsic ID. 2451 RsrcIdx += MI.getNumExplicitDefs() + 1; 2452 2453 const int NumOps = MI.getNumOperands(); 2454 SmallVector<const ValueMapping *, 8> OpdsMapping(NumOps); 2455 2456 // TODO: Should packed/unpacked D16 difference be reported here as part of 2457 // the value mapping? 2458 for (int I = 0; I != NumOps; ++I) { 2459 if (!MI.getOperand(I).isReg()) 2460 continue; 2461 2462 Register OpReg = MI.getOperand(I).getReg(); 2463 unsigned Size = getSizeInBits(OpReg, MRI, *TRI); 2464 2465 // FIXME: Probably need a new intrinsic register bank searchable table to 2466 // handle arbitrary intrinsics easily. 2467 // 2468 // If this has a sampler, it immediately follows rsrc. 2469 const bool MustBeSGPR = I == RsrcIdx || I == RsrcIdx + 1; 2470 2471 if (MustBeSGPR) { 2472 // If this must be an SGPR, so we must report whatever it is as legal. 2473 unsigned NewBank = getRegBankID(OpReg, MRI, *TRI, AMDGPU::SGPRRegBankID); 2474 OpdsMapping[I] = AMDGPU::getValueMapping(NewBank, Size); 2475 } else { 2476 // Some operands must be VGPR, and these are easy to copy to. 2477 OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 2478 } 2479 } 2480 2481 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), NumOps); 2482 } 2483 2484 /// Return the mapping for a pointer arugment. 2485 const RegisterBankInfo::ValueMapping * 2486 AMDGPURegisterBankInfo::getValueMappingForPtr(const MachineRegisterInfo &MRI, 2487 Register PtrReg) const { 2488 LLT PtrTy = MRI.getType(PtrReg); 2489 unsigned Size = PtrTy.getSizeInBits(); 2490 if (Subtarget.useFlatForGlobal() || 2491 !SITargetLowering::isFlatGlobalAddrSpace(PtrTy.getAddressSpace())) 2492 return AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 2493 2494 // If we're using MUBUF instructions for global memory, an SGPR base register 2495 // is possible. Otherwise this needs to be a VGPR. 2496 const RegisterBank *PtrBank = getRegBank(PtrReg, MRI, *TRI); 2497 return AMDGPU::getValueMapping(PtrBank->getID(), Size); 2498 } 2499 2500 const RegisterBankInfo::InstructionMapping & 2501 AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const { 2502 2503 const MachineFunction &MF = *MI.getParent()->getParent(); 2504 const MachineRegisterInfo &MRI = MF.getRegInfo(); 2505 SmallVector<const ValueMapping*, 2> OpdsMapping(2); 2506 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 2507 LLT LoadTy = MRI.getType(MI.getOperand(0).getReg()); 2508 Register PtrReg = MI.getOperand(1).getReg(); 2509 LLT PtrTy = MRI.getType(PtrReg); 2510 unsigned AS = PtrTy.getAddressSpace(); 2511 unsigned PtrSize = PtrTy.getSizeInBits(); 2512 2513 const ValueMapping *ValMapping; 2514 const ValueMapping *PtrMapping; 2515 2516 const RegisterBank *PtrBank = getRegBank(PtrReg, MRI, *TRI); 2517 2518 if (PtrBank == &AMDGPU::SGPRRegBank && 2519 SITargetLowering::isFlatGlobalAddrSpace(AS)) { 2520 if (isScalarLoadLegal(MI)) { 2521 // We have a uniform instruction so we want to use an SMRD load 2522 ValMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 2523 PtrMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize); 2524 } else { 2525 ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 2526 2527 // If we're using MUBUF instructions for global memory, an SGPR base 2528 // register is possible. Otherwise this needs to be a VGPR. 2529 unsigned PtrBankID = Subtarget.useFlatForGlobal() ? 2530 AMDGPU::VGPRRegBankID : AMDGPU::SGPRRegBankID; 2531 2532 PtrMapping = AMDGPU::getValueMapping(PtrBankID, PtrSize); 2533 ValMapping = AMDGPU::getValueMappingLoadSGPROnly(AMDGPU::VGPRRegBankID, 2534 LoadTy); 2535 } 2536 } else { 2537 ValMapping = AMDGPU::getValueMappingLoadSGPROnly(AMDGPU::VGPRRegBankID, LoadTy); 2538 PtrMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize); 2539 } 2540 2541 OpdsMapping[0] = ValMapping; 2542 OpdsMapping[1] = PtrMapping; 2543 const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping( 2544 1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands()); 2545 return Mapping; 2546 2547 // FIXME: Do we want to add a mapping for FLAT load, or should we just 2548 // handle that during instruction selection? 2549 } 2550 2551 unsigned 2552 AMDGPURegisterBankInfo::getRegBankID(Register Reg, 2553 const MachineRegisterInfo &MRI, 2554 const TargetRegisterInfo &TRI, 2555 unsigned Default) const { 2556 const RegisterBank *Bank = getRegBank(Reg, MRI, TRI); 2557 return Bank ? Bank->getID() : Default; 2558 } 2559 2560 2561 static unsigned regBankUnion(unsigned RB0, unsigned RB1) { 2562 return (RB0 == AMDGPU::SGPRRegBankID && RB1 == AMDGPU::SGPRRegBankID) ? 2563 AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID; 2564 } 2565 2566 static int regBankBoolUnion(int RB0, int RB1) { 2567 if (RB0 == -1) 2568 return RB1; 2569 if (RB1 == -1) 2570 return RB0; 2571 2572 // vcc, vcc -> vcc 2573 // vcc, sgpr -> vcc 2574 // vcc, vgpr -> vcc 2575 if (RB0 == AMDGPU::VCCRegBankID || RB1 == AMDGPU::VCCRegBankID) 2576 return AMDGPU::VCCRegBankID; 2577 2578 // vcc, vgpr -> vgpr 2579 return regBankUnion(RB0, RB1); 2580 } 2581 2582 const RegisterBankInfo::ValueMapping * 2583 AMDGPURegisterBankInfo::getSGPROpMapping(Register Reg, 2584 const MachineRegisterInfo &MRI, 2585 const TargetRegisterInfo &TRI) const { 2586 // Lie and claim anything is legal, even though this needs to be an SGPR 2587 // applyMapping will have to deal with it as a waterfall loop. 2588 unsigned Bank = getRegBankID(Reg, MRI, TRI, AMDGPU::SGPRRegBankID); 2589 unsigned Size = getSizeInBits(Reg, MRI, TRI); 2590 return AMDGPU::getValueMapping(Bank, Size); 2591 } 2592 2593 const RegisterBankInfo::ValueMapping * 2594 AMDGPURegisterBankInfo::getVGPROpMapping(Register Reg, 2595 const MachineRegisterInfo &MRI, 2596 const TargetRegisterInfo &TRI) const { 2597 unsigned Size = getSizeInBits(Reg, MRI, TRI); 2598 return AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 2599 } 2600 2601 const RegisterBankInfo::ValueMapping * 2602 AMDGPURegisterBankInfo::getAGPROpMapping(Register Reg, 2603 const MachineRegisterInfo &MRI, 2604 const TargetRegisterInfo &TRI) const { 2605 unsigned Size = getSizeInBits(Reg, MRI, TRI); 2606 return AMDGPU::getValueMapping(AMDGPU::AGPRRegBankID, Size); 2607 } 2608 2609 /// 2610 /// This function must return a legal mapping, because 2611 /// AMDGPURegisterBankInfo::getInstrAlternativeMappings() is not called 2612 /// in RegBankSelect::Mode::Fast. Any mapping that would cause a 2613 /// VGPR to SGPR generated is illegal. 2614 /// 2615 // Operands that must be SGPRs must accept potentially divergent VGPRs as 2616 // legal. These will be dealt with in applyMappingImpl. 2617 // 2618 const RegisterBankInfo::InstructionMapping & 2619 AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 2620 const MachineFunction &MF = *MI.getParent()->getParent(); 2621 const MachineRegisterInfo &MRI = MF.getRegInfo(); 2622 2623 if (MI.isRegSequence()) { 2624 // If any input is a VGPR, the result must be a VGPR. The default handling 2625 // assumes any copy between banks is legal. 2626 unsigned BankID = AMDGPU::SGPRRegBankID; 2627 2628 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) { 2629 auto OpBank = getRegBankID(MI.getOperand(I).getReg(), MRI, *TRI); 2630 // It doesn't make sense to use vcc or scc banks here, so just ignore 2631 // them. 2632 if (OpBank != AMDGPU::SGPRRegBankID) { 2633 BankID = AMDGPU::VGPRRegBankID; 2634 break; 2635 } 2636 } 2637 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 2638 2639 const ValueMapping &ValMap = getValueMapping(0, Size, getRegBank(BankID)); 2640 return getInstructionMapping( 2641 1, /*Cost*/ 1, 2642 /*OperandsMapping*/ getOperandsMapping({&ValMap}), 1); 2643 } 2644 2645 // The default handling is broken and doesn't handle illegal SGPR->VGPR copies 2646 // properly. 2647 // 2648 // TODO: There are additional exec masking dependencies to analyze. 2649 if (MI.getOpcode() == TargetOpcode::G_PHI) { 2650 // TODO: Generate proper invalid bank enum. 2651 int ResultBank = -1; 2652 Register DstReg = MI.getOperand(0).getReg(); 2653 2654 // Sometimes the result may have already been assigned a bank. 2655 if (const RegisterBank *DstBank = getRegBank(DstReg, MRI, *TRI)) 2656 ResultBank = DstBank->getID(); 2657 2658 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) { 2659 Register Reg = MI.getOperand(I).getReg(); 2660 const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI); 2661 2662 // FIXME: Assuming VGPR for any undetermined inputs. 2663 if (!Bank || Bank->getID() == AMDGPU::VGPRRegBankID) { 2664 ResultBank = AMDGPU::VGPRRegBankID; 2665 break; 2666 } 2667 2668 // FIXME: Need to promote SGPR case to s32 2669 unsigned OpBank = Bank->getID(); 2670 ResultBank = regBankBoolUnion(ResultBank, OpBank); 2671 } 2672 2673 assert(ResultBank != -1); 2674 2675 unsigned Size = MRI.getType(DstReg).getSizeInBits(); 2676 2677 const ValueMapping &ValMap = 2678 getValueMapping(0, Size, getRegBank(ResultBank)); 2679 return getInstructionMapping( 2680 1, /*Cost*/ 1, 2681 /*OperandsMapping*/ getOperandsMapping({&ValMap}), 1); 2682 } 2683 2684 const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); 2685 if (Mapping.isValid()) 2686 return Mapping; 2687 2688 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 2689 2690 switch (MI.getOpcode()) { 2691 default: 2692 return getInvalidInstructionMapping(); 2693 2694 case AMDGPU::G_AND: 2695 case AMDGPU::G_OR: 2696 case AMDGPU::G_XOR: { 2697 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 2698 if (Size == 1) { 2699 const RegisterBank *DstBank 2700 = getRegBank(MI.getOperand(0).getReg(), MRI, *TRI); 2701 2702 unsigned TargetBankID = -1; 2703 unsigned BankLHS = -1; 2704 unsigned BankRHS = -1; 2705 if (DstBank) { 2706 TargetBankID = DstBank->getID(); 2707 if (DstBank == &AMDGPU::VCCRegBank) { 2708 TargetBankID = AMDGPU::VCCRegBankID; 2709 BankLHS = AMDGPU::VCCRegBankID; 2710 BankRHS = AMDGPU::VCCRegBankID; 2711 } else { 2712 BankLHS = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI, 2713 AMDGPU::SGPRRegBankID); 2714 BankRHS = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI, 2715 AMDGPU::SGPRRegBankID); 2716 } 2717 } else { 2718 BankLHS = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI, 2719 AMDGPU::VCCRegBankID); 2720 BankRHS = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI, 2721 AMDGPU::VCCRegBankID); 2722 2723 // Both inputs should be true booleans to produce a boolean result. 2724 if (BankLHS == AMDGPU::VGPRRegBankID || BankRHS == AMDGPU::VGPRRegBankID) { 2725 TargetBankID = AMDGPU::VGPRRegBankID; 2726 } else if (BankLHS == AMDGPU::VCCRegBankID || BankRHS == AMDGPU::VCCRegBankID) { 2727 TargetBankID = AMDGPU::VCCRegBankID; 2728 BankLHS = AMDGPU::VCCRegBankID; 2729 BankRHS = AMDGPU::VCCRegBankID; 2730 } else if (BankLHS == AMDGPU::SGPRRegBankID && BankRHS == AMDGPU::SGPRRegBankID) { 2731 TargetBankID = AMDGPU::SGPRRegBankID; 2732 } 2733 } 2734 2735 OpdsMapping[0] = AMDGPU::getValueMapping(TargetBankID, Size); 2736 OpdsMapping[1] = AMDGPU::getValueMapping(BankLHS, Size); 2737 OpdsMapping[2] = AMDGPU::getValueMapping(BankRHS, Size); 2738 break; 2739 } 2740 2741 if (Size == 64) { 2742 2743 if (isSALUMapping(MI)) { 2744 OpdsMapping[0] = getValueMappingSGPR64Only(AMDGPU::SGPRRegBankID, Size); 2745 OpdsMapping[1] = OpdsMapping[2] = OpdsMapping[0]; 2746 } else { 2747 OpdsMapping[0] = getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size); 2748 unsigned Bank1 = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI/*, DefaultBankID*/); 2749 OpdsMapping[1] = AMDGPU::getValueMapping(Bank1, Size); 2750 2751 unsigned Bank2 = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI/*, DefaultBankID*/); 2752 OpdsMapping[2] = AMDGPU::getValueMapping(Bank2, Size); 2753 } 2754 2755 break; 2756 } 2757 2758 LLVM_FALLTHROUGH; 2759 } 2760 case AMDGPU::G_PTR_ADD: 2761 case AMDGPU::G_ADD: 2762 case AMDGPU::G_SUB: 2763 case AMDGPU::G_MUL: 2764 case AMDGPU::G_SHL: 2765 case AMDGPU::G_LSHR: 2766 case AMDGPU::G_ASHR: 2767 case AMDGPU::G_UADDO: 2768 case AMDGPU::G_USUBO: 2769 case AMDGPU::G_UADDE: 2770 case AMDGPU::G_SADDE: 2771 case AMDGPU::G_USUBE: 2772 case AMDGPU::G_SSUBE: 2773 case AMDGPU::G_SMIN: 2774 case AMDGPU::G_SMAX: 2775 case AMDGPU::G_UMIN: 2776 case AMDGPU::G_UMAX: 2777 if (isSALUMapping(MI)) 2778 return getDefaultMappingSOP(MI); 2779 LLVM_FALLTHROUGH; 2780 2781 case AMDGPU::G_FADD: 2782 case AMDGPU::G_FSUB: 2783 case AMDGPU::G_FPTOSI: 2784 case AMDGPU::G_FPTOUI: 2785 case AMDGPU::G_FMUL: 2786 case AMDGPU::G_FMA: 2787 case AMDGPU::G_FMAD: 2788 case AMDGPU::G_FSQRT: 2789 case AMDGPU::G_FFLOOR: 2790 case AMDGPU::G_FCEIL: 2791 case AMDGPU::G_FRINT: 2792 case AMDGPU::G_SITOFP: 2793 case AMDGPU::G_UITOFP: 2794 case AMDGPU::G_FPTRUNC: 2795 case AMDGPU::G_FPEXT: 2796 case AMDGPU::G_FEXP2: 2797 case AMDGPU::G_FLOG2: 2798 case AMDGPU::G_FMINNUM: 2799 case AMDGPU::G_FMAXNUM: 2800 case AMDGPU::G_FMINNUM_IEEE: 2801 case AMDGPU::G_FMAXNUM_IEEE: 2802 case AMDGPU::G_FCANONICALIZE: 2803 case AMDGPU::G_INTRINSIC_TRUNC: 2804 case AMDGPU::G_AMDGPU_FFBH_U32: 2805 case AMDGPU::G_AMDGPU_FMIN_LEGACY: 2806 case AMDGPU::G_AMDGPU_FMAX_LEGACY: 2807 return getDefaultMappingVOP(MI); 2808 case AMDGPU::G_UMULH: 2809 case AMDGPU::G_SMULH: { 2810 if (Subtarget.hasScalarMulHiInsts() && isSALUMapping(MI)) 2811 return getDefaultMappingSOP(MI); 2812 return getDefaultMappingVOP(MI); 2813 } 2814 case AMDGPU::G_IMPLICIT_DEF: { 2815 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 2816 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 2817 break; 2818 } 2819 case AMDGPU::G_FCONSTANT: 2820 case AMDGPU::G_CONSTANT: 2821 case AMDGPU::G_GLOBAL_VALUE: 2822 case AMDGPU::G_BLOCK_ADDR: 2823 case AMDGPU::G_READCYCLECOUNTER: { 2824 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 2825 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 2826 break; 2827 } 2828 case AMDGPU::G_FRAME_INDEX: { 2829 // TODO: This should be the same as other constants, but eliminateFrameIndex 2830 // currently assumes VALU uses. 2831 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 2832 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 2833 break; 2834 } 2835 case AMDGPU::G_INSERT: { 2836 unsigned BankID = isSALUMapping(MI) ? AMDGPU::SGPRRegBankID : 2837 AMDGPU::VGPRRegBankID; 2838 unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 2839 unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 2840 unsigned EltSize = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI); 2841 OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize); 2842 OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize); 2843 OpdsMapping[2] = AMDGPU::getValueMapping(BankID, EltSize); 2844 OpdsMapping[3] = nullptr; 2845 break; 2846 } 2847 case AMDGPU::G_EXTRACT: { 2848 unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI); 2849 unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 2850 unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 2851 OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize); 2852 OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize); 2853 OpdsMapping[2] = nullptr; 2854 break; 2855 } 2856 case AMDGPU::G_BUILD_VECTOR: 2857 case AMDGPU::G_BUILD_VECTOR_TRUNC: { 2858 LLT DstTy = MRI.getType(MI.getOperand(0).getReg()); 2859 if (DstTy == LLT::vector(2, 16)) { 2860 unsigned DstSize = DstTy.getSizeInBits(); 2861 unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 2862 unsigned Src0BankID = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI); 2863 unsigned Src1BankID = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI); 2864 unsigned DstBankID = regBankUnion(Src0BankID, Src1BankID); 2865 2866 OpdsMapping[0] = AMDGPU::getValueMapping(DstBankID, DstSize); 2867 OpdsMapping[1] = AMDGPU::getValueMapping(Src0BankID, SrcSize); 2868 OpdsMapping[2] = AMDGPU::getValueMapping(Src1BankID, SrcSize); 2869 break; 2870 } 2871 2872 LLVM_FALLTHROUGH; 2873 } 2874 case AMDGPU::G_MERGE_VALUES: 2875 case AMDGPU::G_CONCAT_VECTORS: { 2876 unsigned Bank = isSALUMapping(MI) ? 2877 AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID; 2878 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 2879 unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 2880 2881 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize); 2882 // Op1 and Dst should use the same register bank. 2883 for (unsigned i = 1, e = MI.getNumOperands(); i != e; ++i) 2884 OpdsMapping[i] = AMDGPU::getValueMapping(Bank, SrcSize); 2885 break; 2886 } 2887 case AMDGPU::G_BITCAST: 2888 case AMDGPU::G_INTTOPTR: 2889 case AMDGPU::G_PTRTOINT: 2890 case AMDGPU::G_CTLZ: 2891 case AMDGPU::G_CTLZ_ZERO_UNDEF: 2892 case AMDGPU::G_CTTZ: 2893 case AMDGPU::G_CTTZ_ZERO_UNDEF: 2894 case AMDGPU::G_CTPOP: 2895 case AMDGPU::G_BSWAP: 2896 case AMDGPU::G_BITREVERSE: 2897 case AMDGPU::G_FABS: 2898 case AMDGPU::G_FNEG: { 2899 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 2900 unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI); 2901 OpdsMapping[0] = OpdsMapping[1] = AMDGPU::getValueMapping(BankID, Size); 2902 break; 2903 } 2904 case AMDGPU::G_TRUNC: { 2905 Register Dst = MI.getOperand(0).getReg(); 2906 Register Src = MI.getOperand(1).getReg(); 2907 unsigned Bank = getRegBankID(Src, MRI, *TRI); 2908 unsigned DstSize = getSizeInBits(Dst, MRI, *TRI); 2909 unsigned SrcSize = getSizeInBits(Src, MRI, *TRI); 2910 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize); 2911 OpdsMapping[1] = AMDGPU::getValueMapping(Bank, SrcSize); 2912 break; 2913 } 2914 case AMDGPU::G_ZEXT: 2915 case AMDGPU::G_SEXT: 2916 case AMDGPU::G_ANYEXT: { 2917 Register Dst = MI.getOperand(0).getReg(); 2918 Register Src = MI.getOperand(1).getReg(); 2919 unsigned DstSize = getSizeInBits(Dst, MRI, *TRI); 2920 unsigned SrcSize = getSizeInBits(Src, MRI, *TRI); 2921 2922 unsigned DstBank; 2923 const RegisterBank *SrcBank = getRegBank(Src, MRI, *TRI); 2924 assert(SrcBank); 2925 switch (SrcBank->getID()) { 2926 case AMDGPU::SGPRRegBankID: 2927 DstBank = AMDGPU::SGPRRegBankID; 2928 break; 2929 default: 2930 DstBank = AMDGPU::VGPRRegBankID; 2931 break; 2932 } 2933 2934 // TODO: Should anyext be split into 32-bit part as well? 2935 if (MI.getOpcode() == AMDGPU::G_ANYEXT) { 2936 OpdsMapping[0] = AMDGPU::getValueMapping(DstBank, DstSize); 2937 OpdsMapping[1] = AMDGPU::getValueMapping(SrcBank->getID(), SrcSize); 2938 } else { 2939 // Scalar extend can use 64-bit BFE, but VGPRs require extending to 2940 // 32-bits, and then to 64. 2941 OpdsMapping[0] = AMDGPU::getValueMappingSGPR64Only(DstBank, DstSize); 2942 OpdsMapping[1] = AMDGPU::getValueMappingSGPR64Only(SrcBank->getID(), 2943 SrcSize); 2944 } 2945 break; 2946 } 2947 case AMDGPU::G_FCMP: { 2948 unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 2949 unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI); 2950 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 2951 OpdsMapping[1] = nullptr; // Predicate Operand. 2952 OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size); 2953 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 2954 break; 2955 } 2956 case AMDGPU::G_STORE: { 2957 assert(MI.getOperand(0).isReg()); 2958 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 2959 2960 // FIXME: We need to specify a different reg bank once scalar stores are 2961 // supported. 2962 const ValueMapping *ValMapping = 2963 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 2964 OpdsMapping[0] = ValMapping; 2965 OpdsMapping[1] = getValueMappingForPtr(MRI, MI.getOperand(1).getReg()); 2966 break; 2967 } 2968 case AMDGPU::G_ICMP: { 2969 auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()); 2970 unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 2971 unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI); 2972 unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, *TRI); 2973 2974 bool CanUseSCC = Op2Bank == AMDGPU::SGPRRegBankID && 2975 Op3Bank == AMDGPU::SGPRRegBankID && 2976 (Size == 32 || (Size == 64 && 2977 (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) && 2978 Subtarget.hasScalarCompareEq64())); 2979 2980 unsigned Op0Bank = CanUseSCC ? AMDGPU::SGPRRegBankID : AMDGPU::VCCRegBankID; 2981 2982 // TODO: Use 32-bit for scalar output size. 2983 // SCC results will need to be copied to a 32-bit SGPR virtual register. 2984 const unsigned ResultSize = 1; 2985 2986 OpdsMapping[0] = AMDGPU::getValueMapping(Op0Bank, ResultSize); 2987 OpdsMapping[1] = nullptr; // Predicate Operand. 2988 OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size); 2989 OpdsMapping[3] = AMDGPU::getValueMapping(Op3Bank, Size); 2990 break; 2991 } 2992 case AMDGPU::G_EXTRACT_VECTOR_ELT: { 2993 // VGPR index can be used for waterfall when indexing a SGPR vector. 2994 unsigned SrcBankID = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI); 2995 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 2996 unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 2997 unsigned IdxSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 2998 unsigned IdxBank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI); 2999 unsigned OutputBankID = regBankUnion(SrcBankID, IdxBank); 3000 3001 OpdsMapping[0] = AMDGPU::getValueMappingSGPR64Only(OutputBankID, DstSize); 3002 OpdsMapping[1] = AMDGPU::getValueMapping(SrcBankID, SrcSize); 3003 3004 // The index can be either if the source vector is VGPR. 3005 OpdsMapping[2] = AMDGPU::getValueMapping(IdxBank, IdxSize); 3006 break; 3007 } 3008 case AMDGPU::G_INSERT_VECTOR_ELT: { 3009 unsigned OutputBankID = isSALUMapping(MI) ? 3010 AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID; 3011 3012 unsigned VecSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3013 unsigned InsertSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3014 unsigned IdxSize = MRI.getType(MI.getOperand(3).getReg()).getSizeInBits(); 3015 unsigned InsertEltBankID = getRegBankID(MI.getOperand(2).getReg(), 3016 MRI, *TRI); 3017 unsigned IdxBankID = getRegBankID(MI.getOperand(3).getReg(), MRI, *TRI); 3018 3019 OpdsMapping[0] = AMDGPU::getValueMapping(OutputBankID, VecSize); 3020 OpdsMapping[1] = AMDGPU::getValueMapping(OutputBankID, VecSize); 3021 3022 // This is a weird case, because we need to break down the mapping based on 3023 // the register bank of a different operand. 3024 if (InsertSize == 64 && OutputBankID == AMDGPU::VGPRRegBankID) { 3025 OpdsMapping[2] = AMDGPU::getValueMappingSplit64(InsertEltBankID, 3026 InsertSize); 3027 } else { 3028 assert(InsertSize == 32 || InsertSize == 64); 3029 OpdsMapping[2] = AMDGPU::getValueMapping(InsertEltBankID, InsertSize); 3030 } 3031 3032 // The index can be either if the source vector is VGPR. 3033 OpdsMapping[3] = AMDGPU::getValueMapping(IdxBankID, IdxSize); 3034 break; 3035 } 3036 case AMDGPU::G_UNMERGE_VALUES: { 3037 unsigned Bank = isSALUMapping(MI) ? AMDGPU::SGPRRegBankID : 3038 AMDGPU::VGPRRegBankID; 3039 3040 // Op1 and Dst should use the same register bank. 3041 // FIXME: Shouldn't this be the default? Why do we need to handle this? 3042 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 3043 unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI); 3044 OpdsMapping[i] = AMDGPU::getValueMapping(Bank, Size); 3045 } 3046 break; 3047 } 3048 case AMDGPU::G_AMDGPU_BUFFER_LOAD: 3049 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE: 3050 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE: 3051 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT: 3052 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT: 3053 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT: 3054 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT_D16: 3055 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT: 3056 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT_D16: 3057 case AMDGPU::G_AMDGPU_BUFFER_STORE: 3058 case AMDGPU::G_AMDGPU_BUFFER_STORE_BYTE: 3059 case AMDGPU::G_AMDGPU_BUFFER_STORE_SHORT: 3060 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT: 3061 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT_D16: { 3062 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3063 3064 // rsrc 3065 OpdsMapping[1] = getSGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3066 3067 // vindex 3068 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3069 3070 // voffset 3071 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3072 3073 // soffset 3074 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3075 3076 // Any remaining operands are immediates and were correctly null 3077 // initialized. 3078 break; 3079 } 3080 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SWAP: 3081 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_ADD: 3082 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SUB: 3083 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMIN: 3084 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMIN: 3085 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMAX: 3086 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMAX: 3087 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_AND: 3088 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_OR: 3089 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_XOR: 3090 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_INC: 3091 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_DEC: { 3092 // vdata_out 3093 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3094 3095 // vdata_in 3096 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3097 3098 // rsrc 3099 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3100 3101 // vindex 3102 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3103 3104 // voffset 3105 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3106 3107 // soffset 3108 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 3109 3110 // Any remaining operands are immediates and were correctly null 3111 // initialized. 3112 break; 3113 } 3114 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_CMPSWAP: { 3115 // vdata_out 3116 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3117 3118 // vdata_in 3119 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3120 3121 // cmp 3122 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3123 3124 // rsrc 3125 OpdsMapping[3] = getSGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3126 3127 // vindex 3128 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3129 3130 // voffset 3131 OpdsMapping[5] = getVGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 3132 3133 // soffset 3134 OpdsMapping[6] = getSGPROpMapping(MI.getOperand(6).getReg(), MRI, *TRI); 3135 3136 // Any remaining operands are immediates and were correctly null 3137 // initialized. 3138 break; 3139 } 3140 case AMDGPU::G_INTRINSIC: { 3141 switch (MI.getIntrinsicID()) { 3142 default: 3143 return getInvalidInstructionMapping(); 3144 case Intrinsic::amdgcn_div_fmas: 3145 case Intrinsic::amdgcn_div_fixup: 3146 case Intrinsic::amdgcn_trig_preop: 3147 case Intrinsic::amdgcn_sin: 3148 case Intrinsic::amdgcn_cos: 3149 case Intrinsic::amdgcn_log_clamp: 3150 case Intrinsic::amdgcn_rcp: 3151 case Intrinsic::amdgcn_rcp_legacy: 3152 case Intrinsic::amdgcn_rsq: 3153 case Intrinsic::amdgcn_rsq_legacy: 3154 case Intrinsic::amdgcn_rsq_clamp: 3155 case Intrinsic::amdgcn_fmul_legacy: 3156 case Intrinsic::amdgcn_ldexp: 3157 case Intrinsic::amdgcn_frexp_mant: 3158 case Intrinsic::amdgcn_frexp_exp: 3159 case Intrinsic::amdgcn_fract: 3160 case Intrinsic::amdgcn_cvt_pkrtz: 3161 case Intrinsic::amdgcn_cvt_pknorm_i16: 3162 case Intrinsic::amdgcn_cvt_pknorm_u16: 3163 case Intrinsic::amdgcn_cvt_pk_i16: 3164 case Intrinsic::amdgcn_cvt_pk_u16: 3165 case Intrinsic::amdgcn_fmed3: 3166 case Intrinsic::amdgcn_cubeid: 3167 case Intrinsic::amdgcn_cubema: 3168 case Intrinsic::amdgcn_cubesc: 3169 case Intrinsic::amdgcn_cubetc: 3170 case Intrinsic::amdgcn_sffbh: 3171 case Intrinsic::amdgcn_fmad_ftz: 3172 case Intrinsic::amdgcn_mbcnt_lo: 3173 case Intrinsic::amdgcn_mbcnt_hi: 3174 case Intrinsic::amdgcn_ubfe: 3175 case Intrinsic::amdgcn_sbfe: 3176 case Intrinsic::amdgcn_mul_u24: 3177 case Intrinsic::amdgcn_mul_i24: 3178 case Intrinsic::amdgcn_lerp: 3179 case Intrinsic::amdgcn_sad_u8: 3180 case Intrinsic::amdgcn_msad_u8: 3181 case Intrinsic::amdgcn_sad_hi_u8: 3182 case Intrinsic::amdgcn_sad_u16: 3183 case Intrinsic::amdgcn_qsad_pk_u16_u8: 3184 case Intrinsic::amdgcn_mqsad_pk_u16_u8: 3185 case Intrinsic::amdgcn_mqsad_u32_u8: 3186 case Intrinsic::amdgcn_cvt_pk_u8_f32: 3187 case Intrinsic::amdgcn_alignbit: 3188 case Intrinsic::amdgcn_alignbyte: 3189 case Intrinsic::amdgcn_fdot2: 3190 case Intrinsic::amdgcn_sdot2: 3191 case Intrinsic::amdgcn_udot2: 3192 case Intrinsic::amdgcn_sdot4: 3193 case Intrinsic::amdgcn_udot4: 3194 case Intrinsic::amdgcn_sdot8: 3195 case Intrinsic::amdgcn_udot8: 3196 return getDefaultMappingVOP(MI); 3197 case Intrinsic::amdgcn_ds_swizzle: 3198 case Intrinsic::amdgcn_ds_permute: 3199 case Intrinsic::amdgcn_ds_bpermute: 3200 case Intrinsic::amdgcn_update_dpp: 3201 case Intrinsic::amdgcn_mov_dpp8: 3202 case Intrinsic::amdgcn_mov_dpp: 3203 case Intrinsic::amdgcn_wwm: 3204 case Intrinsic::amdgcn_wqm: 3205 case Intrinsic::amdgcn_softwqm: 3206 return getDefaultMappingAllVGPR(MI); 3207 case Intrinsic::amdgcn_kernarg_segment_ptr: 3208 case Intrinsic::amdgcn_s_getpc: 3209 case Intrinsic::amdgcn_groupstaticsize: { 3210 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3211 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3212 break; 3213 } 3214 case Intrinsic::amdgcn_wqm_vote: { 3215 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3216 OpdsMapping[0] = OpdsMapping[2] 3217 = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Size); 3218 break; 3219 } 3220 case Intrinsic::amdgcn_ps_live: { 3221 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 3222 break; 3223 } 3224 case Intrinsic::amdgcn_s_buffer_load: { 3225 // FIXME: This should be moved to G_INTRINSIC_W_SIDE_EFFECTS 3226 Register RSrc = MI.getOperand(2).getReg(); // SGPR 3227 Register Offset = MI.getOperand(3).getReg(); // SGPR/imm 3228 3229 unsigned Size0 = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3230 unsigned Size2 = MRI.getType(RSrc).getSizeInBits(); 3231 unsigned Size3 = MRI.getType(Offset).getSizeInBits(); 3232 3233 unsigned RSrcBank = getRegBankID(RSrc, MRI, *TRI); 3234 unsigned OffsetBank = getRegBankID(Offset, MRI, *TRI); 3235 3236 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size0); 3237 OpdsMapping[1] = nullptr; // intrinsic id 3238 3239 // Lie and claim everything is legal, even though some need to be 3240 // SGPRs. applyMapping will have to deal with it as a waterfall loop. 3241 OpdsMapping[2] = AMDGPU::getValueMapping(RSrcBank, Size2); // rsrc 3242 OpdsMapping[3] = AMDGPU::getValueMapping(OffsetBank, Size3); 3243 OpdsMapping[4] = nullptr; 3244 break; 3245 } 3246 case Intrinsic::amdgcn_div_scale: { 3247 unsigned Dst0Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3248 unsigned Dst1Size = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 3249 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Dst0Size); 3250 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Dst1Size); 3251 3252 unsigned SrcSize = MRI.getType(MI.getOperand(3).getReg()).getSizeInBits(); 3253 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 3254 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 3255 break; 3256 } 3257 case Intrinsic::amdgcn_class: { 3258 Register Src0Reg = MI.getOperand(2).getReg(); 3259 Register Src1Reg = MI.getOperand(3).getReg(); 3260 unsigned Src0Size = MRI.getType(Src0Reg).getSizeInBits(); 3261 unsigned Src1Size = MRI.getType(Src1Reg).getSizeInBits(); 3262 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3263 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, DstSize); 3264 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Src0Size); 3265 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Src1Size); 3266 break; 3267 } 3268 case Intrinsic::amdgcn_icmp: 3269 case Intrinsic::amdgcn_fcmp: { 3270 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3271 // This is not VCCRegBank because this is not used in boolean contexts. 3272 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, DstSize); 3273 unsigned OpSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3274 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, OpSize); 3275 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, OpSize); 3276 break; 3277 } 3278 case Intrinsic::amdgcn_readlane: { 3279 // This must be an SGPR, but accept a VGPR. 3280 Register IdxReg = MI.getOperand(3).getReg(); 3281 unsigned IdxSize = MRI.getType(IdxReg).getSizeInBits(); 3282 unsigned IdxBank = getRegBankID(IdxReg, MRI, *TRI, AMDGPU::SGPRRegBankID); 3283 OpdsMapping[3] = AMDGPU::getValueMapping(IdxBank, IdxSize); 3284 LLVM_FALLTHROUGH; 3285 } 3286 case Intrinsic::amdgcn_readfirstlane: { 3287 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3288 unsigned SrcSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3289 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, DstSize); 3290 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 3291 break; 3292 } 3293 case Intrinsic::amdgcn_writelane: { 3294 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3295 Register SrcReg = MI.getOperand(2).getReg(); 3296 unsigned SrcSize = MRI.getType(SrcReg).getSizeInBits(); 3297 unsigned SrcBank = getRegBankID(SrcReg, MRI, *TRI, AMDGPU::SGPRRegBankID); 3298 Register IdxReg = MI.getOperand(3).getReg(); 3299 unsigned IdxSize = MRI.getType(IdxReg).getSizeInBits(); 3300 unsigned IdxBank = getRegBankID(IdxReg, MRI, *TRI, AMDGPU::SGPRRegBankID); 3301 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 3302 3303 // These 2 must be SGPRs, but accept VGPRs. Readfirstlane will be inserted 3304 // to legalize. 3305 OpdsMapping[2] = AMDGPU::getValueMapping(SrcBank, SrcSize); 3306 OpdsMapping[3] = AMDGPU::getValueMapping(IdxBank, IdxSize); 3307 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 3308 break; 3309 } 3310 case Intrinsic::amdgcn_if_break: { 3311 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3312 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3313 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 3314 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3315 break; 3316 } 3317 case Intrinsic::amdgcn_permlane16: 3318 case Intrinsic::amdgcn_permlanex16: { 3319 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3320 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3321 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3322 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3323 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3324 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3325 break; 3326 } 3327 case Intrinsic::amdgcn_mfma_f32_4x4x1f32: 3328 case Intrinsic::amdgcn_mfma_f32_4x4x4f16: 3329 case Intrinsic::amdgcn_mfma_i32_4x4x4i8: 3330 case Intrinsic::amdgcn_mfma_f32_4x4x2bf16: 3331 case Intrinsic::amdgcn_mfma_f32_16x16x1f32: 3332 case Intrinsic::amdgcn_mfma_f32_16x16x4f32: 3333 case Intrinsic::amdgcn_mfma_f32_16x16x4f16: 3334 case Intrinsic::amdgcn_mfma_f32_16x16x16f16: 3335 case Intrinsic::amdgcn_mfma_i32_16x16x4i8: 3336 case Intrinsic::amdgcn_mfma_i32_16x16x16i8: 3337 case Intrinsic::amdgcn_mfma_f32_16x16x2bf16: 3338 case Intrinsic::amdgcn_mfma_f32_16x16x8bf16: 3339 case Intrinsic::amdgcn_mfma_f32_32x32x1f32: 3340 case Intrinsic::amdgcn_mfma_f32_32x32x2f32: 3341 case Intrinsic::amdgcn_mfma_f32_32x32x4f16: 3342 case Intrinsic::amdgcn_mfma_f32_32x32x8f16: 3343 case Intrinsic::amdgcn_mfma_i32_32x32x4i8: 3344 case Intrinsic::amdgcn_mfma_i32_32x32x8i8: 3345 case Intrinsic::amdgcn_mfma_f32_32x32x2bf16: 3346 case Intrinsic::amdgcn_mfma_f32_32x32x4bf16: { 3347 // Default for MAI intrinsics. 3348 // srcC can also be an immediate which can be folded later. 3349 // FIXME: Should we eventually add an alternative mapping with AGPR src 3350 // for srcA/srcB? 3351 // 3352 // vdst, srcA, srcB, srcC 3353 OpdsMapping[0] = getAGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3354 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3355 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3356 OpdsMapping[4] = getAGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3357 break; 3358 } 3359 case Intrinsic::amdgcn_interp_p1: 3360 case Intrinsic::amdgcn_interp_p2: 3361 case Intrinsic::amdgcn_interp_mov: 3362 case Intrinsic::amdgcn_interp_p1_f16: 3363 case Intrinsic::amdgcn_interp_p2_f16: { 3364 const int M0Idx = MI.getNumOperands() - 1; 3365 Register M0Reg = MI.getOperand(M0Idx).getReg(); 3366 unsigned M0Bank = getRegBankID(M0Reg, MRI, *TRI, AMDGPU::SGPRRegBankID); 3367 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3368 3369 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 3370 for (int I = 2; I != M0Idx && MI.getOperand(I).isReg(); ++I) 3371 OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 3372 3373 // Must be SGPR, but we must take whatever the original bank is and fix it 3374 // later. 3375 OpdsMapping[M0Idx] = AMDGPU::getValueMapping(M0Bank, 32); 3376 break; 3377 } 3378 } 3379 break; 3380 } 3381 case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: { 3382 auto IntrID = MI.getIntrinsicID(); 3383 switch (IntrID) { 3384 case Intrinsic::amdgcn_s_getreg: 3385 case Intrinsic::amdgcn_s_memtime: 3386 case Intrinsic::amdgcn_s_memrealtime: 3387 case Intrinsic::amdgcn_s_get_waveid_in_workgroup: { 3388 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3389 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3390 break; 3391 } 3392 case Intrinsic::amdgcn_ds_fadd: 3393 case Intrinsic::amdgcn_ds_fmin: 3394 case Intrinsic::amdgcn_ds_fmax: 3395 return getDefaultMappingAllVGPR(MI); 3396 case Intrinsic::amdgcn_ds_ordered_add: 3397 case Intrinsic::amdgcn_ds_ordered_swap: { 3398 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3399 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 3400 unsigned M0Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI, 3401 AMDGPU::SGPRRegBankID); 3402 OpdsMapping[2] = AMDGPU::getValueMapping(M0Bank, 32); 3403 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 3404 break; 3405 } 3406 case Intrinsic::amdgcn_ds_append: 3407 case Intrinsic::amdgcn_ds_consume: { 3408 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3409 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 3410 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3411 break; 3412 } 3413 case Intrinsic::amdgcn_exp_compr: 3414 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 3415 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 3416 break; 3417 case Intrinsic::amdgcn_exp: 3418 // FIXME: Could we support packed types here? 3419 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 3420 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 3421 OpdsMapping[5] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 3422 OpdsMapping[6] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 3423 break; 3424 case Intrinsic::amdgcn_s_sendmsg: 3425 case Intrinsic::amdgcn_s_sendmsghalt: { 3426 // This must be an SGPR, but accept a VGPR. 3427 unsigned Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI, 3428 AMDGPU::SGPRRegBankID); 3429 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, 32); 3430 break; 3431 } 3432 case Intrinsic::amdgcn_end_cf: 3433 case Intrinsic::amdgcn_init_exec: { 3434 unsigned Size = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 3435 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3436 break; 3437 } 3438 case Intrinsic::amdgcn_else: { 3439 unsigned WaveSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 3440 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 3441 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, WaveSize); 3442 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, WaveSize); 3443 break; 3444 } 3445 case Intrinsic::amdgcn_kill: { 3446 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 3447 break; 3448 } 3449 case Intrinsic::amdgcn_raw_buffer_load: 3450 case Intrinsic::amdgcn_raw_tbuffer_load: { 3451 // FIXME: Should make intrinsic ID the last operand of the instruction, 3452 // then this would be the same as store 3453 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3454 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3455 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3456 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3457 break; 3458 } 3459 case Intrinsic::amdgcn_raw_buffer_store: 3460 case Intrinsic::amdgcn_raw_buffer_store_format: 3461 case Intrinsic::amdgcn_raw_tbuffer_store: { 3462 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3463 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3464 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3465 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3466 break; 3467 } 3468 case Intrinsic::amdgcn_struct_buffer_load: 3469 case Intrinsic::amdgcn_struct_tbuffer_load: { 3470 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3471 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3472 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3473 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3474 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 3475 break; 3476 } 3477 case Intrinsic::amdgcn_struct_buffer_store: 3478 case Intrinsic::amdgcn_struct_tbuffer_store: { 3479 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3480 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3481 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3482 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3483 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 3484 break; 3485 } 3486 case Intrinsic::amdgcn_init_exec_from_input: { 3487 unsigned Size = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 3488 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3489 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3490 break; 3491 } 3492 case Intrinsic::amdgcn_ds_gws_init: 3493 case Intrinsic::amdgcn_ds_gws_barrier: 3494 case Intrinsic::amdgcn_ds_gws_sema_br: { 3495 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 3496 3497 // This must be an SGPR, but accept a VGPR. 3498 unsigned Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI, 3499 AMDGPU::SGPRRegBankID); 3500 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, 32); 3501 break; 3502 } 3503 case Intrinsic::amdgcn_ds_gws_sema_v: 3504 case Intrinsic::amdgcn_ds_gws_sema_p: 3505 case Intrinsic::amdgcn_ds_gws_sema_release_all: { 3506 // This must be an SGPR, but accept a VGPR. 3507 unsigned Bank = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI, 3508 AMDGPU::SGPRRegBankID); 3509 OpdsMapping[1] = AMDGPU::getValueMapping(Bank, 32); 3510 break; 3511 } 3512 default: 3513 if (const AMDGPU::RsrcIntrinsic *RSrcIntrin = 3514 AMDGPU::lookupRsrcIntrinsic(IntrID)) { 3515 // Non-images can have complications from operands that allow both SGPR 3516 // and VGPR. For now it's too complicated to figure out the final opcode 3517 // to derive the register bank from the MCInstrDesc. 3518 if (RSrcIntrin->IsImage) 3519 return getImageMapping(MRI, MI, RSrcIntrin->RsrcArg); 3520 } 3521 3522 return getInvalidInstructionMapping(); 3523 } 3524 break; 3525 } 3526 case AMDGPU::G_SELECT: { 3527 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3528 unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, *TRI, 3529 AMDGPU::SGPRRegBankID); 3530 unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, *TRI, 3531 AMDGPU::SGPRRegBankID); 3532 bool SGPRSrcs = Op2Bank == AMDGPU::SGPRRegBankID && 3533 Op3Bank == AMDGPU::SGPRRegBankID; 3534 3535 unsigned CondBankDefault = SGPRSrcs ? 3536 AMDGPU::SGPRRegBankID : AMDGPU::VCCRegBankID; 3537 unsigned CondBank = getRegBankID(MI.getOperand(1).getReg(), MRI, *TRI, 3538 CondBankDefault); 3539 if (CondBank == AMDGPU::SGPRRegBankID) 3540 CondBank = SGPRSrcs ? AMDGPU::SGPRRegBankID : AMDGPU::VCCRegBankID; 3541 else if (CondBank == AMDGPU::VGPRRegBankID) 3542 CondBank = AMDGPU::VCCRegBankID; 3543 3544 unsigned Bank = SGPRSrcs && CondBank == AMDGPU::SGPRRegBankID ? 3545 AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID; 3546 3547 assert(CondBank == AMDGPU::VCCRegBankID || CondBank == AMDGPU::SGPRRegBankID); 3548 3549 // TODO: Should report 32-bit for scalar condition type. 3550 if (Size == 64) { 3551 OpdsMapping[0] = AMDGPU::getValueMappingSGPR64Only(Bank, Size); 3552 OpdsMapping[1] = AMDGPU::getValueMapping(CondBank, 1); 3553 OpdsMapping[2] = AMDGPU::getValueMappingSGPR64Only(Bank, Size); 3554 OpdsMapping[3] = AMDGPU::getValueMappingSGPR64Only(Bank, Size); 3555 } else { 3556 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, Size); 3557 OpdsMapping[1] = AMDGPU::getValueMapping(CondBank, 1); 3558 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, Size); 3559 OpdsMapping[3] = AMDGPU::getValueMapping(Bank, Size); 3560 } 3561 3562 break; 3563 } 3564 3565 case AMDGPU::G_LOAD: 3566 case AMDGPU::G_ZEXTLOAD: 3567 case AMDGPU::G_SEXTLOAD: 3568 return getInstrMappingForLoad(MI); 3569 3570 case AMDGPU::G_ATOMICRMW_XCHG: 3571 case AMDGPU::G_ATOMICRMW_ADD: 3572 case AMDGPU::G_ATOMICRMW_SUB: 3573 case AMDGPU::G_ATOMICRMW_AND: 3574 case AMDGPU::G_ATOMICRMW_OR: 3575 case AMDGPU::G_ATOMICRMW_XOR: 3576 case AMDGPU::G_ATOMICRMW_MAX: 3577 case AMDGPU::G_ATOMICRMW_MIN: 3578 case AMDGPU::G_ATOMICRMW_UMAX: 3579 case AMDGPU::G_ATOMICRMW_UMIN: 3580 case AMDGPU::G_ATOMICRMW_FADD: 3581 case AMDGPU::G_AMDGPU_ATOMIC_CMPXCHG: 3582 case AMDGPU::G_AMDGPU_ATOMIC_INC: 3583 case AMDGPU::G_AMDGPU_ATOMIC_DEC: { 3584 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3585 OpdsMapping[1] = getValueMappingForPtr(MRI, MI.getOperand(1).getReg()); 3586 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3587 break; 3588 } 3589 case AMDGPU::G_ATOMIC_CMPXCHG: { 3590 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3591 OpdsMapping[1] = getValueMappingForPtr(MRI, MI.getOperand(1).getReg()); 3592 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3593 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3594 break; 3595 } 3596 case AMDGPU::G_BRCOND: { 3597 unsigned Bank = getRegBankID(MI.getOperand(0).getReg(), MRI, *TRI, 3598 AMDGPU::SGPRRegBankID); 3599 assert(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 1); 3600 if (Bank != AMDGPU::SGPRRegBankID) 3601 Bank = AMDGPU::VCCRegBankID; 3602 3603 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, 1); 3604 break; 3605 } 3606 } 3607 3608 return getInstructionMapping(/*ID*/1, /*Cost*/1, 3609 getOperandsMapping(OpdsMapping), 3610 MI.getNumOperands()); 3611 } 3612