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 "AMDGPU.h" 74 #include "AMDGPUGlobalISelUtils.h" 75 #include "AMDGPUInstrInfo.h" 76 #include "GCNSubtarget.h" 77 #include "SIMachineFunctionInfo.h" 78 #include "SIRegisterInfo.h" 79 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 80 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 81 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 82 #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 83 #include "llvm/IR/IntrinsicsAMDGPU.h" 84 85 #define GET_TARGET_REGBANK_IMPL 86 #include "AMDGPUGenRegisterBank.inc" 87 88 // This file will be TableGen'ed at some point. 89 #include "AMDGPUGenRegisterBankInfo.def" 90 91 using namespace llvm; 92 using namespace MIPatternMatch; 93 94 namespace { 95 96 // Observer to apply a register bank to new registers created by LegalizerHelper. 97 class ApplyRegBankMapping final : public GISelChangeObserver { 98 private: 99 const AMDGPURegisterBankInfo &RBI; 100 MachineRegisterInfo &MRI; 101 const RegisterBank *NewBank; 102 SmallVector<MachineInstr *, 4> NewInsts; 103 104 public: 105 ApplyRegBankMapping(const AMDGPURegisterBankInfo &RBI_, 106 MachineRegisterInfo &MRI_, const RegisterBank *RB) 107 : RBI(RBI_), MRI(MRI_), NewBank(RB) {} 108 109 ~ApplyRegBankMapping() { 110 for (MachineInstr *MI : NewInsts) 111 applyBank(*MI); 112 } 113 114 /// Set any registers that don't have a set register class or bank to SALU. 115 void applyBank(MachineInstr &MI) { 116 const unsigned Opc = MI.getOpcode(); 117 if (Opc == AMDGPU::G_ANYEXT || Opc == AMDGPU::G_ZEXT || 118 Opc == AMDGPU::G_SEXT) { 119 // LegalizerHelper wants to use the basic legalization artifacts when 120 // widening etc. We don't handle selection with vcc in artifact sources, 121 // so we need to use a sslect instead to handle these properly. 122 Register DstReg = MI.getOperand(0).getReg(); 123 Register SrcReg = MI.getOperand(1).getReg(); 124 const RegisterBank *SrcBank = RBI.getRegBank(SrcReg, MRI, *RBI.TRI); 125 if (SrcBank == &AMDGPU::VCCRegBank) { 126 const LLT S32 = LLT::scalar(32); 127 assert(MRI.getType(SrcReg) == LLT::scalar(1)); 128 assert(MRI.getType(DstReg) == S32); 129 assert(NewBank == &AMDGPU::VGPRRegBank); 130 131 // Replace the extension with a select, which really uses the boolean 132 // source. 133 MachineIRBuilder B(MI); 134 auto True = B.buildConstant(S32, Opc == AMDGPU::G_SEXT ? -1 : 1); 135 auto False = B.buildConstant(S32, 0); 136 B.buildSelect(DstReg, SrcReg, True, False); 137 MRI.setRegBank(True.getReg(0), *NewBank); 138 MRI.setRegBank(False.getReg(0), *NewBank); 139 MI.eraseFromParent(); 140 } 141 142 assert(!MRI.getRegClassOrRegBank(DstReg)); 143 MRI.setRegBank(DstReg, *NewBank); 144 return; 145 } 146 147 #ifndef NDEBUG 148 if (Opc == AMDGPU::G_TRUNC) { 149 Register DstReg = MI.getOperand(0).getReg(); 150 const RegisterBank *DstBank = RBI.getRegBank(DstReg, MRI, *RBI.TRI); 151 assert(DstBank != &AMDGPU::VCCRegBank); 152 } 153 #endif 154 155 for (MachineOperand &Op : MI.operands()) { 156 if (!Op.isReg()) 157 continue; 158 159 // We may see physical registers if building a real MI 160 Register Reg = Op.getReg(); 161 if (Reg.isPhysical() || MRI.getRegClassOrRegBank(Reg)) 162 continue; 163 164 const RegisterBank *RB = NewBank; 165 if (MRI.getType(Reg) == LLT::scalar(1)) { 166 assert(NewBank == &AMDGPU::VGPRRegBank && 167 "s1 operands should only be used for vector bools"); 168 assert((MI.getOpcode() != AMDGPU::G_TRUNC && 169 MI.getOpcode() != AMDGPU::G_ANYEXT) && 170 "not expecting legalization artifacts here"); 171 RB = &AMDGPU::VCCRegBank; 172 } 173 174 MRI.setRegBank(Reg, *RB); 175 } 176 } 177 178 void erasingInstr(MachineInstr &MI) override {} 179 180 void createdInstr(MachineInstr &MI) override { 181 // At this point, the instruction was just inserted and has no operands. 182 NewInsts.push_back(&MI); 183 } 184 185 void changingInstr(MachineInstr &MI) override {} 186 void changedInstr(MachineInstr &MI) override { 187 // FIXME: In principle we should probably add the instruction to NewInsts, 188 // but the way the LegalizerHelper uses the observer, we will always see the 189 // registers we need to set the regbank on also referenced in a new 190 // instruction. 191 } 192 }; 193 194 } 195 AMDGPURegisterBankInfo::AMDGPURegisterBankInfo(const GCNSubtarget &ST) 196 : AMDGPUGenRegisterBankInfo(), 197 Subtarget(ST), 198 TRI(Subtarget.getRegisterInfo()), 199 TII(Subtarget.getInstrInfo()) { 200 201 // HACK: Until this is fully tablegen'd. 202 static llvm::once_flag InitializeRegisterBankFlag; 203 204 static auto InitializeRegisterBankOnce = [this]() { 205 assert(&getRegBank(AMDGPU::SGPRRegBankID) == &AMDGPU::SGPRRegBank && 206 &getRegBank(AMDGPU::VGPRRegBankID) == &AMDGPU::VGPRRegBank && 207 &getRegBank(AMDGPU::AGPRRegBankID) == &AMDGPU::AGPRRegBank); 208 (void)this; 209 }; 210 211 llvm::call_once(InitializeRegisterBankFlag, InitializeRegisterBankOnce); 212 } 213 214 static bool isVectorRegisterBank(const RegisterBank &Bank) { 215 unsigned BankID = Bank.getID(); 216 return BankID == AMDGPU::VGPRRegBankID || BankID == AMDGPU::AGPRRegBankID; 217 } 218 219 unsigned AMDGPURegisterBankInfo::copyCost(const RegisterBank &Dst, 220 const RegisterBank &Src, 221 unsigned Size) const { 222 // TODO: Should there be a UniformVGPRRegBank which can use readfirstlane? 223 if (Dst.getID() == AMDGPU::SGPRRegBankID && 224 (isVectorRegisterBank(Src) || Src.getID() == AMDGPU::VCCRegBankID)) { 225 return std::numeric_limits<unsigned>::max(); 226 } 227 228 // Bool values are tricky, because the meaning is based on context. The SCC 229 // and VCC banks are for the natural scalar and vector conditions produced by 230 // a compare. 231 // 232 // Legalization doesn't know about the necessary context, so an s1 use may 233 // have been a truncate from an arbitrary value, in which case a copy (lowered 234 // as a compare with 0) needs to be inserted. 235 if (Size == 1 && 236 (Dst.getID() == AMDGPU::SGPRRegBankID) && 237 (isVectorRegisterBank(Src) || 238 Src.getID() == AMDGPU::SGPRRegBankID || 239 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->getAlign() >= Align(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 546 if ((AS != AMDGPUAS::LOCAL_ADDRESS && AS != AMDGPUAS::REGION_ADDRESS && 547 AS != AMDGPUAS::PRIVATE_ADDRESS) && 548 isScalarLoadLegal(MI)) { 549 const InstructionMapping &SSMapping = getInstructionMapping( 550 1, 1, getOperandsMapping( 551 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 552 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize)}), 553 2); // Num Operands 554 AltMappings.push_back(&SSMapping); 555 } 556 557 const InstructionMapping &VVMapping = getInstructionMapping( 558 2, 1, 559 getOperandsMapping( 560 {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 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_SELECT: { 575 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 576 const InstructionMapping &SSMapping = getInstructionMapping(1, 1, 577 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 578 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1), 579 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 580 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}), 581 4); // Num Operands 582 AltMappings.push_back(&SSMapping); 583 584 const InstructionMapping &VVMapping = getInstructionMapping(2, 1, 585 getOperandsMapping({AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size), 586 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), 587 AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size), 588 AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size)}), 589 4); // Num Operands 590 AltMappings.push_back(&VVMapping); 591 592 return AltMappings; 593 } 594 case TargetOpcode::G_UADDE: 595 case TargetOpcode::G_USUBE: 596 case TargetOpcode::G_SADDE: 597 case TargetOpcode::G_SSUBE: { 598 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 599 const InstructionMapping &SSMapping = getInstructionMapping(1, 1, 600 getOperandsMapping( 601 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 602 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1), 603 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 604 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 605 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1)}), 606 5); // Num Operands 607 AltMappings.push_back(&SSMapping); 608 609 const InstructionMapping &VVMapping = getInstructionMapping(2, 1, 610 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 611 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), 612 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 613 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 614 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1)}), 615 5); // Num Operands 616 AltMappings.push_back(&VVMapping); 617 return AltMappings; 618 } 619 case AMDGPU::G_BRCOND: { 620 assert(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 1); 621 622 // TODO: Change type to 32 for scalar 623 const InstructionMapping &SMapping = getInstructionMapping( 624 1, 1, getOperandsMapping( 625 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1), nullptr}), 626 2); // Num Operands 627 AltMappings.push_back(&SMapping); 628 629 const InstructionMapping &VMapping = getInstructionMapping( 630 1, 1, getOperandsMapping( 631 {AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), nullptr }), 632 2); // Num Operands 633 AltMappings.push_back(&VMapping); 634 return AltMappings; 635 } 636 case AMDGPU::G_INTRINSIC: 637 return getInstrAlternativeMappingsIntrinsic(MI, MRI); 638 case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: 639 return getInstrAlternativeMappingsIntrinsicWSideEffects(MI, MRI); 640 default: 641 break; 642 } 643 return RegisterBankInfo::getInstrAlternativeMappings(MI); 644 } 645 646 void AMDGPURegisterBankInfo::split64BitValueForMapping( 647 MachineIRBuilder &B, 648 SmallVector<Register, 2> &Regs, 649 LLT HalfTy, 650 Register Reg) const { 651 assert(HalfTy.getSizeInBits() == 32); 652 MachineRegisterInfo *MRI = B.getMRI(); 653 Register LoLHS = MRI->createGenericVirtualRegister(HalfTy); 654 Register HiLHS = MRI->createGenericVirtualRegister(HalfTy); 655 const RegisterBank *Bank = getRegBank(Reg, *MRI, *TRI); 656 MRI->setRegBank(LoLHS, *Bank); 657 MRI->setRegBank(HiLHS, *Bank); 658 659 Regs.push_back(LoLHS); 660 Regs.push_back(HiLHS); 661 662 B.buildInstr(AMDGPU::G_UNMERGE_VALUES) 663 .addDef(LoLHS) 664 .addDef(HiLHS) 665 .addUse(Reg); 666 } 667 668 /// Replace the current type each register in \p Regs has with \p NewTy 669 static void setRegsToType(MachineRegisterInfo &MRI, ArrayRef<Register> Regs, 670 LLT NewTy) { 671 for (Register Reg : Regs) { 672 assert(MRI.getType(Reg).getSizeInBits() == NewTy.getSizeInBits()); 673 MRI.setType(Reg, NewTy); 674 } 675 } 676 677 static LLT getHalfSizedType(LLT Ty) { 678 if (Ty.isVector()) { 679 assert(Ty.getNumElements() % 2 == 0); 680 return LLT::scalarOrVector(Ty.getNumElements() / 2, Ty.getElementType()); 681 } 682 683 assert(Ty.getSizeInBits() % 2 == 0); 684 return LLT::scalar(Ty.getSizeInBits() / 2); 685 } 686 687 /// Legalize instruction \p MI where operands in \p OpIndices must be SGPRs. If 688 /// any of the required SGPR operands are VGPRs, perform a waterfall loop to 689 /// execute the instruction for each unique combination of values in all lanes 690 /// in the wave. The block will be split such that rest of the instructions are 691 /// moved to a new block. 692 /// 693 /// Essentially performs this loop: 694 // 695 /// Save Execution Mask 696 /// For (Lane : Wavefront) { 697 /// Enable Lane, Disable all other lanes 698 /// SGPR = read SGPR value for current lane from VGPR 699 /// VGPRResult[Lane] = use_op SGPR 700 /// } 701 /// Restore Execution Mask 702 /// 703 /// There is additional complexity to try for compare values to identify the 704 /// unique values used. 705 bool AMDGPURegisterBankInfo::executeInWaterfallLoop( 706 MachineIRBuilder &B, 707 iterator_range<MachineBasicBlock::iterator> Range, 708 SmallSet<Register, 4> &SGPROperandRegs, 709 MachineRegisterInfo &MRI) const { 710 SmallVector<Register, 4> ResultRegs; 711 SmallVector<Register, 4> InitResultRegs; 712 SmallVector<Register, 4> PhiRegs; 713 714 // Track use registers which have already been expanded with a readfirstlane 715 // sequence. This may have multiple uses if moving a sequence. 716 DenseMap<Register, Register> WaterfalledRegMap; 717 718 MachineBasicBlock &MBB = B.getMBB(); 719 MachineFunction *MF = &B.getMF(); 720 721 const TargetRegisterClass *WaveRC = TRI->getWaveMaskRegClass(); 722 const unsigned WaveAndOpc = Subtarget.isWave32() ? 723 AMDGPU::S_AND_B32 : AMDGPU::S_AND_B64; 724 const unsigned MovTermOpc = Subtarget.isWave32() ? 725 AMDGPU::S_MOV_B32_term : AMDGPU::S_MOV_B64_term; 726 const unsigned XorTermOpc = Subtarget.isWave32() ? 727 AMDGPU::S_XOR_B32_term : AMDGPU::S_XOR_B64_term; 728 const unsigned AndSaveExecOpc = Subtarget.isWave32() ? 729 AMDGPU::S_AND_SAVEEXEC_B32 : AMDGPU::S_AND_SAVEEXEC_B64; 730 const unsigned ExecReg = Subtarget.isWave32() ? 731 AMDGPU::EXEC_LO : AMDGPU::EXEC; 732 733 #ifndef NDEBUG 734 const int OrigRangeSize = std::distance(Range.begin(), Range.end()); 735 #endif 736 737 for (MachineInstr &MI : Range) { 738 for (MachineOperand &Def : MI.defs()) { 739 if (MRI.use_nodbg_empty(Def.getReg())) 740 continue; 741 742 LLT ResTy = MRI.getType(Def.getReg()); 743 const RegisterBank *DefBank = getRegBank(Def.getReg(), MRI, *TRI); 744 ResultRegs.push_back(Def.getReg()); 745 Register InitReg = B.buildUndef(ResTy).getReg(0); 746 Register PhiReg = MRI.createGenericVirtualRegister(ResTy); 747 InitResultRegs.push_back(InitReg); 748 PhiRegs.push_back(PhiReg); 749 MRI.setRegBank(PhiReg, *DefBank); 750 MRI.setRegBank(InitReg, *DefBank); 751 } 752 } 753 754 Register SaveExecReg = MRI.createVirtualRegister(WaveRC); 755 Register InitSaveExecReg = MRI.createVirtualRegister(WaveRC); 756 757 // Don't bother using generic instructions/registers for the exec mask. 758 B.buildInstr(TargetOpcode::IMPLICIT_DEF) 759 .addDef(InitSaveExecReg); 760 761 Register PhiExec = MRI.createVirtualRegister(WaveRC); 762 Register NewExec = MRI.createVirtualRegister(WaveRC); 763 764 // To insert the loop we need to split the block. Move everything before this 765 // point to a new block, and insert a new empty block before this instruction. 766 MachineBasicBlock *LoopBB = MF->CreateMachineBasicBlock(); 767 MachineBasicBlock *RemainderBB = MF->CreateMachineBasicBlock(); 768 MachineBasicBlock *RestoreExecBB = MF->CreateMachineBasicBlock(); 769 MachineFunction::iterator MBBI(MBB); 770 ++MBBI; 771 MF->insert(MBBI, LoopBB); 772 MF->insert(MBBI, RestoreExecBB); 773 MF->insert(MBBI, RemainderBB); 774 775 LoopBB->addSuccessor(RestoreExecBB); 776 LoopBB->addSuccessor(LoopBB); 777 778 // Move the rest of the block into a new block. 779 RemainderBB->transferSuccessorsAndUpdatePHIs(&MBB); 780 RemainderBB->splice(RemainderBB->begin(), &MBB, Range.end(), MBB.end()); 781 782 MBB.addSuccessor(LoopBB); 783 RestoreExecBB->addSuccessor(RemainderBB); 784 785 B.setInsertPt(*LoopBB, LoopBB->end()); 786 787 B.buildInstr(TargetOpcode::PHI) 788 .addDef(PhiExec) 789 .addReg(InitSaveExecReg) 790 .addMBB(&MBB) 791 .addReg(NewExec) 792 .addMBB(LoopBB); 793 794 for (auto Result : zip(InitResultRegs, ResultRegs, PhiRegs)) { 795 B.buildInstr(TargetOpcode::G_PHI) 796 .addDef(std::get<2>(Result)) 797 .addReg(std::get<0>(Result)) // Initial value / implicit_def 798 .addMBB(&MBB) 799 .addReg(std::get<1>(Result)) // Mid-loop value. 800 .addMBB(LoopBB); 801 } 802 803 const DebugLoc &DL = B.getDL(); 804 805 MachineInstr &FirstInst = *Range.begin(); 806 807 // Move the instruction into the loop. Note we moved everything after 808 // Range.end() already into a new block, so Range.end() is no longer valid. 809 LoopBB->splice(LoopBB->end(), &MBB, Range.begin(), MBB.end()); 810 811 // Figure out the iterator range after splicing the instructions. 812 MachineBasicBlock::iterator NewBegin = FirstInst.getIterator(); 813 auto NewEnd = LoopBB->end(); 814 815 MachineBasicBlock::iterator I = Range.begin(); 816 B.setInsertPt(*LoopBB, I); 817 818 Register CondReg; 819 820 assert(std::distance(NewBegin, NewEnd) == OrigRangeSize); 821 822 for (MachineInstr &MI : make_range(NewBegin, NewEnd)) { 823 for (MachineOperand &Op : MI.uses()) { 824 if (!Op.isReg() || Op.isDef()) 825 continue; 826 827 Register OldReg = Op.getReg(); 828 if (!SGPROperandRegs.count(OldReg)) 829 continue; 830 831 // See if we already processed this register in another instruction in the 832 // sequence. 833 auto OldVal = WaterfalledRegMap.find(OldReg); 834 if (OldVal != WaterfalledRegMap.end()) { 835 Op.setReg(OldVal->second); 836 continue; 837 } 838 839 Register OpReg = Op.getReg(); 840 LLT OpTy = MRI.getType(OpReg); 841 842 const RegisterBank *OpBank = getRegBank(OpReg, MRI, *TRI); 843 if (OpBank != &AMDGPU::VGPRRegBank) { 844 // Insert copy from AGPR to VGPR before the loop. 845 B.setMBB(MBB); 846 OpReg = B.buildCopy(OpTy, OpReg).getReg(0); 847 MRI.setRegBank(OpReg, AMDGPU::VGPRRegBank); 848 B.setInstr(*I); 849 } 850 851 unsigned OpSize = OpTy.getSizeInBits(); 852 853 // Can only do a readlane of 32-bit pieces. 854 if (OpSize == 32) { 855 // Avoid extra copies in the simple case of one 32-bit register. 856 Register CurrentLaneOpReg 857 = MRI.createVirtualRegister(&AMDGPU::SReg_32_XM0RegClass); 858 MRI.setType(CurrentLaneOpReg, OpTy); 859 860 constrainGenericRegister(OpReg, AMDGPU::VGPR_32RegClass, MRI); 861 // Read the next variant <- also loop target. 862 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), 863 CurrentLaneOpReg) 864 .addReg(OpReg); 865 866 Register NewCondReg = MRI.createVirtualRegister(WaveRC); 867 bool First = CondReg == AMDGPU::NoRegister; 868 if (First) 869 CondReg = NewCondReg; 870 871 // Compare the just read M0 value to all possible Idx values. 872 B.buildInstr(AMDGPU::V_CMP_EQ_U32_e64) 873 .addDef(NewCondReg) 874 .addReg(CurrentLaneOpReg) 875 .addReg(OpReg); 876 Op.setReg(CurrentLaneOpReg); 877 878 if (!First) { 879 Register AndReg = MRI.createVirtualRegister(WaveRC); 880 881 // If there are multiple operands to consider, and the conditions. 882 B.buildInstr(WaveAndOpc) 883 .addDef(AndReg) 884 .addReg(NewCondReg) 885 .addReg(CondReg); 886 CondReg = AndReg; 887 } 888 } else { 889 LLT S32 = LLT::scalar(32); 890 SmallVector<Register, 8> ReadlanePieces; 891 892 // The compares can be done as 64-bit, but the extract needs to be done 893 // in 32-bit pieces. 894 895 bool Is64 = OpSize % 64 == 0; 896 897 LLT UnmergeTy = OpSize % 64 == 0 ? LLT::scalar(64) : LLT::scalar(32); 898 unsigned CmpOp = OpSize % 64 == 0 ? AMDGPU::V_CMP_EQ_U64_e64 899 : AMDGPU::V_CMP_EQ_U32_e64; 900 901 // The compares can be done as 64-bit, but the extract needs to be done 902 // in 32-bit pieces. 903 904 // Insert the unmerge before the loop. 905 906 B.setMBB(MBB); 907 auto Unmerge = B.buildUnmerge(UnmergeTy, OpReg); 908 B.setInstr(*I); 909 910 unsigned NumPieces = Unmerge->getNumOperands() - 1; 911 for (unsigned PieceIdx = 0; PieceIdx != NumPieces; ++PieceIdx) { 912 Register UnmergePiece = Unmerge.getReg(PieceIdx); 913 914 Register CurrentLaneOpReg; 915 if (Is64) { 916 Register CurrentLaneOpRegLo = MRI.createGenericVirtualRegister(S32); 917 Register CurrentLaneOpRegHi = MRI.createGenericVirtualRegister(S32); 918 919 MRI.setRegClass(UnmergePiece, &AMDGPU::VReg_64RegClass); 920 MRI.setRegClass(CurrentLaneOpRegLo, &AMDGPU::SReg_32_XM0RegClass); 921 MRI.setRegClass(CurrentLaneOpRegHi, &AMDGPU::SReg_32_XM0RegClass); 922 923 // Read the next variant <- also loop target. 924 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), 925 CurrentLaneOpRegLo) 926 .addReg(UnmergePiece, 0, AMDGPU::sub0); 927 928 // Read the next variant <- also loop target. 929 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), 930 CurrentLaneOpRegHi) 931 .addReg(UnmergePiece, 0, AMDGPU::sub1); 932 933 CurrentLaneOpReg = 934 B.buildMerge(LLT::scalar(64), 935 {CurrentLaneOpRegLo, CurrentLaneOpRegHi}) 936 .getReg(0); 937 938 MRI.setRegClass(CurrentLaneOpReg, &AMDGPU::SReg_64_XEXECRegClass); 939 940 if (OpTy.getScalarSizeInBits() == 64) { 941 // If we need to produce a 64-bit element vector, so use the 942 // merged pieces 943 ReadlanePieces.push_back(CurrentLaneOpReg); 944 } else { 945 // 32-bit element type. 946 ReadlanePieces.push_back(CurrentLaneOpRegLo); 947 ReadlanePieces.push_back(CurrentLaneOpRegHi); 948 } 949 } else { 950 CurrentLaneOpReg = MRI.createGenericVirtualRegister(S32); 951 MRI.setRegClass(UnmergePiece, &AMDGPU::VGPR_32RegClass); 952 MRI.setRegClass(CurrentLaneOpReg, &AMDGPU::SReg_32_XM0RegClass); 953 954 // Read the next variant <- also loop target. 955 BuildMI(*LoopBB, I, DL, TII->get(AMDGPU::V_READFIRSTLANE_B32), 956 CurrentLaneOpReg) 957 .addReg(UnmergePiece); 958 ReadlanePieces.push_back(CurrentLaneOpReg); 959 } 960 961 Register NewCondReg = MRI.createVirtualRegister(WaveRC); 962 bool First = CondReg == AMDGPU::NoRegister; 963 if (First) 964 CondReg = NewCondReg; 965 966 B.buildInstr(CmpOp) 967 .addDef(NewCondReg) 968 .addReg(CurrentLaneOpReg) 969 .addReg(UnmergePiece); 970 971 if (!First) { 972 Register AndReg = MRI.createVirtualRegister(WaveRC); 973 974 // If there are multiple operands to consider, and the conditions. 975 B.buildInstr(WaveAndOpc) 976 .addDef(AndReg) 977 .addReg(NewCondReg) 978 .addReg(CondReg); 979 CondReg = AndReg; 980 } 981 } 982 983 // FIXME: Build merge seems to switch to CONCAT_VECTORS but not 984 // BUILD_VECTOR 985 if (OpTy.isVector()) { 986 auto Merge = B.buildBuildVector(OpTy, ReadlanePieces); 987 Op.setReg(Merge.getReg(0)); 988 } else { 989 auto Merge = B.buildMerge(OpTy, ReadlanePieces); 990 Op.setReg(Merge.getReg(0)); 991 } 992 993 MRI.setRegBank(Op.getReg(), AMDGPU::SGPRRegBank); 994 } 995 996 // Make sure we don't re-process this register again. 997 WaterfalledRegMap.insert(std::make_pair(OldReg, Op.getReg())); 998 } 999 } 1000 1001 B.setInsertPt(*LoopBB, LoopBB->end()); 1002 1003 // Update EXEC, save the original EXEC value to VCC. 1004 B.buildInstr(AndSaveExecOpc) 1005 .addDef(NewExec) 1006 .addReg(CondReg, RegState::Kill); 1007 1008 MRI.setSimpleHint(NewExec, CondReg); 1009 1010 // Update EXEC, switch all done bits to 0 and all todo bits to 1. 1011 B.buildInstr(XorTermOpc) 1012 .addDef(ExecReg) 1013 .addReg(ExecReg) 1014 .addReg(NewExec); 1015 1016 // XXX - s_xor_b64 sets scc to 1 if the result is nonzero, so can we use 1017 // s_cbranch_scc0? 1018 1019 // Loop back to V_READFIRSTLANE_B32 if there are still variants to cover. 1020 B.buildInstr(AMDGPU::S_CBRANCH_EXECNZ) 1021 .addMBB(LoopBB); 1022 1023 // Save the EXEC mask before the loop. 1024 BuildMI(MBB, MBB.end(), DL, TII->get(MovTermOpc), SaveExecReg) 1025 .addReg(ExecReg); 1026 1027 // Restore the EXEC mask after the loop. 1028 B.setMBB(*RestoreExecBB); 1029 B.buildInstr(MovTermOpc) 1030 .addDef(ExecReg) 1031 .addReg(SaveExecReg); 1032 1033 // Set the insert point after the original instruction, so any new 1034 // instructions will be in the remainder. 1035 B.setInsertPt(*RemainderBB, RemainderBB->begin()); 1036 1037 return true; 1038 } 1039 1040 // Return any unique registers used by \p MI at \p OpIndices that need to be 1041 // handled in a waterfall loop. Returns these registers in \p 1042 // SGPROperandRegs. Returns true if there are any operands to handle and a 1043 // waterfall loop is necessary. 1044 bool AMDGPURegisterBankInfo::collectWaterfallOperands( 1045 SmallSet<Register, 4> &SGPROperandRegs, MachineInstr &MI, 1046 MachineRegisterInfo &MRI, ArrayRef<unsigned> OpIndices) const { 1047 for (unsigned Op : OpIndices) { 1048 assert(MI.getOperand(Op).isUse()); 1049 Register Reg = MI.getOperand(Op).getReg(); 1050 const RegisterBank *OpBank = getRegBank(Reg, MRI, *TRI); 1051 if (OpBank->getID() != AMDGPU::SGPRRegBankID) 1052 SGPROperandRegs.insert(Reg); 1053 } 1054 1055 // No operands need to be replaced, so no need to loop. 1056 return !SGPROperandRegs.empty(); 1057 } 1058 1059 bool AMDGPURegisterBankInfo::executeInWaterfallLoop( 1060 MachineIRBuilder &B, MachineInstr &MI, MachineRegisterInfo &MRI, 1061 ArrayRef<unsigned> OpIndices) const { 1062 // Use a set to avoid extra readfirstlanes in the case where multiple operands 1063 // are the same register. 1064 SmallSet<Register, 4> SGPROperandRegs; 1065 1066 if (!collectWaterfallOperands(SGPROperandRegs, MI, MRI, OpIndices)) 1067 return false; 1068 1069 MachineBasicBlock::iterator I = MI.getIterator(); 1070 return executeInWaterfallLoop(B, make_range(I, std::next(I)), 1071 SGPROperandRegs, MRI); 1072 } 1073 1074 bool AMDGPURegisterBankInfo::executeInWaterfallLoop( 1075 MachineInstr &MI, MachineRegisterInfo &MRI, 1076 ArrayRef<unsigned> OpIndices) const { 1077 MachineIRBuilder B(MI); 1078 return executeInWaterfallLoop(B, MI, MRI, OpIndices); 1079 } 1080 1081 // Legalize an operand that must be an SGPR by inserting a readfirstlane. 1082 void AMDGPURegisterBankInfo::constrainOpWithReadfirstlane( 1083 MachineInstr &MI, MachineRegisterInfo &MRI, unsigned OpIdx) const { 1084 Register Reg = MI.getOperand(OpIdx).getReg(); 1085 const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI); 1086 if (Bank == &AMDGPU::SGPRRegBank) 1087 return; 1088 1089 LLT Ty = MRI.getType(Reg); 1090 MachineIRBuilder B(MI); 1091 1092 if (Bank != &AMDGPU::VGPRRegBank) { 1093 // We need to copy from AGPR to VGPR 1094 Reg = B.buildCopy(Ty, Reg).getReg(0); 1095 MRI.setRegBank(Reg, AMDGPU::VGPRRegBank); 1096 } 1097 1098 Register SGPR = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); 1099 B.buildInstr(AMDGPU::V_READFIRSTLANE_B32) 1100 .addDef(SGPR) 1101 .addReg(Reg); 1102 1103 MRI.setType(SGPR, Ty); 1104 1105 const TargetRegisterClass *Constrained = 1106 constrainGenericRegister(Reg, AMDGPU::VGPR_32RegClass, MRI); 1107 (void)Constrained; 1108 assert(Constrained && "Failed to constrain readfirstlane src reg"); 1109 1110 MI.getOperand(OpIdx).setReg(SGPR); 1111 } 1112 1113 /// Split \p Ty into 2 pieces. The first will have \p FirstSize bits, and the 1114 /// rest will be in the remainder. 1115 static std::pair<LLT, LLT> splitUnequalType(LLT Ty, unsigned FirstSize) { 1116 unsigned TotalSize = Ty.getSizeInBits(); 1117 if (!Ty.isVector()) 1118 return {LLT::scalar(FirstSize), LLT::scalar(TotalSize - FirstSize)}; 1119 1120 LLT EltTy = Ty.getElementType(); 1121 unsigned EltSize = EltTy.getSizeInBits(); 1122 assert(FirstSize % EltSize == 0); 1123 1124 unsigned FirstPartNumElts = FirstSize / EltSize; 1125 unsigned RemainderElts = (TotalSize - FirstSize) / EltSize; 1126 1127 return {LLT::scalarOrVector(FirstPartNumElts, EltTy), 1128 LLT::scalarOrVector(RemainderElts, EltTy)}; 1129 } 1130 1131 static LLT widen96To128(LLT Ty) { 1132 if (!Ty.isVector()) 1133 return LLT::scalar(128); 1134 1135 LLT EltTy = Ty.getElementType(); 1136 assert(128 % EltTy.getSizeInBits() == 0); 1137 return LLT::vector(128 / EltTy.getSizeInBits(), EltTy); 1138 } 1139 1140 bool AMDGPURegisterBankInfo::applyMappingLoad(MachineInstr &MI, 1141 const AMDGPURegisterBankInfo::OperandsMapper &OpdMapper, 1142 MachineRegisterInfo &MRI) const { 1143 Register DstReg = MI.getOperand(0).getReg(); 1144 const LLT LoadTy = MRI.getType(DstReg); 1145 unsigned LoadSize = LoadTy.getSizeInBits(); 1146 const unsigned MaxNonSmrdLoadSize = 128; 1147 1148 const RegisterBank *PtrBank = 1149 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 1150 if (PtrBank == &AMDGPU::SGPRRegBank) { 1151 // If the pointer is an SGPR, we ordinarily have nothing to do. 1152 if (LoadSize != 96) 1153 return false; 1154 1155 MachineMemOperand *MMO = *MI.memoperands_begin(); 1156 Register PtrReg = MI.getOperand(1).getReg(); 1157 // 96-bit loads are only available for vector loads. We need to split this 1158 // into a 64-bit part, and 32 (unless we can widen to a 128-bit load). 1159 1160 ApplyRegBankMapping O(*this, MRI, &AMDGPU::SGPRRegBank); 1161 MachineIRBuilder B(MI, O); 1162 1163 if (MMO->getAlign() < Align(16)) { 1164 LLT Part64, Part32; 1165 std::tie(Part64, Part32) = splitUnequalType(LoadTy, 64); 1166 auto Load0 = B.buildLoadFromOffset(Part64, PtrReg, *MMO, 0); 1167 auto Load1 = B.buildLoadFromOffset(Part32, PtrReg, *MMO, 8); 1168 1169 auto Undef = B.buildUndef(LoadTy); 1170 auto Ins0 = B.buildInsert(LoadTy, Undef, Load0, 0); 1171 B.buildInsert(MI.getOperand(0), Ins0, Load1, 64); 1172 } else { 1173 LLT WiderTy = widen96To128(LoadTy); 1174 auto WideLoad = B.buildLoadFromOffset(WiderTy, PtrReg, *MMO, 0); 1175 B.buildExtract(MI.getOperand(0), WideLoad, 0); 1176 } 1177 1178 MI.eraseFromParent(); 1179 return true; 1180 } 1181 1182 // 128-bit loads are supported for all instruction types. 1183 if (LoadSize <= MaxNonSmrdLoadSize) 1184 return false; 1185 1186 SmallVector<Register, 16> DefRegs(OpdMapper.getVRegs(0)); 1187 SmallVector<Register, 1> SrcRegs(OpdMapper.getVRegs(1)); 1188 1189 if (SrcRegs.empty()) 1190 SrcRegs.push_back(MI.getOperand(1).getReg()); 1191 1192 assert(LoadSize % MaxNonSmrdLoadSize == 0); 1193 1194 // RegBankSelect only emits scalar types, so we need to reset the pointer 1195 // operand to a pointer type. 1196 Register BasePtrReg = SrcRegs[0]; 1197 LLT PtrTy = MRI.getType(MI.getOperand(1).getReg()); 1198 MRI.setType(BasePtrReg, PtrTy); 1199 1200 unsigned NumSplitParts = LoadTy.getSizeInBits() / MaxNonSmrdLoadSize; 1201 const LLT LoadSplitTy = LoadTy.divide(NumSplitParts); 1202 ApplyRegBankMapping Observer(*this, MRI, &AMDGPU::VGPRRegBank); 1203 MachineIRBuilder B(MI, Observer); 1204 LegalizerHelper Helper(B.getMF(), Observer, B); 1205 1206 if (LoadTy.isVector()) { 1207 if (Helper.fewerElementsVector(MI, 0, LoadSplitTy) != LegalizerHelper::Legalized) 1208 return false; 1209 } else { 1210 if (Helper.narrowScalar(MI, 0, LoadSplitTy) != LegalizerHelper::Legalized) 1211 return false; 1212 } 1213 1214 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 1215 return true; 1216 } 1217 1218 bool AMDGPURegisterBankInfo::applyMappingDynStackAlloc( 1219 MachineInstr &MI, 1220 const AMDGPURegisterBankInfo::OperandsMapper &OpdMapper, 1221 MachineRegisterInfo &MRI) const { 1222 const MachineFunction &MF = *MI.getMF(); 1223 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); 1224 const auto &TFI = *ST.getFrameLowering(); 1225 1226 // Guard in case the stack growth direction ever changes with scratch 1227 // instructions. 1228 if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown) 1229 return false; 1230 1231 Register Dst = MI.getOperand(0).getReg(); 1232 Register AllocSize = MI.getOperand(1).getReg(); 1233 Align Alignment = assumeAligned(MI.getOperand(2).getImm()); 1234 1235 const RegisterBank *SizeBank = getRegBank(AllocSize, MRI, *TRI); 1236 1237 // TODO: Need to emit a wave reduction to get the maximum size. 1238 if (SizeBank != &AMDGPU::SGPRRegBank) 1239 return false; 1240 1241 LLT PtrTy = MRI.getType(Dst); 1242 LLT IntPtrTy = LLT::scalar(PtrTy.getSizeInBits()); 1243 1244 const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>(); 1245 Register SPReg = Info->getStackPtrOffsetReg(); 1246 ApplyRegBankMapping ApplyBank(*this, MRI, &AMDGPU::SGPRRegBank); 1247 MachineIRBuilder B(MI, ApplyBank); 1248 1249 auto WaveSize = B.buildConstant(LLT::scalar(32), ST.getWavefrontSizeLog2()); 1250 auto ScaledSize = B.buildShl(IntPtrTy, AllocSize, WaveSize); 1251 1252 auto SPCopy = B.buildCopy(PtrTy, SPReg); 1253 if (Alignment > TFI.getStackAlign()) { 1254 auto PtrAdd = B.buildPtrAdd(PtrTy, SPCopy, ScaledSize); 1255 B.buildMaskLowPtrBits(Dst, PtrAdd, 1256 Log2(Alignment) + ST.getWavefrontSizeLog2()); 1257 } else { 1258 B.buildPtrAdd(Dst, SPCopy, ScaledSize); 1259 } 1260 1261 MI.eraseFromParent(); 1262 return true; 1263 } 1264 1265 bool AMDGPURegisterBankInfo::applyMappingImage( 1266 MachineInstr &MI, const AMDGPURegisterBankInfo::OperandsMapper &OpdMapper, 1267 MachineRegisterInfo &MRI, int RsrcIdx) const { 1268 const int NumDefs = MI.getNumExplicitDefs(); 1269 1270 // The reported argument index is relative to the IR intrinsic call arguments, 1271 // so we need to shift by the number of defs and the intrinsic ID. 1272 RsrcIdx += NumDefs + 1; 1273 1274 // Insert copies to VGPR arguments. 1275 applyDefaultMapping(OpdMapper); 1276 1277 // Fixup any SGPR arguments. 1278 SmallVector<unsigned, 4> SGPRIndexes; 1279 for (int I = NumDefs, NumOps = MI.getNumOperands(); I != NumOps; ++I) { 1280 if (!MI.getOperand(I).isReg()) 1281 continue; 1282 1283 // If this intrinsic has a sampler, it immediately follows rsrc. 1284 if (I == RsrcIdx || I == RsrcIdx + 1) 1285 SGPRIndexes.push_back(I); 1286 } 1287 1288 executeInWaterfallLoop(MI, MRI, SGPRIndexes); 1289 return true; 1290 } 1291 1292 static Register getSrcRegIgnoringCopies(const MachineRegisterInfo &MRI, 1293 Register Reg) { 1294 MachineInstr *Def = getDefIgnoringCopies(Reg, MRI); 1295 if (!Def) 1296 return Reg; 1297 1298 // TODO: Guard against this being an implicit def 1299 return Def->getOperand(0).getReg(); 1300 } 1301 1302 // Analyze a combined offset from an llvm.amdgcn.s.buffer intrinsic and store 1303 // the three offsets (voffset, soffset and instoffset) 1304 static unsigned setBufferOffsets(MachineIRBuilder &B, 1305 const AMDGPURegisterBankInfo &RBI, 1306 Register CombinedOffset, Register &VOffsetReg, 1307 Register &SOffsetReg, int64_t &InstOffsetVal, 1308 Align Alignment) { 1309 const LLT S32 = LLT::scalar(32); 1310 MachineRegisterInfo *MRI = B.getMRI(); 1311 1312 if (Optional<int64_t> Imm = getConstantVRegSExtVal(CombinedOffset, *MRI)) { 1313 uint32_t SOffset, ImmOffset; 1314 if (AMDGPU::splitMUBUFOffset(*Imm, SOffset, ImmOffset, &RBI.Subtarget, 1315 Alignment)) { 1316 VOffsetReg = B.buildConstant(S32, 0).getReg(0); 1317 SOffsetReg = B.buildConstant(S32, SOffset).getReg(0); 1318 InstOffsetVal = ImmOffset; 1319 1320 B.getMRI()->setRegBank(VOffsetReg, AMDGPU::VGPRRegBank); 1321 B.getMRI()->setRegBank(SOffsetReg, AMDGPU::SGPRRegBank); 1322 return SOffset + ImmOffset; 1323 } 1324 } 1325 1326 Register Base; 1327 unsigned Offset; 1328 1329 std::tie(Base, Offset) = 1330 AMDGPU::getBaseWithConstantOffset(*MRI, CombinedOffset); 1331 1332 uint32_t SOffset, ImmOffset; 1333 if ((int)Offset > 0 && AMDGPU::splitMUBUFOffset(Offset, SOffset, ImmOffset, 1334 &RBI.Subtarget, Alignment)) { 1335 if (RBI.getRegBank(Base, *MRI, *RBI.TRI) == &AMDGPU::VGPRRegBank) { 1336 VOffsetReg = Base; 1337 SOffsetReg = B.buildConstant(S32, SOffset).getReg(0); 1338 B.getMRI()->setRegBank(SOffsetReg, AMDGPU::SGPRRegBank); 1339 InstOffsetVal = ImmOffset; 1340 return 0; // XXX - Why is this 0? 1341 } 1342 1343 // If we have SGPR base, we can use it for soffset. 1344 if (SOffset == 0) { 1345 VOffsetReg = B.buildConstant(S32, 0).getReg(0); 1346 B.getMRI()->setRegBank(VOffsetReg, AMDGPU::VGPRRegBank); 1347 SOffsetReg = Base; 1348 InstOffsetVal = ImmOffset; 1349 return 0; // XXX - Why is this 0? 1350 } 1351 } 1352 1353 // Handle the variable sgpr + vgpr case. 1354 MachineInstr *Add = getOpcodeDef(AMDGPU::G_ADD, CombinedOffset, *MRI); 1355 if (Add && (int)Offset >= 0) { 1356 Register Src0 = getSrcRegIgnoringCopies(*MRI, Add->getOperand(1).getReg()); 1357 Register Src1 = getSrcRegIgnoringCopies(*MRI, Add->getOperand(2).getReg()); 1358 1359 const RegisterBank *Src0Bank = RBI.getRegBank(Src0, *MRI, *RBI.TRI); 1360 const RegisterBank *Src1Bank = RBI.getRegBank(Src1, *MRI, *RBI.TRI); 1361 1362 if (Src0Bank == &AMDGPU::VGPRRegBank && Src1Bank == &AMDGPU::SGPRRegBank) { 1363 VOffsetReg = Src0; 1364 SOffsetReg = Src1; 1365 return 0; 1366 } 1367 1368 if (Src0Bank == &AMDGPU::SGPRRegBank && Src1Bank == &AMDGPU::VGPRRegBank) { 1369 VOffsetReg = Src1; 1370 SOffsetReg = Src0; 1371 return 0; 1372 } 1373 } 1374 1375 // Ensure we have a VGPR for the combined offset. This could be an issue if we 1376 // have an SGPR offset and a VGPR resource. 1377 if (RBI.getRegBank(CombinedOffset, *MRI, *RBI.TRI) == &AMDGPU::VGPRRegBank) { 1378 VOffsetReg = CombinedOffset; 1379 } else { 1380 VOffsetReg = B.buildCopy(S32, CombinedOffset).getReg(0); 1381 B.getMRI()->setRegBank(VOffsetReg, AMDGPU::VGPRRegBank); 1382 } 1383 1384 SOffsetReg = B.buildConstant(S32, 0).getReg(0); 1385 B.getMRI()->setRegBank(SOffsetReg, AMDGPU::SGPRRegBank); 1386 return 0; 1387 } 1388 1389 bool AMDGPURegisterBankInfo::applyMappingSBufferLoad( 1390 const OperandsMapper &OpdMapper) const { 1391 MachineInstr &MI = OpdMapper.getMI(); 1392 MachineRegisterInfo &MRI = OpdMapper.getMRI(); 1393 1394 const LLT S32 = LLT::scalar(32); 1395 Register Dst = MI.getOperand(0).getReg(); 1396 LLT Ty = MRI.getType(Dst); 1397 1398 const RegisterBank *RSrcBank = 1399 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 1400 const RegisterBank *OffsetBank = 1401 OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 1402 if (RSrcBank == &AMDGPU::SGPRRegBank && 1403 OffsetBank == &AMDGPU::SGPRRegBank) 1404 return true; // Legal mapping 1405 1406 // FIXME: 96-bit case was widened during legalize. We neeed to narrow it back 1407 // here but don't have an MMO. 1408 1409 unsigned LoadSize = Ty.getSizeInBits(); 1410 int NumLoads = 1; 1411 if (LoadSize == 256 || LoadSize == 512) { 1412 NumLoads = LoadSize / 128; 1413 Ty = Ty.divide(NumLoads); 1414 } 1415 1416 // Use the alignment to ensure that the required offsets will fit into the 1417 // immediate offsets. 1418 const Align Alignment = NumLoads > 1 ? Align(16 * NumLoads) : Align(1); 1419 1420 MachineIRBuilder B(MI); 1421 MachineFunction &MF = B.getMF(); 1422 1423 Register SOffset; 1424 Register VOffset; 1425 int64_t ImmOffset = 0; 1426 1427 unsigned MMOOffset = setBufferOffsets(B, *this, MI.getOperand(2).getReg(), 1428 VOffset, SOffset, ImmOffset, Alignment); 1429 1430 // TODO: 96-bit loads were widened to 128-bit results. Shrink the result if we 1431 // can, but we neeed to track an MMO for that. 1432 const unsigned MemSize = (Ty.getSizeInBits() + 7) / 8; 1433 const Align MemAlign(4); // FIXME: ABI type alignment? 1434 MachineMemOperand *BaseMMO = MF.getMachineMemOperand( 1435 MachinePointerInfo(), 1436 MachineMemOperand::MOLoad | MachineMemOperand::MODereferenceable | 1437 MachineMemOperand::MOInvariant, 1438 MemSize, MemAlign); 1439 if (MMOOffset != 0) 1440 BaseMMO = MF.getMachineMemOperand(BaseMMO, MMOOffset, MemSize); 1441 1442 // If only the offset is divergent, emit a MUBUF buffer load instead. We can 1443 // assume that the buffer is unswizzled. 1444 1445 Register RSrc = MI.getOperand(1).getReg(); 1446 Register VIndex = B.buildConstant(S32, 0).getReg(0); 1447 B.getMRI()->setRegBank(VIndex, AMDGPU::VGPRRegBank); 1448 1449 SmallVector<Register, 4> LoadParts(NumLoads); 1450 1451 MachineBasicBlock::iterator MII = MI.getIterator(); 1452 MachineInstrSpan Span(MII, &B.getMBB()); 1453 1454 for (int i = 0; i < NumLoads; ++i) { 1455 if (NumLoads == 1) { 1456 LoadParts[i] = Dst; 1457 } else { 1458 LoadParts[i] = MRI.createGenericVirtualRegister(Ty); 1459 MRI.setRegBank(LoadParts[i], AMDGPU::VGPRRegBank); 1460 } 1461 1462 MachineMemOperand *MMO = BaseMMO; 1463 if (i != 0) 1464 BaseMMO = MF.getMachineMemOperand(BaseMMO, MMOOffset + 16 * i, MemSize); 1465 1466 B.buildInstr(AMDGPU::G_AMDGPU_BUFFER_LOAD) 1467 .addDef(LoadParts[i]) // vdata 1468 .addUse(RSrc) // rsrc 1469 .addUse(VIndex) // vindex 1470 .addUse(VOffset) // voffset 1471 .addUse(SOffset) // soffset 1472 .addImm(ImmOffset + 16 * i) // offset(imm) 1473 .addImm(0) // cachepolicy, swizzled buffer(imm) 1474 .addImm(0) // idxen(imm) 1475 .addMemOperand(MMO); 1476 } 1477 1478 // TODO: If only the resource is a VGPR, it may be better to execute the 1479 // scalar load in the waterfall loop if the resource is expected to frequently 1480 // be dynamically uniform. 1481 if (RSrcBank != &AMDGPU::SGPRRegBank) { 1482 // Remove the original instruction to avoid potentially confusing the 1483 // waterfall loop logic. 1484 B.setInstr(*Span.begin()); 1485 MI.eraseFromParent(); 1486 1487 SmallSet<Register, 4> OpsToWaterfall; 1488 1489 OpsToWaterfall.insert(RSrc); 1490 executeInWaterfallLoop(B, make_range(Span.begin(), Span.end()), 1491 OpsToWaterfall, MRI); 1492 } 1493 1494 if (NumLoads != 1) { 1495 if (Ty.isVector()) 1496 B.buildConcatVectors(Dst, LoadParts); 1497 else 1498 B.buildMerge(Dst, LoadParts); 1499 } 1500 1501 // We removed the instruction earlier with a waterfall loop. 1502 if (RSrcBank == &AMDGPU::SGPRRegBank) 1503 MI.eraseFromParent(); 1504 1505 return true; 1506 } 1507 1508 bool AMDGPURegisterBankInfo::applyMappingBFEIntrinsic( 1509 const OperandsMapper &OpdMapper, bool Signed) const { 1510 MachineInstr &MI = OpdMapper.getMI(); 1511 MachineRegisterInfo &MRI = OpdMapper.getMRI(); 1512 1513 // Insert basic copies 1514 applyDefaultMapping(OpdMapper); 1515 1516 Register DstReg = MI.getOperand(0).getReg(); 1517 LLT Ty = MRI.getType(DstReg); 1518 1519 const LLT S32 = LLT::scalar(32); 1520 1521 const RegisterBank *DstBank = 1522 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1523 if (DstBank == &AMDGPU::VGPRRegBank) { 1524 if (Ty == S32) 1525 return true; 1526 1527 // TODO: 64-bit version is scalar only, so we need to expand this. 1528 return false; 1529 } 1530 1531 Register SrcReg = MI.getOperand(2).getReg(); 1532 Register OffsetReg = MI.getOperand(3).getReg(); 1533 Register WidthReg = MI.getOperand(4).getReg(); 1534 1535 // The scalar form packs the offset and width in a single operand. 1536 1537 ApplyRegBankMapping ApplyBank(*this, MRI, &AMDGPU::SGPRRegBank); 1538 MachineIRBuilder B(MI, ApplyBank); 1539 1540 // Ensure the high bits are clear to insert the offset. 1541 auto OffsetMask = B.buildConstant(S32, maskTrailingOnes<unsigned>(6)); 1542 auto ClampOffset = B.buildAnd(S32, OffsetReg, OffsetMask); 1543 1544 // Zeros out the low bits, so don't bother clamping the input value. 1545 auto ShiftWidth = B.buildShl(S32, WidthReg, B.buildConstant(S32, 16)); 1546 1547 // Transformation function, pack the offset and width of a BFE into 1548 // the format expected by the S_BFE_I32 / S_BFE_U32. In the second 1549 // source, bits [5:0] contain the offset and bits [22:16] the width. 1550 auto MergedInputs = B.buildOr(S32, ClampOffset, ShiftWidth); 1551 1552 // TODO: It might be worth using a pseudo here to avoid scc clobber and 1553 // register class constraints. 1554 unsigned Opc = Ty == S32 ? (Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32) : 1555 (Signed ? AMDGPU::S_BFE_I64 : AMDGPU::S_BFE_U64); 1556 1557 auto MIB = B.buildInstr(Opc, {DstReg}, {SrcReg, MergedInputs}); 1558 if (!constrainSelectedInstRegOperands(*MIB, *TII, *TRI, *this)) 1559 llvm_unreachable("failed to constrain BFE"); 1560 1561 MI.eraseFromParent(); 1562 return true; 1563 } 1564 1565 // Return a suitable opcode for extending the operands of Opc when widening. 1566 static unsigned getExtendOp(unsigned Opc) { 1567 switch (Opc) { 1568 case TargetOpcode::G_ASHR: 1569 case TargetOpcode::G_SMIN: 1570 case TargetOpcode::G_SMAX: 1571 return TargetOpcode::G_SEXT; 1572 case TargetOpcode::G_LSHR: 1573 case TargetOpcode::G_UMIN: 1574 case TargetOpcode::G_UMAX: 1575 return TargetOpcode::G_ZEXT; 1576 default: 1577 return TargetOpcode::G_ANYEXT; 1578 } 1579 } 1580 1581 // Emit a legalized extension from <2 x s16> to 2 32-bit components, avoiding 1582 // any illegal vector extend or unmerge operations. 1583 static std::pair<Register, Register> 1584 unpackV2S16ToS32(MachineIRBuilder &B, Register Src, unsigned ExtOpcode) { 1585 const LLT S32 = LLT::scalar(32); 1586 auto Bitcast = B.buildBitcast(S32, Src); 1587 1588 if (ExtOpcode == TargetOpcode::G_SEXT) { 1589 auto ExtLo = B.buildSExtInReg(S32, Bitcast, 16); 1590 auto ShiftHi = B.buildAShr(S32, Bitcast, B.buildConstant(S32, 16)); 1591 return std::make_pair(ExtLo.getReg(0), ShiftHi.getReg(0)); 1592 } 1593 1594 auto ShiftHi = B.buildLShr(S32, Bitcast, B.buildConstant(S32, 16)); 1595 if (ExtOpcode == TargetOpcode::G_ZEXT) { 1596 auto ExtLo = B.buildAnd(S32, Bitcast, B.buildConstant(S32, 0xffff)); 1597 return std::make_pair(ExtLo.getReg(0), ShiftHi.getReg(0)); 1598 } 1599 1600 assert(ExtOpcode == TargetOpcode::G_ANYEXT); 1601 return std::make_pair(Bitcast.getReg(0), ShiftHi.getReg(0)); 1602 } 1603 1604 // For cases where only a single copy is inserted for matching register banks. 1605 // Replace the register in the instruction operand 1606 static bool substituteSimpleCopyRegs( 1607 const AMDGPURegisterBankInfo::OperandsMapper &OpdMapper, unsigned OpIdx) { 1608 SmallVector<unsigned, 1> SrcReg(OpdMapper.getVRegs(OpIdx)); 1609 if (!SrcReg.empty()) { 1610 assert(SrcReg.size() == 1); 1611 OpdMapper.getMI().getOperand(OpIdx).setReg(SrcReg[0]); 1612 return true; 1613 } 1614 1615 return false; 1616 } 1617 1618 /// Handle register layout difference for f16 images for some subtargets. 1619 Register AMDGPURegisterBankInfo::handleD16VData(MachineIRBuilder &B, 1620 MachineRegisterInfo &MRI, 1621 Register Reg) const { 1622 if (!Subtarget.hasUnpackedD16VMem()) 1623 return Reg; 1624 1625 const LLT S16 = LLT::scalar(16); 1626 LLT StoreVT = MRI.getType(Reg); 1627 if (!StoreVT.isVector() || StoreVT.getElementType() != S16) 1628 return Reg; 1629 1630 auto Unmerge = B.buildUnmerge(S16, Reg); 1631 1632 1633 SmallVector<Register, 4> WideRegs; 1634 for (int I = 0, E = Unmerge->getNumOperands() - 1; I != E; ++I) 1635 WideRegs.push_back(Unmerge.getReg(I)); 1636 1637 const LLT S32 = LLT::scalar(32); 1638 int NumElts = StoreVT.getNumElements(); 1639 1640 return B.buildMerge(LLT::vector(NumElts, S32), WideRegs).getReg(0); 1641 } 1642 1643 static std::pair<Register, unsigned> 1644 getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg) { 1645 int64_t Const; 1646 if (mi_match(Reg, MRI, m_ICst(Const))) 1647 return std::make_pair(Register(), Const); 1648 1649 Register Base; 1650 if (mi_match(Reg, MRI, m_GAdd(m_Reg(Base), m_ICst(Const)))) 1651 return std::make_pair(Base, Const); 1652 1653 // TODO: Handle G_OR used for add case 1654 return std::make_pair(Reg, 0); 1655 } 1656 1657 std::pair<Register, unsigned> 1658 AMDGPURegisterBankInfo::splitBufferOffsets(MachineIRBuilder &B, 1659 Register OrigOffset) const { 1660 const unsigned MaxImm = 4095; 1661 Register BaseReg; 1662 unsigned ImmOffset; 1663 const LLT S32 = LLT::scalar(32); 1664 1665 std::tie(BaseReg, ImmOffset) = getBaseWithConstantOffset(*B.getMRI(), 1666 OrigOffset); 1667 1668 unsigned C1 = 0; 1669 if (ImmOffset != 0) { 1670 // If the immediate value is too big for the immoffset field, put the value 1671 // and -4096 into the immoffset field so that the value that is copied/added 1672 // for the voffset field is a multiple of 4096, and it stands more chance 1673 // of being CSEd with the copy/add for another similar load/store. 1674 // However, do not do that rounding down to a multiple of 4096 if that is a 1675 // negative number, as it appears to be illegal to have a negative offset 1676 // in the vgpr, even if adding the immediate offset makes it positive. 1677 unsigned Overflow = ImmOffset & ~MaxImm; 1678 ImmOffset -= Overflow; 1679 if ((int32_t)Overflow < 0) { 1680 Overflow += ImmOffset; 1681 ImmOffset = 0; 1682 } 1683 1684 C1 = ImmOffset; 1685 if (Overflow != 0) { 1686 if (!BaseReg) 1687 BaseReg = B.buildConstant(S32, Overflow).getReg(0); 1688 else { 1689 auto OverflowVal = B.buildConstant(S32, Overflow); 1690 BaseReg = B.buildAdd(S32, BaseReg, OverflowVal).getReg(0); 1691 } 1692 } 1693 } 1694 1695 if (!BaseReg) 1696 BaseReg = B.buildConstant(S32, 0).getReg(0); 1697 1698 return {BaseReg, C1}; 1699 } 1700 1701 static bool isZero(Register Reg, MachineRegisterInfo &MRI) { 1702 int64_t C; 1703 return mi_match(Reg, MRI, m_ICst(C)) && C == 0; 1704 } 1705 1706 static unsigned extractCPol(unsigned CachePolicy) { 1707 return CachePolicy & AMDGPU::CPol::ALL; 1708 } 1709 1710 static unsigned extractSWZ(unsigned CachePolicy) { 1711 return (CachePolicy >> 3) & 1; 1712 } 1713 1714 1715 MachineInstr * 1716 AMDGPURegisterBankInfo::selectStoreIntrinsic(MachineIRBuilder &B, 1717 MachineInstr &MI) const { 1718 MachineRegisterInfo &MRI = *B.getMRI(); 1719 executeInWaterfallLoop(B, MI, MRI, {2, 4}); 1720 1721 // FIXME: DAG lowering brokenly changes opcode based on FP vs. integer. 1722 1723 Register VData = MI.getOperand(1).getReg(); 1724 LLT Ty = MRI.getType(VData); 1725 1726 int EltSize = Ty.getScalarSizeInBits(); 1727 int Size = Ty.getSizeInBits(); 1728 1729 // FIXME: Broken integer truncstore. 1730 if (EltSize != 32) 1731 report_fatal_error("unhandled intrinsic store"); 1732 1733 // FIXME: Verifier should enforce 1 MMO for these intrinsics. 1734 const int MemSize = (*MI.memoperands_begin())->getSize(); 1735 1736 1737 Register RSrc = MI.getOperand(2).getReg(); 1738 Register VOffset = MI.getOperand(3).getReg(); 1739 Register SOffset = MI.getOperand(4).getReg(); 1740 unsigned CachePolicy = MI.getOperand(5).getImm(); 1741 1742 unsigned ImmOffset; 1743 std::tie(VOffset, ImmOffset) = splitBufferOffsets(B, VOffset); 1744 1745 const bool Offen = !isZero(VOffset, MRI); 1746 1747 unsigned Opc = AMDGPU::BUFFER_STORE_DWORD_OFFEN_exact; 1748 switch (8 * MemSize) { 1749 case 8: 1750 Opc = Offen ? AMDGPU::BUFFER_STORE_BYTE_OFFEN_exact : 1751 AMDGPU::BUFFER_STORE_BYTE_OFFSET_exact; 1752 break; 1753 case 16: 1754 Opc = Offen ? AMDGPU::BUFFER_STORE_SHORT_OFFEN_exact : 1755 AMDGPU::BUFFER_STORE_SHORT_OFFSET_exact; 1756 break; 1757 default: 1758 Opc = Offen ? AMDGPU::BUFFER_STORE_DWORD_OFFEN_exact : 1759 AMDGPU::BUFFER_STORE_DWORD_OFFSET_exact; 1760 if (Size > 32) 1761 Opc = AMDGPU::getMUBUFOpcode(Opc, Size / 32); 1762 break; 1763 } 1764 1765 1766 // Set the insertion point back to the instruction in case it was moved into a 1767 // loop. 1768 B.setInstr(MI); 1769 1770 MachineInstrBuilder MIB = B.buildInstr(Opc) 1771 .addUse(VData); 1772 1773 if (Offen) 1774 MIB.addUse(VOffset); 1775 1776 MIB.addUse(RSrc) 1777 .addUse(SOffset) 1778 .addImm(ImmOffset) 1779 .addImm(extractCPol(CachePolicy)) 1780 .addImm(0) // tfe: FIXME: Remove from inst 1781 .addImm(extractSWZ(CachePolicy)) 1782 .cloneMemRefs(MI); 1783 1784 // FIXME: We need a way to report failure from applyMappingImpl. 1785 // Insert constrain copies before inserting the loop. 1786 if (!constrainSelectedInstRegOperands(*MIB, *TII, *TRI, *this)) 1787 report_fatal_error("failed to constrain selected store intrinsic"); 1788 1789 return MIB; 1790 } 1791 1792 bool AMDGPURegisterBankInfo::buildVCopy(MachineIRBuilder &B, Register DstReg, 1793 Register SrcReg) const { 1794 MachineRegisterInfo &MRI = *B.getMRI(); 1795 LLT SrcTy = MRI.getType(SrcReg); 1796 if (SrcTy.getSizeInBits() == 32) { 1797 // Use a v_mov_b32 here to make the exec dependency explicit. 1798 B.buildInstr(AMDGPU::V_MOV_B32_e32) 1799 .addDef(DstReg) 1800 .addUse(SrcReg); 1801 return constrainGenericRegister(DstReg, AMDGPU::VGPR_32RegClass, MRI) && 1802 constrainGenericRegister(SrcReg, AMDGPU::SReg_32RegClass, MRI); 1803 } 1804 1805 Register TmpReg0 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); 1806 Register TmpReg1 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); 1807 1808 B.buildInstr(AMDGPU::V_MOV_B32_e32) 1809 .addDef(TmpReg0) 1810 .addUse(SrcReg, 0, AMDGPU::sub0); 1811 B.buildInstr(AMDGPU::V_MOV_B32_e32) 1812 .addDef(TmpReg1) 1813 .addUse(SrcReg, 0, AMDGPU::sub1); 1814 B.buildInstr(AMDGPU::REG_SEQUENCE) 1815 .addDef(DstReg) 1816 .addUse(TmpReg0) 1817 .addImm(AMDGPU::sub0) 1818 .addUse(TmpReg1) 1819 .addImm(AMDGPU::sub1); 1820 1821 return constrainGenericRegister(SrcReg, AMDGPU::SReg_64RegClass, MRI) && 1822 constrainGenericRegister(DstReg, AMDGPU::VReg_64RegClass, MRI); 1823 } 1824 1825 /// Utility function for pushing dynamic vector indexes with a constant offset 1826 /// into waterwall loops. 1827 static void reinsertVectorIndexAdd(MachineIRBuilder &B, 1828 MachineInstr &IdxUseInstr, 1829 unsigned OpIdx, 1830 unsigned ConstOffset) { 1831 MachineRegisterInfo &MRI = *B.getMRI(); 1832 const LLT S32 = LLT::scalar(32); 1833 Register WaterfallIdx = IdxUseInstr.getOperand(OpIdx).getReg(); 1834 B.setInsertPt(*IdxUseInstr.getParent(), IdxUseInstr.getIterator()); 1835 1836 auto MaterializedOffset = B.buildConstant(S32, ConstOffset); 1837 1838 auto Add = B.buildAdd(S32, WaterfallIdx, MaterializedOffset); 1839 MRI.setRegBank(MaterializedOffset.getReg(0), AMDGPU::SGPRRegBank); 1840 MRI.setRegBank(Add.getReg(0), AMDGPU::SGPRRegBank); 1841 IdxUseInstr.getOperand(OpIdx).setReg(Add.getReg(0)); 1842 } 1843 1844 /// Implement extending a 32-bit value to a 64-bit value. \p Lo32Reg is the 1845 /// original 32-bit source value (to be inserted in the low part of the combined 1846 /// 64-bit result), and \p Hi32Reg is the high half of the combined 64-bit 1847 /// value. 1848 static void extendLow32IntoHigh32(MachineIRBuilder &B, 1849 Register Hi32Reg, Register Lo32Reg, 1850 unsigned ExtOpc, 1851 const RegisterBank &RegBank, 1852 bool IsBooleanSrc = false) { 1853 if (ExtOpc == AMDGPU::G_ZEXT) { 1854 B.buildConstant(Hi32Reg, 0); 1855 } else if (ExtOpc == AMDGPU::G_SEXT) { 1856 if (IsBooleanSrc) { 1857 // If we know the original source was an s1, the high half is the same as 1858 // the low. 1859 B.buildCopy(Hi32Reg, Lo32Reg); 1860 } else { 1861 // Replicate sign bit from 32-bit extended part. 1862 auto ShiftAmt = B.buildConstant(LLT::scalar(32), 31); 1863 B.getMRI()->setRegBank(ShiftAmt.getReg(0), RegBank); 1864 B.buildAShr(Hi32Reg, Lo32Reg, ShiftAmt); 1865 } 1866 } else { 1867 assert(ExtOpc == AMDGPU::G_ANYEXT && "not an integer extension"); 1868 B.buildUndef(Hi32Reg); 1869 } 1870 } 1871 1872 bool AMDGPURegisterBankInfo::foldExtractEltToCmpSelect( 1873 MachineInstr &MI, MachineRegisterInfo &MRI, 1874 const OperandsMapper &OpdMapper) const { 1875 1876 Register VecReg = MI.getOperand(1).getReg(); 1877 Register Idx = MI.getOperand(2).getReg(); 1878 1879 const RegisterBank &IdxBank = 1880 *OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 1881 1882 bool IsDivergentIdx = IdxBank != AMDGPU::SGPRRegBank; 1883 1884 LLT VecTy = MRI.getType(VecReg); 1885 unsigned EltSize = VecTy.getScalarSizeInBits(); 1886 unsigned NumElem = VecTy.getNumElements(); 1887 1888 if (!SITargetLowering::shouldExpandVectorDynExt(EltSize, NumElem, 1889 IsDivergentIdx)) 1890 return false; 1891 1892 MachineIRBuilder B(MI); 1893 LLT S32 = LLT::scalar(32); 1894 1895 const RegisterBank &DstBank = 1896 *OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1897 const RegisterBank &SrcBank = 1898 *OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 1899 1900 const RegisterBank &CCBank = 1901 (DstBank == AMDGPU::SGPRRegBank && 1902 SrcBank == AMDGPU::SGPRRegBank && 1903 IdxBank == AMDGPU::SGPRRegBank) ? AMDGPU::SGPRRegBank 1904 : AMDGPU::VCCRegBank; 1905 LLT CCTy = (CCBank == AMDGPU::SGPRRegBank) ? S32 : LLT::scalar(1); 1906 1907 if (CCBank == AMDGPU::VCCRegBank && IdxBank == AMDGPU::SGPRRegBank) { 1908 Idx = B.buildCopy(S32, Idx)->getOperand(0).getReg(); 1909 MRI.setRegBank(Idx, AMDGPU::VGPRRegBank); 1910 } 1911 1912 LLT EltTy = VecTy.getScalarType(); 1913 SmallVector<Register, 2> DstRegs(OpdMapper.getVRegs(0)); 1914 unsigned NumLanes = DstRegs.size(); 1915 if (!NumLanes) 1916 NumLanes = 1; 1917 else 1918 EltTy = MRI.getType(DstRegs[0]); 1919 1920 auto UnmergeToEltTy = B.buildUnmerge(EltTy, VecReg); 1921 SmallVector<Register, 2> Res(NumLanes); 1922 for (unsigned L = 0; L < NumLanes; ++L) 1923 Res[L] = UnmergeToEltTy.getReg(L); 1924 1925 for (unsigned I = 1; I < NumElem; ++I) { 1926 auto IC = B.buildConstant(S32, I); 1927 MRI.setRegBank(IC->getOperand(0).getReg(), AMDGPU::SGPRRegBank); 1928 auto Cmp = B.buildICmp(CmpInst::ICMP_EQ, CCTy, Idx, IC); 1929 MRI.setRegBank(Cmp->getOperand(0).getReg(), CCBank); 1930 1931 for (unsigned L = 0; L < NumLanes; ++L) { 1932 auto S = B.buildSelect(EltTy, Cmp, 1933 UnmergeToEltTy.getReg(I * NumLanes + L), Res[L]); 1934 1935 for (unsigned N : { 0, 2, 3 }) 1936 MRI.setRegBank(S->getOperand(N).getReg(), DstBank); 1937 1938 Res[L] = S->getOperand(0).getReg(); 1939 } 1940 } 1941 1942 for (unsigned L = 0; L < NumLanes; ++L) { 1943 Register DstReg = (NumLanes == 1) ? MI.getOperand(0).getReg() : DstRegs[L]; 1944 B.buildCopy(DstReg, Res[L]); 1945 MRI.setRegBank(DstReg, DstBank); 1946 } 1947 1948 MRI.setRegBank(MI.getOperand(0).getReg(), DstBank); 1949 MI.eraseFromParent(); 1950 1951 return true; 1952 } 1953 1954 bool AMDGPURegisterBankInfo::foldInsertEltToCmpSelect( 1955 MachineInstr &MI, MachineRegisterInfo &MRI, 1956 const OperandsMapper &OpdMapper) const { 1957 1958 Register VecReg = MI.getOperand(1).getReg(); 1959 Register Idx = MI.getOperand(3).getReg(); 1960 1961 const RegisterBank &IdxBank = 1962 *OpdMapper.getInstrMapping().getOperandMapping(3).BreakDown[0].RegBank; 1963 1964 bool IsDivergentIdx = IdxBank != AMDGPU::SGPRRegBank; 1965 1966 LLT VecTy = MRI.getType(VecReg); 1967 unsigned EltSize = VecTy.getScalarSizeInBits(); 1968 unsigned NumElem = VecTy.getNumElements(); 1969 1970 if (!SITargetLowering::shouldExpandVectorDynExt(EltSize, NumElem, 1971 IsDivergentIdx)) 1972 return false; 1973 1974 MachineIRBuilder B(MI); 1975 LLT S32 = LLT::scalar(32); 1976 1977 const RegisterBank &DstBank = 1978 *OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1979 const RegisterBank &SrcBank = 1980 *OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 1981 const RegisterBank &InsBank = 1982 *OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 1983 1984 const RegisterBank &CCBank = 1985 (DstBank == AMDGPU::SGPRRegBank && 1986 SrcBank == AMDGPU::SGPRRegBank && 1987 InsBank == AMDGPU::SGPRRegBank && 1988 IdxBank == AMDGPU::SGPRRegBank) ? AMDGPU::SGPRRegBank 1989 : AMDGPU::VCCRegBank; 1990 LLT CCTy = (CCBank == AMDGPU::SGPRRegBank) ? S32 : LLT::scalar(1); 1991 1992 if (CCBank == AMDGPU::VCCRegBank && IdxBank == AMDGPU::SGPRRegBank) { 1993 Idx = B.buildCopy(S32, Idx)->getOperand(0).getReg(); 1994 MRI.setRegBank(Idx, AMDGPU::VGPRRegBank); 1995 } 1996 1997 LLT EltTy = VecTy.getScalarType(); 1998 SmallVector<Register, 2> InsRegs(OpdMapper.getVRegs(2)); 1999 unsigned NumLanes = InsRegs.size(); 2000 if (!NumLanes) { 2001 NumLanes = 1; 2002 InsRegs.push_back(MI.getOperand(2).getReg()); 2003 } else { 2004 EltTy = MRI.getType(InsRegs[0]); 2005 } 2006 2007 auto UnmergeToEltTy = B.buildUnmerge(EltTy, VecReg); 2008 SmallVector<Register, 16> Ops(NumElem * NumLanes); 2009 2010 for (unsigned I = 0; I < NumElem; ++I) { 2011 auto IC = B.buildConstant(S32, I); 2012 MRI.setRegBank(IC->getOperand(0).getReg(), AMDGPU::SGPRRegBank); 2013 auto Cmp = B.buildICmp(CmpInst::ICMP_EQ, CCTy, Idx, IC); 2014 MRI.setRegBank(Cmp->getOperand(0).getReg(), CCBank); 2015 2016 for (unsigned L = 0; L < NumLanes; ++L) { 2017 auto S = B.buildSelect(EltTy, Cmp, InsRegs[L], 2018 UnmergeToEltTy.getReg(I * NumLanes + L)); 2019 2020 for (unsigned N : { 0, 2, 3 }) 2021 MRI.setRegBank(S->getOperand(N).getReg(), DstBank); 2022 2023 Ops[I * NumLanes + L] = S->getOperand(0).getReg(); 2024 } 2025 } 2026 2027 LLT MergeTy = LLT::vector(Ops.size(), EltTy); 2028 if (MergeTy == MRI.getType(MI.getOperand(0).getReg())) { 2029 B.buildBuildVector(MI.getOperand(0), Ops); 2030 } else { 2031 auto Vec = B.buildBuildVector(MergeTy, Ops); 2032 MRI.setRegBank(Vec->getOperand(0).getReg(), DstBank); 2033 B.buildBitcast(MI.getOperand(0).getReg(), Vec); 2034 } 2035 2036 MRI.setRegBank(MI.getOperand(0).getReg(), DstBank); 2037 MI.eraseFromParent(); 2038 2039 return true; 2040 } 2041 2042 void AMDGPURegisterBankInfo::applyMappingImpl( 2043 const OperandsMapper &OpdMapper) const { 2044 MachineInstr &MI = OpdMapper.getMI(); 2045 unsigned Opc = MI.getOpcode(); 2046 MachineRegisterInfo &MRI = OpdMapper.getMRI(); 2047 switch (Opc) { 2048 case AMDGPU::G_PHI: { 2049 Register DstReg = MI.getOperand(0).getReg(); 2050 LLT DstTy = MRI.getType(DstReg); 2051 if (DstTy != LLT::scalar(1)) 2052 break; 2053 2054 const LLT S32 = LLT::scalar(32); 2055 const RegisterBank *DstBank = 2056 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2057 if (DstBank == &AMDGPU::VCCRegBank) { 2058 applyDefaultMapping(OpdMapper); 2059 // The standard handling only considers the result register bank for 2060 // phis. For VCC, blindly inserting a copy when the phi is lowered will 2061 // produce an invalid copy. We can only copy with some kind of compare to 2062 // get a vector boolean result. Insert a regitser bank copy that will be 2063 // correctly lowered to a compare. 2064 MachineIRBuilder B(*MI.getParent()->getParent()); 2065 2066 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) { 2067 Register SrcReg = MI.getOperand(I).getReg(); 2068 const RegisterBank *SrcBank = getRegBank(SrcReg, MRI, *TRI); 2069 2070 if (SrcBank != &AMDGPU::VCCRegBank) { 2071 MachineBasicBlock *SrcMBB = MI.getOperand(I + 1).getMBB(); 2072 B.setInsertPt(*SrcMBB, SrcMBB->getFirstTerminator()); 2073 2074 auto Copy = B.buildCopy(LLT::scalar(1), SrcReg); 2075 MRI.setRegBank(Copy.getReg(0), AMDGPU::VCCRegBank); 2076 MI.getOperand(I).setReg(Copy.getReg(0)); 2077 } 2078 } 2079 2080 return; 2081 } 2082 2083 // Phi handling is strange and only considers the bank of the destination. 2084 substituteSimpleCopyRegs(OpdMapper, 0); 2085 2086 // Promote SGPR/VGPR booleans to s32 2087 MachineFunction *MF = MI.getParent()->getParent(); 2088 ApplyRegBankMapping ApplyBank(*this, MRI, DstBank); 2089 MachineIRBuilder B(MI, ApplyBank); 2090 LegalizerHelper Helper(*MF, ApplyBank, B); 2091 2092 if (Helper.widenScalar(MI, 0, S32) != LegalizerHelper::Legalized) 2093 llvm_unreachable("widen scalar should have succeeded"); 2094 2095 return; 2096 } 2097 case AMDGPU::G_ICMP: 2098 case AMDGPU::G_UADDO: 2099 case AMDGPU::G_USUBO: 2100 case AMDGPU::G_UADDE: 2101 case AMDGPU::G_SADDE: 2102 case AMDGPU::G_USUBE: 2103 case AMDGPU::G_SSUBE: { 2104 unsigned BoolDstOp = Opc == AMDGPU::G_ICMP ? 0 : 1; 2105 Register DstReg = MI.getOperand(BoolDstOp).getReg(); 2106 2107 const RegisterBank *DstBank = 2108 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2109 if (DstBank != &AMDGPU::SGPRRegBank) 2110 break; 2111 2112 const bool HasCarryIn = MI.getNumOperands() == 5; 2113 2114 // If this is a scalar compare, promote the result to s32, as the selection 2115 // will end up using a copy to a 32-bit vreg. 2116 const LLT S32 = LLT::scalar(32); 2117 Register NewDstReg = MRI.createGenericVirtualRegister(S32); 2118 MRI.setRegBank(NewDstReg, AMDGPU::SGPRRegBank); 2119 MI.getOperand(BoolDstOp).setReg(NewDstReg); 2120 MachineIRBuilder B(MI); 2121 2122 if (HasCarryIn) { 2123 Register NewSrcReg = MRI.createGenericVirtualRegister(S32); 2124 MRI.setRegBank(NewSrcReg, AMDGPU::SGPRRegBank); 2125 B.buildZExt(NewSrcReg, MI.getOperand(4).getReg()); 2126 MI.getOperand(4).setReg(NewSrcReg); 2127 } 2128 2129 MachineBasicBlock *MBB = MI.getParent(); 2130 B.setInsertPt(*MBB, std::next(MI.getIterator())); 2131 2132 // If we had a constrained VCC result register, a copy was inserted to VCC 2133 // from SGPR. 2134 SmallVector<Register, 1> DefRegs(OpdMapper.getVRegs(0)); 2135 if (DefRegs.empty()) 2136 DefRegs.push_back(DstReg); 2137 B.buildTrunc(DefRegs[0], NewDstReg); 2138 return; 2139 } 2140 case AMDGPU::G_SELECT: { 2141 Register DstReg = MI.getOperand(0).getReg(); 2142 LLT DstTy = MRI.getType(DstReg); 2143 2144 SmallVector<Register, 1> CondRegs(OpdMapper.getVRegs(1)); 2145 if (CondRegs.empty()) 2146 CondRegs.push_back(MI.getOperand(1).getReg()); 2147 else { 2148 assert(CondRegs.size() == 1); 2149 } 2150 2151 const RegisterBank *CondBank = getRegBank(CondRegs[0], MRI, *TRI); 2152 if (CondBank == &AMDGPU::SGPRRegBank) { 2153 MachineIRBuilder B(MI); 2154 const LLT S32 = LLT::scalar(32); 2155 Register NewCondReg = MRI.createGenericVirtualRegister(S32); 2156 MRI.setRegBank(NewCondReg, AMDGPU::SGPRRegBank); 2157 2158 MI.getOperand(1).setReg(NewCondReg); 2159 B.buildZExt(NewCondReg, CondRegs[0]); 2160 } 2161 2162 if (DstTy.getSizeInBits() != 64) 2163 break; 2164 2165 MachineIRBuilder B(MI); 2166 LLT HalfTy = getHalfSizedType(DstTy); 2167 2168 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 2169 SmallVector<Register, 2> Src1Regs(OpdMapper.getVRegs(2)); 2170 SmallVector<Register, 2> Src2Regs(OpdMapper.getVRegs(3)); 2171 2172 // All inputs are SGPRs, nothing special to do. 2173 if (DefRegs.empty()) { 2174 assert(Src1Regs.empty() && Src2Regs.empty()); 2175 break; 2176 } 2177 2178 if (Src1Regs.empty()) 2179 split64BitValueForMapping(B, Src1Regs, HalfTy, MI.getOperand(2).getReg()); 2180 else { 2181 setRegsToType(MRI, Src1Regs, HalfTy); 2182 } 2183 2184 if (Src2Regs.empty()) 2185 split64BitValueForMapping(B, Src2Regs, HalfTy, MI.getOperand(3).getReg()); 2186 else 2187 setRegsToType(MRI, Src2Regs, HalfTy); 2188 2189 setRegsToType(MRI, DefRegs, HalfTy); 2190 2191 B.buildSelect(DefRegs[0], CondRegs[0], Src1Regs[0], Src2Regs[0]); 2192 B.buildSelect(DefRegs[1], CondRegs[0], Src1Regs[1], Src2Regs[1]); 2193 2194 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 2195 MI.eraseFromParent(); 2196 return; 2197 } 2198 case AMDGPU::G_BRCOND: { 2199 Register CondReg = MI.getOperand(0).getReg(); 2200 // FIXME: Should use legalizer helper, but should change bool ext type. 2201 const RegisterBank *CondBank = 2202 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2203 2204 if (CondBank == &AMDGPU::SGPRRegBank) { 2205 MachineIRBuilder B(MI); 2206 const LLT S32 = LLT::scalar(32); 2207 Register NewCondReg = MRI.createGenericVirtualRegister(S32); 2208 MRI.setRegBank(NewCondReg, AMDGPU::SGPRRegBank); 2209 2210 MI.getOperand(0).setReg(NewCondReg); 2211 B.buildZExt(NewCondReg, CondReg); 2212 return; 2213 } 2214 2215 break; 2216 } 2217 case AMDGPU::G_AND: 2218 case AMDGPU::G_OR: 2219 case AMDGPU::G_XOR: { 2220 // 64-bit and is only available on the SALU, so split into 2 32-bit ops if 2221 // there is a VGPR input. 2222 Register DstReg = MI.getOperand(0).getReg(); 2223 LLT DstTy = MRI.getType(DstReg); 2224 2225 if (DstTy.getSizeInBits() == 1) { 2226 const RegisterBank *DstBank = 2227 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2228 if (DstBank == &AMDGPU::VCCRegBank) 2229 break; 2230 2231 MachineFunction *MF = MI.getParent()->getParent(); 2232 ApplyRegBankMapping ApplyBank(*this, MRI, DstBank); 2233 MachineIRBuilder B(MI, ApplyBank); 2234 LegalizerHelper Helper(*MF, ApplyBank, B); 2235 2236 if (Helper.widenScalar(MI, 0, LLT::scalar(32)) != 2237 LegalizerHelper::Legalized) 2238 llvm_unreachable("widen scalar should have succeeded"); 2239 return; 2240 } 2241 2242 if (DstTy.getSizeInBits() != 64) 2243 break; 2244 2245 LLT HalfTy = getHalfSizedType(DstTy); 2246 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 2247 SmallVector<Register, 2> Src0Regs(OpdMapper.getVRegs(1)); 2248 SmallVector<Register, 2> Src1Regs(OpdMapper.getVRegs(2)); 2249 2250 // All inputs are SGPRs, nothing special to do. 2251 if (DefRegs.empty()) { 2252 assert(Src0Regs.empty() && Src1Regs.empty()); 2253 break; 2254 } 2255 2256 assert(DefRegs.size() == 2); 2257 assert(Src0Regs.size() == Src1Regs.size() && 2258 (Src0Regs.empty() || Src0Regs.size() == 2)); 2259 2260 // Depending on where the source registers came from, the generic code may 2261 // have decided to split the inputs already or not. If not, we still need to 2262 // extract the values. 2263 MachineIRBuilder B(MI); 2264 2265 if (Src0Regs.empty()) 2266 split64BitValueForMapping(B, Src0Regs, HalfTy, MI.getOperand(1).getReg()); 2267 else 2268 setRegsToType(MRI, Src0Regs, HalfTy); 2269 2270 if (Src1Regs.empty()) 2271 split64BitValueForMapping(B, Src1Regs, HalfTy, MI.getOperand(2).getReg()); 2272 else 2273 setRegsToType(MRI, Src1Regs, HalfTy); 2274 2275 setRegsToType(MRI, DefRegs, HalfTy); 2276 2277 B.buildInstr(Opc, {DefRegs[0]}, {Src0Regs[0], Src1Regs[0]}); 2278 B.buildInstr(Opc, {DefRegs[1]}, {Src0Regs[1], Src1Regs[1]}); 2279 2280 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 2281 MI.eraseFromParent(); 2282 return; 2283 } 2284 case AMDGPU::G_ADD: 2285 case AMDGPU::G_SUB: 2286 case AMDGPU::G_MUL: 2287 case AMDGPU::G_SHL: 2288 case AMDGPU::G_LSHR: 2289 case AMDGPU::G_ASHR: 2290 case AMDGPU::G_SMIN: 2291 case AMDGPU::G_SMAX: 2292 case AMDGPU::G_UMIN: 2293 case AMDGPU::G_UMAX: { 2294 Register DstReg = MI.getOperand(0).getReg(); 2295 LLT DstTy = MRI.getType(DstReg); 2296 2297 // 16-bit operations are VALU only, but can be promoted to 32-bit SALU. 2298 // Packed 16-bit operations need to be scalarized and promoted. 2299 if (DstTy != LLT::scalar(16) && DstTy != LLT::vector(2, 16)) 2300 break; 2301 2302 const RegisterBank *DstBank = 2303 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2304 if (DstBank == &AMDGPU::VGPRRegBank) 2305 break; 2306 2307 const LLT S32 = LLT::scalar(32); 2308 MachineBasicBlock *MBB = MI.getParent(); 2309 MachineFunction *MF = MBB->getParent(); 2310 ApplyRegBankMapping ApplySALU(*this, MRI, &AMDGPU::SGPRRegBank); 2311 MachineIRBuilder B(MI, ApplySALU); 2312 2313 if (DstTy.isVector()) { 2314 Register WideSrc0Lo, WideSrc0Hi; 2315 Register WideSrc1Lo, WideSrc1Hi; 2316 2317 unsigned ExtendOp = getExtendOp(MI.getOpcode()); 2318 std::tie(WideSrc0Lo, WideSrc0Hi) 2319 = unpackV2S16ToS32(B, MI.getOperand(1).getReg(), ExtendOp); 2320 std::tie(WideSrc1Lo, WideSrc1Hi) 2321 = unpackV2S16ToS32(B, MI.getOperand(2).getReg(), ExtendOp); 2322 auto Lo = B.buildInstr(MI.getOpcode(), {S32}, {WideSrc0Lo, WideSrc1Lo}); 2323 auto Hi = B.buildInstr(MI.getOpcode(), {S32}, {WideSrc0Hi, WideSrc1Hi}); 2324 B.buildBuildVectorTrunc(DstReg, {Lo.getReg(0), Hi.getReg(0)}); 2325 MI.eraseFromParent(); 2326 } else { 2327 LegalizerHelper Helper(*MF, ApplySALU, B); 2328 2329 if (Helper.widenScalar(MI, 0, S32) != LegalizerHelper::Legalized) 2330 llvm_unreachable("widen scalar should have succeeded"); 2331 2332 // FIXME: s16 shift amounts should be legal. 2333 if (Opc == AMDGPU::G_SHL || Opc == AMDGPU::G_LSHR || 2334 Opc == AMDGPU::G_ASHR) { 2335 B.setInsertPt(*MBB, MI.getIterator()); 2336 if (Helper.widenScalar(MI, 1, S32) != LegalizerHelper::Legalized) 2337 llvm_unreachable("widen scalar should have succeeded"); 2338 } 2339 } 2340 2341 return; 2342 } 2343 case AMDGPU::G_SEXT_INREG: { 2344 SmallVector<Register, 2> SrcRegs(OpdMapper.getVRegs(1)); 2345 if (SrcRegs.empty()) 2346 break; // Nothing to repair 2347 2348 const LLT S32 = LLT::scalar(32); 2349 MachineIRBuilder B(MI); 2350 ApplyRegBankMapping O(*this, MRI, &AMDGPU::VGPRRegBank); 2351 GISelObserverWrapper Observer(&O); 2352 B.setChangeObserver(Observer); 2353 2354 // Don't use LegalizerHelper's narrowScalar. It produces unwanted G_SEXTs 2355 // we would need to further expand, and doesn't let us directly set the 2356 // result registers. 2357 SmallVector<Register, 2> DstRegs(OpdMapper.getVRegs(0)); 2358 2359 int Amt = MI.getOperand(2).getImm(); 2360 if (Amt <= 32) { 2361 if (Amt == 32) { 2362 // The low bits are unchanged. 2363 B.buildCopy(DstRegs[0], SrcRegs[0]); 2364 } else { 2365 // Extend in the low bits and propagate the sign bit to the high half. 2366 B.buildSExtInReg(DstRegs[0], SrcRegs[0], Amt); 2367 } 2368 2369 B.buildAShr(DstRegs[1], DstRegs[0], B.buildConstant(S32, 31)); 2370 } else { 2371 // The low bits are unchanged, and extend in the high bits. 2372 B.buildCopy(DstRegs[0], SrcRegs[0]); 2373 B.buildSExtInReg(DstRegs[1], DstRegs[0], Amt - 32); 2374 } 2375 2376 Register DstReg = MI.getOperand(0).getReg(); 2377 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 2378 MI.eraseFromParent(); 2379 return; 2380 } 2381 case AMDGPU::G_CTPOP: 2382 case AMDGPU::G_BITREVERSE: 2383 case AMDGPU::G_CTLZ_ZERO_UNDEF: 2384 case AMDGPU::G_CTTZ_ZERO_UNDEF: { 2385 const RegisterBank *DstBank = 2386 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2387 if (DstBank == &AMDGPU::SGPRRegBank) 2388 break; 2389 2390 Register SrcReg = MI.getOperand(1).getReg(); 2391 const LLT S32 = LLT::scalar(32); 2392 LLT Ty = MRI.getType(SrcReg); 2393 if (Ty == S32) 2394 break; 2395 2396 ApplyRegBankMapping ApplyVALU(*this, MRI, &AMDGPU::VGPRRegBank); 2397 MachineIRBuilder B(MI, ApplyVALU); 2398 2399 MachineFunction &MF = B.getMF(); 2400 LegalizerHelper Helper(MF, ApplyVALU, B); 2401 2402 if (Helper.narrowScalar(MI, 1, S32) != LegalizerHelper::Legalized) 2403 llvm_unreachable("narrowScalar should have succeeded"); 2404 return; 2405 } 2406 case AMDGPU::G_SEXT: 2407 case AMDGPU::G_ZEXT: 2408 case AMDGPU::G_ANYEXT: { 2409 Register SrcReg = MI.getOperand(1).getReg(); 2410 LLT SrcTy = MRI.getType(SrcReg); 2411 const bool Signed = Opc == AMDGPU::G_SEXT; 2412 2413 assert(empty(OpdMapper.getVRegs(1))); 2414 2415 MachineIRBuilder B(MI); 2416 const RegisterBank *SrcBank = 2417 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 2418 2419 Register DstReg = MI.getOperand(0).getReg(); 2420 LLT DstTy = MRI.getType(DstReg); 2421 if (DstTy.isScalar() && 2422 SrcBank != &AMDGPU::SGPRRegBank && 2423 SrcBank != &AMDGPU::VCCRegBank && 2424 // FIXME: Should handle any type that round to s64 when irregular 2425 // breakdowns supported. 2426 DstTy.getSizeInBits() == 64 && 2427 SrcTy.getSizeInBits() <= 32) { 2428 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 2429 2430 // Extend to 32-bit, and then extend the low half. 2431 if (Signed) { 2432 // TODO: Should really be buildSExtOrCopy 2433 B.buildSExtOrTrunc(DefRegs[0], SrcReg); 2434 } else if (Opc == AMDGPU::G_ZEXT) { 2435 B.buildZExtOrTrunc(DefRegs[0], SrcReg); 2436 } else { 2437 B.buildAnyExtOrTrunc(DefRegs[0], SrcReg); 2438 } 2439 2440 extendLow32IntoHigh32(B, DefRegs[1], DefRegs[0], Opc, *SrcBank); 2441 MRI.setRegBank(DstReg, *SrcBank); 2442 MI.eraseFromParent(); 2443 return; 2444 } 2445 2446 if (SrcTy != LLT::scalar(1)) 2447 return; 2448 2449 // It is not legal to have a legalization artifact with a VCC source. Rather 2450 // than introducing a copy, insert the select we would have to select the 2451 // copy to. 2452 if (SrcBank == &AMDGPU::VCCRegBank) { 2453 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 2454 2455 const RegisterBank *DstBank = &AMDGPU::VGPRRegBank; 2456 2457 unsigned DstSize = DstTy.getSizeInBits(); 2458 // 64-bit select is SGPR only 2459 const bool UseSel64 = DstSize > 32 && 2460 SrcBank->getID() == AMDGPU::SGPRRegBankID; 2461 2462 // TODO: Should s16 select be legal? 2463 LLT SelType = UseSel64 ? LLT::scalar(64) : LLT::scalar(32); 2464 auto True = B.buildConstant(SelType, Signed ? -1 : 1); 2465 auto False = B.buildConstant(SelType, 0); 2466 2467 MRI.setRegBank(True.getReg(0), *DstBank); 2468 MRI.setRegBank(False.getReg(0), *DstBank); 2469 MRI.setRegBank(DstReg, *DstBank); 2470 2471 if (DstSize > 32) { 2472 B.buildSelect(DefRegs[0], SrcReg, True, False); 2473 extendLow32IntoHigh32(B, DefRegs[1], DefRegs[0], Opc, *SrcBank, true); 2474 } else if (DstSize < 32) { 2475 auto Sel = B.buildSelect(SelType, SrcReg, True, False); 2476 MRI.setRegBank(Sel.getReg(0), *DstBank); 2477 B.buildTrunc(DstReg, Sel); 2478 } else { 2479 B.buildSelect(DstReg, SrcReg, True, False); 2480 } 2481 2482 MI.eraseFromParent(); 2483 return; 2484 } 2485 2486 break; 2487 } 2488 case AMDGPU::G_BUILD_VECTOR: 2489 case AMDGPU::G_BUILD_VECTOR_TRUNC: { 2490 Register DstReg = MI.getOperand(0).getReg(); 2491 LLT DstTy = MRI.getType(DstReg); 2492 if (DstTy != LLT::vector(2, 16)) 2493 break; 2494 2495 assert(MI.getNumOperands() == 3 && OpdMapper.getVRegs(0).empty()); 2496 substituteSimpleCopyRegs(OpdMapper, 1); 2497 substituteSimpleCopyRegs(OpdMapper, 2); 2498 2499 const RegisterBank *DstBank = 2500 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2501 if (DstBank == &AMDGPU::SGPRRegBank) 2502 break; // Can use S_PACK_* instructions. 2503 2504 MachineIRBuilder B(MI); 2505 2506 Register Lo = MI.getOperand(1).getReg(); 2507 Register Hi = MI.getOperand(2).getReg(); 2508 const LLT S32 = LLT::scalar(32); 2509 2510 const RegisterBank *BankLo = 2511 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 2512 const RegisterBank *BankHi = 2513 OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 2514 2515 Register ZextLo; 2516 Register ShiftHi; 2517 2518 if (Opc == AMDGPU::G_BUILD_VECTOR) { 2519 ZextLo = B.buildZExt(S32, Lo).getReg(0); 2520 MRI.setRegBank(ZextLo, *BankLo); 2521 2522 Register ZextHi = B.buildZExt(S32, Hi).getReg(0); 2523 MRI.setRegBank(ZextHi, *BankHi); 2524 2525 auto ShiftAmt = B.buildConstant(S32, 16); 2526 MRI.setRegBank(ShiftAmt.getReg(0), *BankHi); 2527 2528 ShiftHi = B.buildShl(S32, ZextHi, ShiftAmt).getReg(0); 2529 MRI.setRegBank(ShiftHi, *BankHi); 2530 } else { 2531 Register MaskLo = B.buildConstant(S32, 0xffff).getReg(0); 2532 MRI.setRegBank(MaskLo, *BankLo); 2533 2534 auto ShiftAmt = B.buildConstant(S32, 16); 2535 MRI.setRegBank(ShiftAmt.getReg(0), *BankHi); 2536 2537 ShiftHi = B.buildShl(S32, Hi, ShiftAmt).getReg(0); 2538 MRI.setRegBank(ShiftHi, *BankHi); 2539 2540 ZextLo = B.buildAnd(S32, Lo, MaskLo).getReg(0); 2541 MRI.setRegBank(ZextLo, *BankLo); 2542 } 2543 2544 auto Or = B.buildOr(S32, ZextLo, ShiftHi); 2545 MRI.setRegBank(Or.getReg(0), *DstBank); 2546 2547 B.buildBitcast(DstReg, Or); 2548 MI.eraseFromParent(); 2549 return; 2550 } 2551 case AMDGPU::G_EXTRACT_VECTOR_ELT: { 2552 SmallVector<Register, 2> DstRegs(OpdMapper.getVRegs(0)); 2553 2554 assert(OpdMapper.getVRegs(1).empty() && OpdMapper.getVRegs(2).empty()); 2555 2556 Register DstReg = MI.getOperand(0).getReg(); 2557 Register SrcReg = MI.getOperand(1).getReg(); 2558 2559 const LLT S32 = LLT::scalar(32); 2560 LLT DstTy = MRI.getType(DstReg); 2561 LLT SrcTy = MRI.getType(SrcReg); 2562 2563 if (foldExtractEltToCmpSelect(MI, MRI, OpdMapper)) 2564 return; 2565 2566 MachineIRBuilder B(MI); 2567 2568 const ValueMapping &DstMapping 2569 = OpdMapper.getInstrMapping().getOperandMapping(0); 2570 const RegisterBank *DstBank = DstMapping.BreakDown[0].RegBank; 2571 const RegisterBank *SrcBank = 2572 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 2573 const RegisterBank *IdxBank = 2574 OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 2575 2576 Register BaseIdxReg; 2577 unsigned ConstOffset; 2578 std::tie(BaseIdxReg, ConstOffset) = 2579 AMDGPU::getBaseWithConstantOffset(MRI, MI.getOperand(2).getReg()); 2580 2581 // See if the index is an add of a constant which will be foldable by moving 2582 // the base register of the index later if this is going to be executed in a 2583 // waterfall loop. This is essentially to reassociate the add of a constant 2584 // with the readfirstlane. 2585 bool ShouldMoveIndexIntoLoop = IdxBank != &AMDGPU::SGPRRegBank && 2586 ConstOffset > 0 && 2587 ConstOffset < SrcTy.getNumElements(); 2588 2589 // Move the base register. We'll re-insert the add later. 2590 if (ShouldMoveIndexIntoLoop) 2591 MI.getOperand(2).setReg(BaseIdxReg); 2592 2593 // If this is a VGPR result only because the index was a VGPR result, the 2594 // actual indexing will be done on the SGPR source vector, which will 2595 // produce a scalar result. We need to copy to the VGPR result inside the 2596 // waterfall loop. 2597 const bool NeedCopyToVGPR = DstBank == &AMDGPU::VGPRRegBank && 2598 SrcBank == &AMDGPU::SGPRRegBank; 2599 if (DstRegs.empty()) { 2600 applyDefaultMapping(OpdMapper); 2601 2602 executeInWaterfallLoop(MI, MRI, { 2 }); 2603 2604 if (NeedCopyToVGPR) { 2605 // We don't want a phi for this temporary reg. 2606 Register TmpReg = MRI.createGenericVirtualRegister(DstTy); 2607 MRI.setRegBank(TmpReg, AMDGPU::SGPRRegBank); 2608 MI.getOperand(0).setReg(TmpReg); 2609 B.setInsertPt(*MI.getParent(), ++MI.getIterator()); 2610 2611 // Use a v_mov_b32 here to make the exec dependency explicit. 2612 buildVCopy(B, DstReg, TmpReg); 2613 } 2614 2615 // Re-insert the constant offset add inside the waterfall loop. 2616 if (ShouldMoveIndexIntoLoop) 2617 reinsertVectorIndexAdd(B, MI, 2, ConstOffset); 2618 2619 return; 2620 } 2621 2622 assert(DstTy.getSizeInBits() == 64); 2623 2624 LLT Vec32 = LLT::vector(2 * SrcTy.getNumElements(), 32); 2625 2626 auto CastSrc = B.buildBitcast(Vec32, SrcReg); 2627 auto One = B.buildConstant(S32, 1); 2628 2629 MachineBasicBlock::iterator MII = MI.getIterator(); 2630 2631 // Split the vector index into 32-bit pieces. Prepare to move all of the 2632 // new instructions into a waterfall loop if necessary. 2633 // 2634 // Don't put the bitcast or constant in the loop. 2635 MachineInstrSpan Span(MII, &B.getMBB()); 2636 2637 // Compute 32-bit element indices, (2 * OrigIdx, 2 * OrigIdx + 1). 2638 auto IdxLo = B.buildShl(S32, BaseIdxReg, One); 2639 auto IdxHi = B.buildAdd(S32, IdxLo, One); 2640 2641 auto Extract0 = B.buildExtractVectorElement(DstRegs[0], CastSrc, IdxLo); 2642 auto Extract1 = B.buildExtractVectorElement(DstRegs[1], CastSrc, IdxHi); 2643 2644 MRI.setRegBank(DstReg, *DstBank); 2645 MRI.setRegBank(CastSrc.getReg(0), *SrcBank); 2646 MRI.setRegBank(One.getReg(0), AMDGPU::SGPRRegBank); 2647 MRI.setRegBank(IdxLo.getReg(0), AMDGPU::SGPRRegBank); 2648 MRI.setRegBank(IdxHi.getReg(0), AMDGPU::SGPRRegBank); 2649 2650 SmallSet<Register, 4> OpsToWaterfall; 2651 if (!collectWaterfallOperands(OpsToWaterfall, MI, MRI, { 2 })) { 2652 MI.eraseFromParent(); 2653 return; 2654 } 2655 2656 // Remove the original instruction to avoid potentially confusing the 2657 // waterfall loop logic. 2658 B.setInstr(*Span.begin()); 2659 MI.eraseFromParent(); 2660 executeInWaterfallLoop(B, make_range(Span.begin(), Span.end()), 2661 OpsToWaterfall, MRI); 2662 2663 if (NeedCopyToVGPR) { 2664 MachineBasicBlock *LoopBB = Extract1->getParent(); 2665 Register TmpReg0 = MRI.createGenericVirtualRegister(S32); 2666 Register TmpReg1 = MRI.createGenericVirtualRegister(S32); 2667 MRI.setRegBank(TmpReg0, AMDGPU::SGPRRegBank); 2668 MRI.setRegBank(TmpReg1, AMDGPU::SGPRRegBank); 2669 2670 Extract0->getOperand(0).setReg(TmpReg0); 2671 Extract1->getOperand(0).setReg(TmpReg1); 2672 2673 B.setInsertPt(*LoopBB, ++Extract1->getIterator()); 2674 2675 buildVCopy(B, DstRegs[0], TmpReg0); 2676 buildVCopy(B, DstRegs[1], TmpReg1); 2677 } 2678 2679 if (ShouldMoveIndexIntoLoop) 2680 reinsertVectorIndexAdd(B, *IdxLo, 1, ConstOffset); 2681 2682 return; 2683 } 2684 case AMDGPU::G_INSERT_VECTOR_ELT: { 2685 SmallVector<Register, 2> InsRegs(OpdMapper.getVRegs(2)); 2686 2687 Register DstReg = MI.getOperand(0).getReg(); 2688 LLT VecTy = MRI.getType(DstReg); 2689 2690 assert(OpdMapper.getVRegs(0).empty()); 2691 assert(OpdMapper.getVRegs(3).empty()); 2692 2693 if (substituteSimpleCopyRegs(OpdMapper, 1)) 2694 MRI.setType(MI.getOperand(1).getReg(), VecTy); 2695 2696 if (foldInsertEltToCmpSelect(MI, MRI, OpdMapper)) 2697 return; 2698 2699 const RegisterBank *IdxBank = 2700 OpdMapper.getInstrMapping().getOperandMapping(3).BreakDown[0].RegBank; 2701 2702 Register SrcReg = MI.getOperand(1).getReg(); 2703 Register InsReg = MI.getOperand(2).getReg(); 2704 LLT InsTy = MRI.getType(InsReg); 2705 (void)InsTy; 2706 2707 Register BaseIdxReg; 2708 unsigned ConstOffset; 2709 std::tie(BaseIdxReg, ConstOffset) = 2710 AMDGPU::getBaseWithConstantOffset(MRI, MI.getOperand(3).getReg()); 2711 2712 // See if the index is an add of a constant which will be foldable by moving 2713 // the base register of the index later if this is going to be executed in a 2714 // waterfall loop. This is essentially to reassociate the add of a constant 2715 // with the readfirstlane. 2716 bool ShouldMoveIndexIntoLoop = IdxBank != &AMDGPU::SGPRRegBank && 2717 ConstOffset > 0 && 2718 ConstOffset < VecTy.getNumElements(); 2719 2720 // Move the base register. We'll re-insert the add later. 2721 if (ShouldMoveIndexIntoLoop) 2722 MI.getOperand(3).setReg(BaseIdxReg); 2723 2724 2725 if (InsRegs.empty()) { 2726 executeInWaterfallLoop(MI, MRI, { 3 }); 2727 2728 // Re-insert the constant offset add inside the waterfall loop. 2729 if (ShouldMoveIndexIntoLoop) { 2730 MachineIRBuilder B(MI); 2731 reinsertVectorIndexAdd(B, MI, 3, ConstOffset); 2732 } 2733 2734 return; 2735 } 2736 2737 2738 assert(InsTy.getSizeInBits() == 64); 2739 2740 const LLT S32 = LLT::scalar(32); 2741 LLT Vec32 = LLT::vector(2 * VecTy.getNumElements(), 32); 2742 2743 MachineIRBuilder B(MI); 2744 auto CastSrc = B.buildBitcast(Vec32, SrcReg); 2745 auto One = B.buildConstant(S32, 1); 2746 2747 // Split the vector index into 32-bit pieces. Prepare to move all of the 2748 // new instructions into a waterfall loop if necessary. 2749 // 2750 // Don't put the bitcast or constant in the loop. 2751 MachineInstrSpan Span(MachineBasicBlock::iterator(&MI), &B.getMBB()); 2752 2753 // Compute 32-bit element indices, (2 * OrigIdx, 2 * OrigIdx + 1). 2754 auto IdxLo = B.buildShl(S32, BaseIdxReg, One); 2755 auto IdxHi = B.buildAdd(S32, IdxLo, One); 2756 2757 auto InsLo = B.buildInsertVectorElement(Vec32, CastSrc, InsRegs[0], IdxLo); 2758 auto InsHi = B.buildInsertVectorElement(Vec32, InsLo, InsRegs[1], IdxHi); 2759 2760 const RegisterBank *DstBank = 2761 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2762 const RegisterBank *SrcBank = 2763 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 2764 const RegisterBank *InsSrcBank = 2765 OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 2766 2767 MRI.setRegBank(InsReg, *InsSrcBank); 2768 MRI.setRegBank(CastSrc.getReg(0), *SrcBank); 2769 MRI.setRegBank(InsLo.getReg(0), *DstBank); 2770 MRI.setRegBank(InsHi.getReg(0), *DstBank); 2771 MRI.setRegBank(One.getReg(0), AMDGPU::SGPRRegBank); 2772 MRI.setRegBank(IdxLo.getReg(0), AMDGPU::SGPRRegBank); 2773 MRI.setRegBank(IdxHi.getReg(0), AMDGPU::SGPRRegBank); 2774 2775 2776 SmallSet<Register, 4> OpsToWaterfall; 2777 if (!collectWaterfallOperands(OpsToWaterfall, MI, MRI, { 3 })) { 2778 B.setInsertPt(B.getMBB(), MI); 2779 B.buildBitcast(DstReg, InsHi); 2780 MI.eraseFromParent(); 2781 return; 2782 } 2783 2784 B.setInstr(*Span.begin()); 2785 MI.eraseFromParent(); 2786 2787 // Figure out the point after the waterfall loop before mangling the control 2788 // flow. 2789 executeInWaterfallLoop(B, make_range(Span.begin(), Span.end()), 2790 OpsToWaterfall, MRI); 2791 2792 // The insertion point is now right after the original instruction. 2793 // 2794 // Keep the bitcast to the original vector type out of the loop. Doing this 2795 // saved an extra phi we don't need inside the loop. 2796 B.buildBitcast(DstReg, InsHi); 2797 2798 // Re-insert the constant offset add inside the waterfall loop. 2799 if (ShouldMoveIndexIntoLoop) 2800 reinsertVectorIndexAdd(B, *IdxLo, 1, ConstOffset); 2801 2802 return; 2803 } 2804 case AMDGPU::G_AMDGPU_BUFFER_LOAD: 2805 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT: 2806 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT: 2807 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE: 2808 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE: 2809 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT: 2810 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT_D16: 2811 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT: 2812 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT_D16: 2813 case AMDGPU::G_AMDGPU_BUFFER_STORE: 2814 case AMDGPU::G_AMDGPU_BUFFER_STORE_BYTE: 2815 case AMDGPU::G_AMDGPU_BUFFER_STORE_SHORT: 2816 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT: 2817 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT_D16: 2818 case AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT: 2819 case AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT_D16: { 2820 applyDefaultMapping(OpdMapper); 2821 executeInWaterfallLoop(MI, MRI, {1, 4}); 2822 return; 2823 } 2824 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SWAP: 2825 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_ADD: 2826 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SUB: 2827 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMIN: 2828 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMIN: 2829 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMAX: 2830 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMAX: 2831 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_AND: 2832 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_OR: 2833 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_XOR: 2834 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_INC: 2835 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_DEC: { 2836 applyDefaultMapping(OpdMapper); 2837 executeInWaterfallLoop(MI, MRI, {2, 5}); 2838 return; 2839 } 2840 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FADD: 2841 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FMIN: 2842 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FMAX: { 2843 applyDefaultMapping(OpdMapper); 2844 executeInWaterfallLoop(MI, MRI, {2, 5}); 2845 return; 2846 } 2847 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_CMPSWAP: { 2848 applyDefaultMapping(OpdMapper); 2849 executeInWaterfallLoop(MI, MRI, {3, 6}); 2850 return; 2851 } 2852 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD: { 2853 applyMappingSBufferLoad(OpdMapper); 2854 return; 2855 } 2856 case AMDGPU::G_INTRINSIC: { 2857 switch (MI.getIntrinsicID()) { 2858 case Intrinsic::amdgcn_readlane: { 2859 substituteSimpleCopyRegs(OpdMapper, 2); 2860 2861 assert(OpdMapper.getVRegs(0).empty()); 2862 assert(OpdMapper.getVRegs(3).empty()); 2863 2864 // Make sure the index is an SGPR. It doesn't make sense to run this in a 2865 // waterfall loop, so assume it's a uniform value. 2866 constrainOpWithReadfirstlane(MI, MRI, 3); // Index 2867 return; 2868 } 2869 case Intrinsic::amdgcn_writelane: { 2870 assert(OpdMapper.getVRegs(0).empty()); 2871 assert(OpdMapper.getVRegs(2).empty()); 2872 assert(OpdMapper.getVRegs(3).empty()); 2873 2874 substituteSimpleCopyRegs(OpdMapper, 4); // VGPR input val 2875 constrainOpWithReadfirstlane(MI, MRI, 2); // Source value 2876 constrainOpWithReadfirstlane(MI, MRI, 3); // Index 2877 return; 2878 } 2879 case Intrinsic::amdgcn_interp_p1: 2880 case Intrinsic::amdgcn_interp_p2: 2881 case Intrinsic::amdgcn_interp_mov: 2882 case Intrinsic::amdgcn_interp_p1_f16: 2883 case Intrinsic::amdgcn_interp_p2_f16: { 2884 applyDefaultMapping(OpdMapper); 2885 2886 // Readlane for m0 value, which is always the last operand. 2887 // FIXME: Should this be a waterfall loop instead? 2888 constrainOpWithReadfirstlane(MI, MRI, MI.getNumOperands() - 1); // Index 2889 return; 2890 } 2891 case Intrinsic::amdgcn_permlane16: 2892 case Intrinsic::amdgcn_permlanex16: { 2893 // Doing a waterfall loop over these wouldn't make any sense. 2894 substituteSimpleCopyRegs(OpdMapper, 2); 2895 substituteSimpleCopyRegs(OpdMapper, 3); 2896 constrainOpWithReadfirstlane(MI, MRI, 4); 2897 constrainOpWithReadfirstlane(MI, MRI, 5); 2898 return; 2899 } 2900 case Intrinsic::amdgcn_sbfe: 2901 applyMappingBFEIntrinsic(OpdMapper, true); 2902 return; 2903 case Intrinsic::amdgcn_ubfe: 2904 applyMappingBFEIntrinsic(OpdMapper, false); 2905 return; 2906 case Intrinsic::amdgcn_ballot: 2907 // Use default handling and insert copy to vcc source. 2908 break; 2909 } 2910 break; 2911 } 2912 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD: 2913 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE: { 2914 const AMDGPU::RsrcIntrinsic *RSrcIntrin 2915 = AMDGPU::lookupRsrcIntrinsic(MI.getIntrinsicID()); 2916 assert(RSrcIntrin && RSrcIntrin->IsImage); 2917 // Non-images can have complications from operands that allow both SGPR 2918 // and VGPR. For now it's too complicated to figure out the final opcode 2919 // to derive the register bank from the MCInstrDesc. 2920 applyMappingImage(MI, OpdMapper, MRI, RSrcIntrin->RsrcArg); 2921 return; 2922 } 2923 case AMDGPU::G_AMDGPU_INTRIN_BVH_INTERSECT_RAY: { 2924 unsigned N = MI.getNumExplicitOperands() - 2; 2925 executeInWaterfallLoop(MI, MRI, { N }); 2926 return; 2927 } 2928 case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: { 2929 auto IntrID = MI.getIntrinsicID(); 2930 switch (IntrID) { 2931 case Intrinsic::amdgcn_ds_ordered_add: 2932 case Intrinsic::amdgcn_ds_ordered_swap: { 2933 // This is only allowed to execute with 1 lane, so readfirstlane is safe. 2934 assert(OpdMapper.getVRegs(0).empty()); 2935 substituteSimpleCopyRegs(OpdMapper, 3); 2936 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 2937 return; 2938 } 2939 case Intrinsic::amdgcn_ds_gws_init: 2940 case Intrinsic::amdgcn_ds_gws_barrier: 2941 case Intrinsic::amdgcn_ds_gws_sema_br: { 2942 // Only the first lane is executes, so readfirstlane is safe. 2943 substituteSimpleCopyRegs(OpdMapper, 1); 2944 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 2945 return; 2946 } 2947 case Intrinsic::amdgcn_ds_gws_sema_v: 2948 case Intrinsic::amdgcn_ds_gws_sema_p: 2949 case Intrinsic::amdgcn_ds_gws_sema_release_all: { 2950 // Only the first lane is executes, so readfirstlane is safe. 2951 constrainOpWithReadfirstlane(MI, MRI, 1); // M0 2952 return; 2953 } 2954 case Intrinsic::amdgcn_ds_append: 2955 case Intrinsic::amdgcn_ds_consume: { 2956 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 2957 return; 2958 } 2959 case Intrinsic::amdgcn_s_sendmsg: 2960 case Intrinsic::amdgcn_s_sendmsghalt: { 2961 // FIXME: Should this use a waterfall loop? 2962 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 2963 return; 2964 } 2965 case Intrinsic::amdgcn_s_setreg: { 2966 constrainOpWithReadfirstlane(MI, MRI, 2); 2967 return; 2968 } 2969 default: { 2970 if (const AMDGPU::RsrcIntrinsic *RSrcIntrin = 2971 AMDGPU::lookupRsrcIntrinsic(IntrID)) { 2972 // Non-images can have complications from operands that allow both SGPR 2973 // and VGPR. For now it's too complicated to figure out the final opcode 2974 // to derive the register bank from the MCInstrDesc. 2975 if (RSrcIntrin->IsImage) { 2976 applyMappingImage(MI, OpdMapper, MRI, RSrcIntrin->RsrcArg); 2977 return; 2978 } 2979 } 2980 2981 break; 2982 } 2983 } 2984 break; 2985 } 2986 case AMDGPU::G_LOAD: 2987 case AMDGPU::G_ZEXTLOAD: 2988 case AMDGPU::G_SEXTLOAD: { 2989 if (applyMappingLoad(MI, OpdMapper, MRI)) 2990 return; 2991 break; 2992 } 2993 case AMDGPU::G_DYN_STACKALLOC: 2994 applyMappingDynStackAlloc(MI, OpdMapper, MRI); 2995 return; 2996 default: 2997 break; 2998 } 2999 3000 return applyDefaultMapping(OpdMapper); 3001 } 3002 3003 // vgpr, sgpr -> vgpr 3004 // vgpr, agpr -> vgpr 3005 // agpr, agpr -> agpr 3006 // agpr, sgpr -> vgpr 3007 static unsigned regBankUnion(unsigned RB0, unsigned RB1) { 3008 if (RB0 == AMDGPU::InvalidRegBankID) 3009 return RB1; 3010 if (RB1 == AMDGPU::InvalidRegBankID) 3011 return RB0; 3012 3013 if (RB0 == AMDGPU::SGPRRegBankID && RB1 == AMDGPU::SGPRRegBankID) 3014 return AMDGPU::SGPRRegBankID; 3015 3016 if (RB0 == AMDGPU::AGPRRegBankID && RB1 == AMDGPU::AGPRRegBankID) 3017 return AMDGPU::AGPRRegBankID; 3018 3019 return AMDGPU::VGPRRegBankID; 3020 } 3021 3022 static unsigned regBankBoolUnion(unsigned RB0, unsigned RB1) { 3023 if (RB0 == AMDGPU::InvalidRegBankID) 3024 return RB1; 3025 if (RB1 == AMDGPU::InvalidRegBankID) 3026 return RB0; 3027 3028 // vcc, vcc -> vcc 3029 // vcc, sgpr -> vcc 3030 // vcc, vgpr -> vcc 3031 if (RB0 == AMDGPU::VCCRegBankID || RB1 == AMDGPU::VCCRegBankID) 3032 return AMDGPU::VCCRegBankID; 3033 3034 // vcc, vgpr -> vgpr 3035 return regBankUnion(RB0, RB1); 3036 } 3037 3038 unsigned AMDGPURegisterBankInfo::getMappingType(const MachineRegisterInfo &MRI, 3039 const MachineInstr &MI) const { 3040 unsigned RegBank = AMDGPU::InvalidRegBankID; 3041 3042 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 3043 if (!MI.getOperand(i).isReg()) 3044 continue; 3045 Register Reg = MI.getOperand(i).getReg(); 3046 if (const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI)) { 3047 RegBank = regBankUnion(RegBank, Bank->getID()); 3048 if (RegBank == AMDGPU::VGPRRegBankID) 3049 break; 3050 } 3051 } 3052 3053 return RegBank; 3054 } 3055 3056 bool AMDGPURegisterBankInfo::isSALUMapping(const MachineInstr &MI) const { 3057 const MachineFunction &MF = *MI.getParent()->getParent(); 3058 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3059 for (unsigned i = 0, e = MI.getNumOperands();i != e; ++i) { 3060 if (!MI.getOperand(i).isReg()) 3061 continue; 3062 Register Reg = MI.getOperand(i).getReg(); 3063 if (const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI)) { 3064 if (Bank->getID() != AMDGPU::SGPRRegBankID) 3065 return false; 3066 } 3067 } 3068 return true; 3069 } 3070 3071 const RegisterBankInfo::InstructionMapping & 3072 AMDGPURegisterBankInfo::getDefaultMappingSOP(const MachineInstr &MI) const { 3073 const MachineFunction &MF = *MI.getParent()->getParent(); 3074 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3075 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 3076 3077 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 3078 const MachineOperand &SrcOp = MI.getOperand(i); 3079 if (!SrcOp.isReg()) 3080 continue; 3081 3082 unsigned Size = getSizeInBits(SrcOp.getReg(), MRI, *TRI); 3083 OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3084 } 3085 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), 3086 MI.getNumOperands()); 3087 } 3088 3089 const RegisterBankInfo::InstructionMapping & 3090 AMDGPURegisterBankInfo::getDefaultMappingVOP(const MachineInstr &MI) const { 3091 const MachineFunction &MF = *MI.getParent()->getParent(); 3092 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3093 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 3094 3095 // Even though we technically could use SGPRs, this would require knowledge of 3096 // the constant bus restriction. Force all sources to VGPR (except for VCC). 3097 // 3098 // TODO: Unary ops are trivially OK, so accept SGPRs? 3099 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 3100 const MachineOperand &Src = MI.getOperand(i); 3101 if (!Src.isReg()) 3102 continue; 3103 3104 unsigned Size = getSizeInBits(Src.getReg(), MRI, *TRI); 3105 unsigned BankID = Size == 1 ? AMDGPU::VCCRegBankID : AMDGPU::VGPRRegBankID; 3106 OpdsMapping[i] = AMDGPU::getValueMapping(BankID, Size); 3107 } 3108 3109 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), 3110 MI.getNumOperands()); 3111 } 3112 3113 const RegisterBankInfo::InstructionMapping & 3114 AMDGPURegisterBankInfo::getDefaultMappingAllVGPR(const MachineInstr &MI) const { 3115 const MachineFunction &MF = *MI.getParent()->getParent(); 3116 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3117 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 3118 3119 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) { 3120 const MachineOperand &Op = MI.getOperand(I); 3121 if (!Op.isReg()) 3122 continue; 3123 3124 unsigned Size = getSizeInBits(Op.getReg(), MRI, *TRI); 3125 OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3126 } 3127 3128 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), 3129 MI.getNumOperands()); 3130 } 3131 3132 const RegisterBankInfo::InstructionMapping & 3133 AMDGPURegisterBankInfo::getImageMapping(const MachineRegisterInfo &MRI, 3134 const MachineInstr &MI, 3135 int RsrcIdx) const { 3136 // The reported argument index is relative to the IR intrinsic call arguments, 3137 // so we need to shift by the number of defs and the intrinsic ID. 3138 RsrcIdx += MI.getNumExplicitDefs() + 1; 3139 3140 const int NumOps = MI.getNumOperands(); 3141 SmallVector<const ValueMapping *, 8> OpdsMapping(NumOps); 3142 3143 // TODO: Should packed/unpacked D16 difference be reported here as part of 3144 // the value mapping? 3145 for (int I = 0; I != NumOps; ++I) { 3146 if (!MI.getOperand(I).isReg()) 3147 continue; 3148 3149 Register OpReg = MI.getOperand(I).getReg(); 3150 // We replace some dead address operands with $noreg 3151 if (!OpReg) 3152 continue; 3153 3154 unsigned Size = getSizeInBits(OpReg, MRI, *TRI); 3155 3156 // FIXME: Probably need a new intrinsic register bank searchable table to 3157 // handle arbitrary intrinsics easily. 3158 // 3159 // If this has a sampler, it immediately follows rsrc. 3160 const bool MustBeSGPR = I == RsrcIdx || I == RsrcIdx + 1; 3161 3162 if (MustBeSGPR) { 3163 // If this must be an SGPR, so we must report whatever it is as legal. 3164 unsigned NewBank = getRegBankID(OpReg, MRI, AMDGPU::SGPRRegBankID); 3165 OpdsMapping[I] = AMDGPU::getValueMapping(NewBank, Size); 3166 } else { 3167 // Some operands must be VGPR, and these are easy to copy to. 3168 OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3169 } 3170 } 3171 3172 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), NumOps); 3173 } 3174 3175 /// Return the mapping for a pointer arugment. 3176 const RegisterBankInfo::ValueMapping * 3177 AMDGPURegisterBankInfo::getValueMappingForPtr(const MachineRegisterInfo &MRI, 3178 Register PtrReg) const { 3179 LLT PtrTy = MRI.getType(PtrReg); 3180 unsigned Size = PtrTy.getSizeInBits(); 3181 if (Subtarget.useFlatForGlobal() || 3182 !AMDGPU::isFlatGlobalAddrSpace(PtrTy.getAddressSpace())) 3183 return AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3184 3185 // If we're using MUBUF instructions for global memory, an SGPR base register 3186 // is possible. Otherwise this needs to be a VGPR. 3187 const RegisterBank *PtrBank = getRegBank(PtrReg, MRI, *TRI); 3188 return AMDGPU::getValueMapping(PtrBank->getID(), Size); 3189 } 3190 3191 const RegisterBankInfo::InstructionMapping & 3192 AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const { 3193 3194 const MachineFunction &MF = *MI.getParent()->getParent(); 3195 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3196 SmallVector<const ValueMapping*, 2> OpdsMapping(2); 3197 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3198 Register PtrReg = MI.getOperand(1).getReg(); 3199 LLT PtrTy = MRI.getType(PtrReg); 3200 unsigned AS = PtrTy.getAddressSpace(); 3201 unsigned PtrSize = PtrTy.getSizeInBits(); 3202 3203 const ValueMapping *ValMapping; 3204 const ValueMapping *PtrMapping; 3205 3206 const RegisterBank *PtrBank = getRegBank(PtrReg, MRI, *TRI); 3207 3208 if (PtrBank == &AMDGPU::SGPRRegBank && AMDGPU::isFlatGlobalAddrSpace(AS)) { 3209 if (isScalarLoadLegal(MI)) { 3210 // We have a uniform instruction so we want to use an SMRD load 3211 ValMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3212 PtrMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize); 3213 } else { 3214 ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3215 3216 // If we're using MUBUF instructions for global memory, an SGPR base 3217 // register is possible. Otherwise this needs to be a VGPR. 3218 unsigned PtrBankID = Subtarget.useFlatForGlobal() ? 3219 AMDGPU::VGPRRegBankID : AMDGPU::SGPRRegBankID; 3220 3221 PtrMapping = AMDGPU::getValueMapping(PtrBankID, PtrSize); 3222 } 3223 } else { 3224 ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3225 PtrMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize); 3226 } 3227 3228 OpdsMapping[0] = ValMapping; 3229 OpdsMapping[1] = PtrMapping; 3230 const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping( 3231 1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands()); 3232 return Mapping; 3233 3234 // FIXME: Do we want to add a mapping for FLAT load, or should we just 3235 // handle that during instruction selection? 3236 } 3237 3238 unsigned 3239 AMDGPURegisterBankInfo::getRegBankID(Register Reg, 3240 const MachineRegisterInfo &MRI, 3241 unsigned Default) const { 3242 const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI); 3243 return Bank ? Bank->getID() : Default; 3244 } 3245 3246 const RegisterBankInfo::ValueMapping * 3247 AMDGPURegisterBankInfo::getSGPROpMapping(Register Reg, 3248 const MachineRegisterInfo &MRI, 3249 const TargetRegisterInfo &TRI) const { 3250 // Lie and claim anything is legal, even though this needs to be an SGPR 3251 // applyMapping will have to deal with it as a waterfall loop. 3252 unsigned Bank = getRegBankID(Reg, MRI, AMDGPU::SGPRRegBankID); 3253 unsigned Size = getSizeInBits(Reg, MRI, TRI); 3254 return AMDGPU::getValueMapping(Bank, Size); 3255 } 3256 3257 const RegisterBankInfo::ValueMapping * 3258 AMDGPURegisterBankInfo::getVGPROpMapping(Register Reg, 3259 const MachineRegisterInfo &MRI, 3260 const TargetRegisterInfo &TRI) const { 3261 unsigned Size = getSizeInBits(Reg, MRI, TRI); 3262 return AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3263 } 3264 3265 const RegisterBankInfo::ValueMapping * 3266 AMDGPURegisterBankInfo::getAGPROpMapping(Register Reg, 3267 const MachineRegisterInfo &MRI, 3268 const TargetRegisterInfo &TRI) const { 3269 unsigned Size = getSizeInBits(Reg, MRI, TRI); 3270 return AMDGPU::getValueMapping(AMDGPU::AGPRRegBankID, Size); 3271 } 3272 3273 /// 3274 /// This function must return a legal mapping, because 3275 /// AMDGPURegisterBankInfo::getInstrAlternativeMappings() is not called 3276 /// in RegBankSelect::Mode::Fast. Any mapping that would cause a 3277 /// VGPR to SGPR generated is illegal. 3278 /// 3279 // Operands that must be SGPRs must accept potentially divergent VGPRs as 3280 // legal. These will be dealt with in applyMappingImpl. 3281 // 3282 const RegisterBankInfo::InstructionMapping & 3283 AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 3284 const MachineFunction &MF = *MI.getParent()->getParent(); 3285 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3286 3287 if (MI.isCopy() || MI.getOpcode() == AMDGPU::G_FREEZE) { 3288 // The default logic bothers to analyze impossible alternative mappings. We 3289 // want the most straightforward mapping, so just directly handle this. 3290 const RegisterBank *DstBank = getRegBank(MI.getOperand(0).getReg(), MRI, 3291 *TRI); 3292 const RegisterBank *SrcBank = getRegBank(MI.getOperand(1).getReg(), MRI, 3293 *TRI); 3294 assert(SrcBank && "src bank should have been assigned already"); 3295 if (!DstBank) 3296 DstBank = SrcBank; 3297 3298 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3299 if (cannotCopy(*DstBank, *SrcBank, Size)) 3300 return getInvalidInstructionMapping(); 3301 3302 const ValueMapping &ValMap = getValueMapping(0, Size, *DstBank); 3303 unsigned OpdsMappingSize = MI.isCopy() ? 1 : 2; 3304 SmallVector<const ValueMapping *, 1> OpdsMapping(OpdsMappingSize); 3305 OpdsMapping[0] = &ValMap; 3306 if (MI.getOpcode() == AMDGPU::G_FREEZE) 3307 OpdsMapping[1] = &ValMap; 3308 3309 return getInstructionMapping( 3310 1, /*Cost*/ 1, 3311 /*OperandsMapping*/ getOperandsMapping(OpdsMapping), OpdsMappingSize); 3312 } 3313 3314 if (MI.isRegSequence()) { 3315 // If any input is a VGPR, the result must be a VGPR. The default handling 3316 // assumes any copy between banks is legal. 3317 unsigned BankID = AMDGPU::SGPRRegBankID; 3318 3319 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) { 3320 auto OpBank = getRegBankID(MI.getOperand(I).getReg(), MRI); 3321 // It doesn't make sense to use vcc or scc banks here, so just ignore 3322 // them. 3323 if (OpBank != AMDGPU::SGPRRegBankID) { 3324 BankID = AMDGPU::VGPRRegBankID; 3325 break; 3326 } 3327 } 3328 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3329 3330 const ValueMapping &ValMap = getValueMapping(0, Size, getRegBank(BankID)); 3331 return getInstructionMapping( 3332 1, /*Cost*/ 1, 3333 /*OperandsMapping*/ getOperandsMapping({&ValMap}), 1); 3334 } 3335 3336 // The default handling is broken and doesn't handle illegal SGPR->VGPR copies 3337 // properly. 3338 // 3339 // TODO: There are additional exec masking dependencies to analyze. 3340 if (MI.getOpcode() == TargetOpcode::G_PHI) { 3341 unsigned ResultBank = AMDGPU::InvalidRegBankID; 3342 Register DstReg = MI.getOperand(0).getReg(); 3343 3344 // Sometimes the result may have already been assigned a bank. 3345 if (const RegisterBank *DstBank = getRegBank(DstReg, MRI, *TRI)) 3346 ResultBank = DstBank->getID(); 3347 3348 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) { 3349 Register Reg = MI.getOperand(I).getReg(); 3350 const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI); 3351 3352 // FIXME: Assuming VGPR for any undetermined inputs. 3353 if (!Bank || Bank->getID() == AMDGPU::VGPRRegBankID) { 3354 ResultBank = AMDGPU::VGPRRegBankID; 3355 break; 3356 } 3357 3358 // FIXME: Need to promote SGPR case to s32 3359 unsigned OpBank = Bank->getID(); 3360 ResultBank = regBankBoolUnion(ResultBank, OpBank); 3361 } 3362 3363 assert(ResultBank != AMDGPU::InvalidRegBankID); 3364 3365 unsigned Size = MRI.getType(DstReg).getSizeInBits(); 3366 3367 const ValueMapping &ValMap = 3368 getValueMapping(0, Size, getRegBank(ResultBank)); 3369 return getInstructionMapping( 3370 1, /*Cost*/ 1, 3371 /*OperandsMapping*/ getOperandsMapping({&ValMap}), 1); 3372 } 3373 3374 const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); 3375 if (Mapping.isValid()) 3376 return Mapping; 3377 3378 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 3379 3380 switch (MI.getOpcode()) { 3381 default: 3382 return getInvalidInstructionMapping(); 3383 3384 case AMDGPU::G_AND: 3385 case AMDGPU::G_OR: 3386 case AMDGPU::G_XOR: { 3387 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3388 if (Size == 1) { 3389 const RegisterBank *DstBank 3390 = getRegBank(MI.getOperand(0).getReg(), MRI, *TRI); 3391 3392 unsigned TargetBankID = AMDGPU::InvalidRegBankID; 3393 unsigned BankLHS = AMDGPU::InvalidRegBankID; 3394 unsigned BankRHS = AMDGPU::InvalidRegBankID; 3395 if (DstBank) { 3396 TargetBankID = DstBank->getID(); 3397 if (DstBank == &AMDGPU::VCCRegBank) { 3398 TargetBankID = AMDGPU::VCCRegBankID; 3399 BankLHS = AMDGPU::VCCRegBankID; 3400 BankRHS = AMDGPU::VCCRegBankID; 3401 } else { 3402 BankLHS = getRegBankID(MI.getOperand(1).getReg(), MRI, 3403 AMDGPU::SGPRRegBankID); 3404 BankRHS = getRegBankID(MI.getOperand(2).getReg(), MRI, 3405 AMDGPU::SGPRRegBankID); 3406 } 3407 } else { 3408 BankLHS = getRegBankID(MI.getOperand(1).getReg(), MRI, 3409 AMDGPU::VCCRegBankID); 3410 BankRHS = getRegBankID(MI.getOperand(2).getReg(), MRI, 3411 AMDGPU::VCCRegBankID); 3412 3413 // Both inputs should be true booleans to produce a boolean result. 3414 if (BankLHS == AMDGPU::VGPRRegBankID || BankRHS == AMDGPU::VGPRRegBankID) { 3415 TargetBankID = AMDGPU::VGPRRegBankID; 3416 } else if (BankLHS == AMDGPU::VCCRegBankID || BankRHS == AMDGPU::VCCRegBankID) { 3417 TargetBankID = AMDGPU::VCCRegBankID; 3418 BankLHS = AMDGPU::VCCRegBankID; 3419 BankRHS = AMDGPU::VCCRegBankID; 3420 } else if (BankLHS == AMDGPU::SGPRRegBankID && BankRHS == AMDGPU::SGPRRegBankID) { 3421 TargetBankID = AMDGPU::SGPRRegBankID; 3422 } 3423 } 3424 3425 OpdsMapping[0] = AMDGPU::getValueMapping(TargetBankID, Size); 3426 OpdsMapping[1] = AMDGPU::getValueMapping(BankLHS, Size); 3427 OpdsMapping[2] = AMDGPU::getValueMapping(BankRHS, Size); 3428 break; 3429 } 3430 3431 if (Size == 64) { 3432 3433 if (isSALUMapping(MI)) { 3434 OpdsMapping[0] = getValueMappingSGPR64Only(AMDGPU::SGPRRegBankID, Size); 3435 OpdsMapping[1] = OpdsMapping[2] = OpdsMapping[0]; 3436 } else { 3437 OpdsMapping[0] = getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size); 3438 unsigned Bank1 = getRegBankID(MI.getOperand(1).getReg(), MRI /*, DefaultBankID*/); 3439 OpdsMapping[1] = AMDGPU::getValueMapping(Bank1, Size); 3440 3441 unsigned Bank2 = getRegBankID(MI.getOperand(2).getReg(), MRI /*, DefaultBankID*/); 3442 OpdsMapping[2] = AMDGPU::getValueMapping(Bank2, Size); 3443 } 3444 3445 break; 3446 } 3447 3448 LLVM_FALLTHROUGH; 3449 } 3450 case AMDGPU::G_PTR_ADD: 3451 case AMDGPU::G_PTRMASK: 3452 case AMDGPU::G_ADD: 3453 case AMDGPU::G_SUB: 3454 case AMDGPU::G_MUL: 3455 case AMDGPU::G_SHL: 3456 case AMDGPU::G_LSHR: 3457 case AMDGPU::G_ASHR: 3458 case AMDGPU::G_UADDO: 3459 case AMDGPU::G_USUBO: 3460 case AMDGPU::G_UADDE: 3461 case AMDGPU::G_SADDE: 3462 case AMDGPU::G_USUBE: 3463 case AMDGPU::G_SSUBE: 3464 case AMDGPU::G_SMIN: 3465 case AMDGPU::G_SMAX: 3466 case AMDGPU::G_UMIN: 3467 case AMDGPU::G_UMAX: 3468 case AMDGPU::G_SHUFFLE_VECTOR: 3469 if (isSALUMapping(MI)) 3470 return getDefaultMappingSOP(MI); 3471 LLVM_FALLTHROUGH; 3472 3473 case AMDGPU::G_SADDSAT: // FIXME: Could lower sat ops for SALU 3474 case AMDGPU::G_SSUBSAT: 3475 case AMDGPU::G_UADDSAT: 3476 case AMDGPU::G_USUBSAT: 3477 case AMDGPU::G_FADD: 3478 case AMDGPU::G_FSUB: 3479 case AMDGPU::G_FPTOSI: 3480 case AMDGPU::G_FPTOUI: 3481 case AMDGPU::G_FMUL: 3482 case AMDGPU::G_FMA: 3483 case AMDGPU::G_FMAD: 3484 case AMDGPU::G_FSQRT: 3485 case AMDGPU::G_FFLOOR: 3486 case AMDGPU::G_FCEIL: 3487 case AMDGPU::G_FRINT: 3488 case AMDGPU::G_SITOFP: 3489 case AMDGPU::G_UITOFP: 3490 case AMDGPU::G_FPTRUNC: 3491 case AMDGPU::G_FPEXT: 3492 case AMDGPU::G_FEXP2: 3493 case AMDGPU::G_FLOG2: 3494 case AMDGPU::G_FMINNUM: 3495 case AMDGPU::G_FMAXNUM: 3496 case AMDGPU::G_FMINNUM_IEEE: 3497 case AMDGPU::G_FMAXNUM_IEEE: 3498 case AMDGPU::G_FCANONICALIZE: 3499 case AMDGPU::G_INTRINSIC_TRUNC: 3500 case AMDGPU::G_BSWAP: // TODO: Somehow expand for scalar? 3501 case AMDGPU::G_FSHR: // TODO: Expand for scalar 3502 case AMDGPU::G_AMDGPU_FFBH_U32: 3503 case AMDGPU::G_AMDGPU_FMIN_LEGACY: 3504 case AMDGPU::G_AMDGPU_FMAX_LEGACY: 3505 case AMDGPU::G_AMDGPU_RCP_IFLAG: 3506 case AMDGPU::G_AMDGPU_CVT_F32_UBYTE0: 3507 case AMDGPU::G_AMDGPU_CVT_F32_UBYTE1: 3508 case AMDGPU::G_AMDGPU_CVT_F32_UBYTE2: 3509 case AMDGPU::G_AMDGPU_CVT_F32_UBYTE3: 3510 case AMDGPU::G_AMDGPU_CVT_PK_I16_I32: 3511 case AMDGPU::G_AMDGPU_SMED3: 3512 return getDefaultMappingVOP(MI); 3513 case AMDGPU::G_UMULH: 3514 case AMDGPU::G_SMULH: { 3515 if (Subtarget.hasScalarMulHiInsts() && isSALUMapping(MI)) 3516 return getDefaultMappingSOP(MI); 3517 return getDefaultMappingVOP(MI); 3518 } 3519 case AMDGPU::G_IMPLICIT_DEF: { 3520 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3521 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3522 break; 3523 } 3524 case AMDGPU::G_FCONSTANT: 3525 case AMDGPU::G_CONSTANT: 3526 case AMDGPU::G_GLOBAL_VALUE: 3527 case AMDGPU::G_BLOCK_ADDR: 3528 case AMDGPU::G_READCYCLECOUNTER: { 3529 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3530 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3531 break; 3532 } 3533 case AMDGPU::G_FRAME_INDEX: { 3534 // TODO: This should be the same as other constants, but eliminateFrameIndex 3535 // currently assumes VALU uses. 3536 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3537 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3538 break; 3539 } 3540 case AMDGPU::G_DYN_STACKALLOC: { 3541 // Result is always uniform, and a wave reduction is needed for the source. 3542 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32); 3543 unsigned SrcBankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3544 OpdsMapping[1] = AMDGPU::getValueMapping(SrcBankID, 32); 3545 break; 3546 } 3547 case AMDGPU::G_INSERT: { 3548 unsigned BankID = getMappingType(MRI, MI); 3549 unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3550 unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 3551 unsigned EltSize = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI); 3552 OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize); 3553 OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize); 3554 OpdsMapping[2] = AMDGPU::getValueMapping(BankID, EltSize); 3555 OpdsMapping[3] = nullptr; 3556 break; 3557 } 3558 case AMDGPU::G_EXTRACT: { 3559 unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3560 unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3561 unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 3562 OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize); 3563 OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize); 3564 OpdsMapping[2] = nullptr; 3565 break; 3566 } 3567 case AMDGPU::G_BUILD_VECTOR: 3568 case AMDGPU::G_BUILD_VECTOR_TRUNC: { 3569 LLT DstTy = MRI.getType(MI.getOperand(0).getReg()); 3570 if (DstTy == LLT::vector(2, 16)) { 3571 unsigned DstSize = DstTy.getSizeInBits(); 3572 unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 3573 unsigned Src0BankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3574 unsigned Src1BankID = getRegBankID(MI.getOperand(2).getReg(), MRI); 3575 unsigned DstBankID = regBankUnion(Src0BankID, Src1BankID); 3576 3577 OpdsMapping[0] = AMDGPU::getValueMapping(DstBankID, DstSize); 3578 OpdsMapping[1] = AMDGPU::getValueMapping(Src0BankID, SrcSize); 3579 OpdsMapping[2] = AMDGPU::getValueMapping(Src1BankID, SrcSize); 3580 break; 3581 } 3582 3583 LLVM_FALLTHROUGH; 3584 } 3585 case AMDGPU::G_MERGE_VALUES: 3586 case AMDGPU::G_CONCAT_VECTORS: { 3587 unsigned Bank = getMappingType(MRI, MI); 3588 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3589 unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 3590 3591 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize); 3592 // Op1 and Dst should use the same register bank. 3593 for (unsigned i = 1, e = MI.getNumOperands(); i != e; ++i) 3594 OpdsMapping[i] = AMDGPU::getValueMapping(Bank, SrcSize); 3595 break; 3596 } 3597 case AMDGPU::G_BITREVERSE: 3598 case AMDGPU::G_BITCAST: 3599 case AMDGPU::G_INTTOPTR: 3600 case AMDGPU::G_PTRTOINT: 3601 case AMDGPU::G_FABS: 3602 case AMDGPU::G_FNEG: { 3603 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3604 unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3605 OpdsMapping[0] = OpdsMapping[1] = AMDGPU::getValueMapping(BankID, Size); 3606 break; 3607 } 3608 case AMDGPU::G_CTLZ_ZERO_UNDEF: 3609 case AMDGPU::G_CTTZ_ZERO_UNDEF: 3610 case AMDGPU::G_CTPOP: { 3611 unsigned Size = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 3612 unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3613 OpdsMapping[0] = AMDGPU::getValueMapping(BankID, 32); 3614 3615 // This should really be getValueMappingSGPR64Only, but allowing the generic 3616 // code to handle the register split just makes using LegalizerHelper more 3617 // difficult. 3618 OpdsMapping[1] = AMDGPU::getValueMapping(BankID, Size); 3619 break; 3620 } 3621 case AMDGPU::G_TRUNC: { 3622 Register Dst = MI.getOperand(0).getReg(); 3623 Register Src = MI.getOperand(1).getReg(); 3624 unsigned Bank = getRegBankID(Src, MRI); 3625 unsigned DstSize = getSizeInBits(Dst, MRI, *TRI); 3626 unsigned SrcSize = getSizeInBits(Src, MRI, *TRI); 3627 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize); 3628 OpdsMapping[1] = AMDGPU::getValueMapping(Bank, SrcSize); 3629 break; 3630 } 3631 case AMDGPU::G_ZEXT: 3632 case AMDGPU::G_SEXT: 3633 case AMDGPU::G_ANYEXT: 3634 case AMDGPU::G_SEXT_INREG: { 3635 Register Dst = MI.getOperand(0).getReg(); 3636 Register Src = MI.getOperand(1).getReg(); 3637 unsigned DstSize = getSizeInBits(Dst, MRI, *TRI); 3638 unsigned SrcSize = getSizeInBits(Src, MRI, *TRI); 3639 3640 unsigned DstBank; 3641 const RegisterBank *SrcBank = getRegBank(Src, MRI, *TRI); 3642 assert(SrcBank); 3643 switch (SrcBank->getID()) { 3644 case AMDGPU::SGPRRegBankID: 3645 DstBank = AMDGPU::SGPRRegBankID; 3646 break; 3647 default: 3648 DstBank = AMDGPU::VGPRRegBankID; 3649 break; 3650 } 3651 3652 // Scalar extend can use 64-bit BFE, but VGPRs require extending to 3653 // 32-bits, and then to 64. 3654 OpdsMapping[0] = AMDGPU::getValueMappingSGPR64Only(DstBank, DstSize); 3655 OpdsMapping[1] = AMDGPU::getValueMappingSGPR64Only(SrcBank->getID(), 3656 SrcSize); 3657 break; 3658 } 3659 case AMDGPU::G_FCMP: { 3660 unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3661 unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI); 3662 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 3663 OpdsMapping[1] = nullptr; // Predicate Operand. 3664 OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size); 3665 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3666 break; 3667 } 3668 case AMDGPU::G_STORE: { 3669 assert(MI.getOperand(0).isReg()); 3670 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3671 3672 // FIXME: We need to specify a different reg bank once scalar stores are 3673 // supported. 3674 const ValueMapping *ValMapping = 3675 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3676 OpdsMapping[0] = ValMapping; 3677 OpdsMapping[1] = getValueMappingForPtr(MRI, MI.getOperand(1).getReg()); 3678 break; 3679 } 3680 case AMDGPU::G_ICMP: { 3681 auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()); 3682 unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3683 3684 // See if the result register has already been constrained to vcc, which may 3685 // happen due to control flow intrinsic lowering. 3686 unsigned DstBank = getRegBankID(MI.getOperand(0).getReg(), MRI, 3687 AMDGPU::SGPRRegBankID); 3688 unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI); 3689 unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI); 3690 3691 bool CanUseSCC = DstBank == AMDGPU::SGPRRegBankID && 3692 Op2Bank == AMDGPU::SGPRRegBankID && 3693 Op3Bank == AMDGPU::SGPRRegBankID && 3694 (Size == 32 || (Size == 64 && 3695 (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) && 3696 Subtarget.hasScalarCompareEq64())); 3697 3698 DstBank = CanUseSCC ? AMDGPU::SGPRRegBankID : AMDGPU::VCCRegBankID; 3699 unsigned SrcBank = CanUseSCC ? AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID; 3700 3701 // TODO: Use 32-bit for scalar output size. 3702 // SCC results will need to be copied to a 32-bit SGPR virtual register. 3703 const unsigned ResultSize = 1; 3704 3705 OpdsMapping[0] = AMDGPU::getValueMapping(DstBank, ResultSize); 3706 OpdsMapping[2] = AMDGPU::getValueMapping(SrcBank, Size); 3707 OpdsMapping[3] = AMDGPU::getValueMapping(SrcBank, Size); 3708 break; 3709 } 3710 case AMDGPU::G_EXTRACT_VECTOR_ELT: { 3711 // VGPR index can be used for waterfall when indexing a SGPR vector. 3712 unsigned SrcBankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3713 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3714 unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 3715 unsigned IdxSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3716 unsigned IdxBank = getRegBankID(MI.getOperand(2).getReg(), MRI); 3717 unsigned OutputBankID = regBankUnion(SrcBankID, IdxBank); 3718 3719 OpdsMapping[0] = AMDGPU::getValueMappingSGPR64Only(OutputBankID, DstSize); 3720 OpdsMapping[1] = AMDGPU::getValueMapping(SrcBankID, SrcSize); 3721 3722 // The index can be either if the source vector is VGPR. 3723 OpdsMapping[2] = AMDGPU::getValueMapping(IdxBank, IdxSize); 3724 break; 3725 } 3726 case AMDGPU::G_INSERT_VECTOR_ELT: { 3727 unsigned OutputBankID = isSALUMapping(MI) ? 3728 AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID; 3729 3730 unsigned VecSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3731 unsigned InsertSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3732 unsigned IdxSize = MRI.getType(MI.getOperand(3).getReg()).getSizeInBits(); 3733 unsigned InsertEltBankID = getRegBankID(MI.getOperand(2).getReg(), MRI); 3734 unsigned IdxBankID = getRegBankID(MI.getOperand(3).getReg(), MRI); 3735 3736 OpdsMapping[0] = AMDGPU::getValueMapping(OutputBankID, VecSize); 3737 OpdsMapping[1] = AMDGPU::getValueMapping(OutputBankID, VecSize); 3738 3739 // This is a weird case, because we need to break down the mapping based on 3740 // the register bank of a different operand. 3741 if (InsertSize == 64 && OutputBankID == AMDGPU::VGPRRegBankID) { 3742 OpdsMapping[2] = AMDGPU::getValueMappingSplit64(InsertEltBankID, 3743 InsertSize); 3744 } else { 3745 assert(InsertSize == 32 || InsertSize == 64); 3746 OpdsMapping[2] = AMDGPU::getValueMapping(InsertEltBankID, InsertSize); 3747 } 3748 3749 // The index can be either if the source vector is VGPR. 3750 OpdsMapping[3] = AMDGPU::getValueMapping(IdxBankID, IdxSize); 3751 break; 3752 } 3753 case AMDGPU::G_UNMERGE_VALUES: { 3754 unsigned Bank = getMappingType(MRI, MI); 3755 3756 // Op1 and Dst should use the same register bank. 3757 // FIXME: Shouldn't this be the default? Why do we need to handle this? 3758 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 3759 unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI); 3760 OpdsMapping[i] = AMDGPU::getValueMapping(Bank, Size); 3761 } 3762 break; 3763 } 3764 case AMDGPU::G_AMDGPU_BUFFER_LOAD: 3765 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE: 3766 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE: 3767 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT: 3768 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT: 3769 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT: 3770 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT_D16: 3771 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT: 3772 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT_D16: 3773 case AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT: 3774 case AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT_D16: 3775 case AMDGPU::G_AMDGPU_BUFFER_STORE: 3776 case AMDGPU::G_AMDGPU_BUFFER_STORE_BYTE: 3777 case AMDGPU::G_AMDGPU_BUFFER_STORE_SHORT: 3778 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT: 3779 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT_D16: { 3780 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3781 3782 // rsrc 3783 OpdsMapping[1] = getSGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3784 3785 // vindex 3786 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3787 3788 // voffset 3789 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3790 3791 // soffset 3792 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3793 3794 // Any remaining operands are immediates and were correctly null 3795 // initialized. 3796 break; 3797 } 3798 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SWAP: 3799 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_ADD: 3800 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SUB: 3801 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMIN: 3802 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMIN: 3803 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMAX: 3804 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMAX: 3805 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_AND: 3806 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_OR: 3807 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_XOR: 3808 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_INC: 3809 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_DEC: 3810 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FADD: 3811 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FMIN: 3812 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FMAX: { 3813 // vdata_out 3814 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3815 3816 // vdata_in 3817 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3818 3819 // rsrc 3820 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3821 3822 // vindex 3823 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3824 3825 // voffset 3826 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3827 3828 // soffset 3829 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 3830 3831 // Any remaining operands are immediates and were correctly null 3832 // initialized. 3833 break; 3834 } 3835 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_CMPSWAP: { 3836 // vdata_out 3837 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3838 3839 // vdata_in 3840 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3841 3842 // cmp 3843 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3844 3845 // rsrc 3846 OpdsMapping[3] = getSGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3847 3848 // vindex 3849 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3850 3851 // voffset 3852 OpdsMapping[5] = getVGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 3853 3854 // soffset 3855 OpdsMapping[6] = getSGPROpMapping(MI.getOperand(6).getReg(), MRI, *TRI); 3856 3857 // Any remaining operands are immediates and were correctly null 3858 // initialized. 3859 break; 3860 } 3861 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD: { 3862 // Lie and claim everything is legal, even though some need to be 3863 // SGPRs. applyMapping will have to deal with it as a waterfall loop. 3864 OpdsMapping[1] = getSGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3865 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3866 3867 // We need to convert this to a MUBUF if either the resource of offset is 3868 // VGPR. 3869 unsigned RSrcBank = OpdsMapping[1]->BreakDown[0].RegBank->getID(); 3870 unsigned OffsetBank = OpdsMapping[2]->BreakDown[0].RegBank->getID(); 3871 unsigned ResultBank = regBankUnion(RSrcBank, OffsetBank); 3872 3873 unsigned Size0 = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3874 OpdsMapping[0] = AMDGPU::getValueMapping(ResultBank, Size0); 3875 break; 3876 } 3877 case AMDGPU::G_INTRINSIC: { 3878 switch (MI.getIntrinsicID()) { 3879 default: 3880 return getInvalidInstructionMapping(); 3881 case Intrinsic::amdgcn_div_fmas: 3882 case Intrinsic::amdgcn_div_fixup: 3883 case Intrinsic::amdgcn_trig_preop: 3884 case Intrinsic::amdgcn_sin: 3885 case Intrinsic::amdgcn_cos: 3886 case Intrinsic::amdgcn_log_clamp: 3887 case Intrinsic::amdgcn_rcp: 3888 case Intrinsic::amdgcn_rcp_legacy: 3889 case Intrinsic::amdgcn_sqrt: 3890 case Intrinsic::amdgcn_rsq: 3891 case Intrinsic::amdgcn_rsq_legacy: 3892 case Intrinsic::amdgcn_rsq_clamp: 3893 case Intrinsic::amdgcn_fmul_legacy: 3894 case Intrinsic::amdgcn_fma_legacy: 3895 case Intrinsic::amdgcn_ldexp: 3896 case Intrinsic::amdgcn_frexp_mant: 3897 case Intrinsic::amdgcn_frexp_exp: 3898 case Intrinsic::amdgcn_fract: 3899 case Intrinsic::amdgcn_cvt_pkrtz: 3900 case Intrinsic::amdgcn_cvt_pknorm_i16: 3901 case Intrinsic::amdgcn_cvt_pknorm_u16: 3902 case Intrinsic::amdgcn_cvt_pk_i16: 3903 case Intrinsic::amdgcn_cvt_pk_u16: 3904 case Intrinsic::amdgcn_fmed3: 3905 case Intrinsic::amdgcn_cubeid: 3906 case Intrinsic::amdgcn_cubema: 3907 case Intrinsic::amdgcn_cubesc: 3908 case Intrinsic::amdgcn_cubetc: 3909 case Intrinsic::amdgcn_sffbh: 3910 case Intrinsic::amdgcn_fmad_ftz: 3911 case Intrinsic::amdgcn_mbcnt_lo: 3912 case Intrinsic::amdgcn_mbcnt_hi: 3913 case Intrinsic::amdgcn_mul_u24: 3914 case Intrinsic::amdgcn_mul_i24: 3915 case Intrinsic::amdgcn_lerp: 3916 case Intrinsic::amdgcn_sad_u8: 3917 case Intrinsic::amdgcn_msad_u8: 3918 case Intrinsic::amdgcn_sad_hi_u8: 3919 case Intrinsic::amdgcn_sad_u16: 3920 case Intrinsic::amdgcn_qsad_pk_u16_u8: 3921 case Intrinsic::amdgcn_mqsad_pk_u16_u8: 3922 case Intrinsic::amdgcn_mqsad_u32_u8: 3923 case Intrinsic::amdgcn_cvt_pk_u8_f32: 3924 case Intrinsic::amdgcn_alignbit: 3925 case Intrinsic::amdgcn_alignbyte: 3926 case Intrinsic::amdgcn_fdot2: 3927 case Intrinsic::amdgcn_sdot2: 3928 case Intrinsic::amdgcn_udot2: 3929 case Intrinsic::amdgcn_sdot4: 3930 case Intrinsic::amdgcn_udot4: 3931 case Intrinsic::amdgcn_sdot8: 3932 case Intrinsic::amdgcn_udot8: 3933 return getDefaultMappingVOP(MI); 3934 case Intrinsic::amdgcn_sbfe: 3935 case Intrinsic::amdgcn_ubfe: 3936 if (isSALUMapping(MI)) 3937 return getDefaultMappingSOP(MI); 3938 return getDefaultMappingVOP(MI); 3939 case Intrinsic::amdgcn_ds_swizzle: 3940 case Intrinsic::amdgcn_ds_permute: 3941 case Intrinsic::amdgcn_ds_bpermute: 3942 case Intrinsic::amdgcn_update_dpp: 3943 case Intrinsic::amdgcn_mov_dpp8: 3944 case Intrinsic::amdgcn_mov_dpp: 3945 case Intrinsic::amdgcn_strict_wwm: 3946 case Intrinsic::amdgcn_wwm: 3947 case Intrinsic::amdgcn_strict_wqm: 3948 case Intrinsic::amdgcn_wqm: 3949 case Intrinsic::amdgcn_softwqm: 3950 case Intrinsic::amdgcn_set_inactive: 3951 return getDefaultMappingAllVGPR(MI); 3952 case Intrinsic::amdgcn_kernarg_segment_ptr: 3953 case Intrinsic::amdgcn_s_getpc: 3954 case Intrinsic::amdgcn_groupstaticsize: 3955 case Intrinsic::amdgcn_reloc_constant: 3956 case Intrinsic::returnaddress: { 3957 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3958 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3959 break; 3960 } 3961 case Intrinsic::amdgcn_wqm_vote: { 3962 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3963 OpdsMapping[0] = OpdsMapping[2] 3964 = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Size); 3965 break; 3966 } 3967 case Intrinsic::amdgcn_ps_live: { 3968 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 3969 break; 3970 } 3971 case Intrinsic::amdgcn_div_scale: { 3972 unsigned Dst0Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3973 unsigned Dst1Size = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 3974 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Dst0Size); 3975 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Dst1Size); 3976 3977 unsigned SrcSize = MRI.getType(MI.getOperand(3).getReg()).getSizeInBits(); 3978 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 3979 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 3980 break; 3981 } 3982 case Intrinsic::amdgcn_class: { 3983 Register Src0Reg = MI.getOperand(2).getReg(); 3984 Register Src1Reg = MI.getOperand(3).getReg(); 3985 unsigned Src0Size = MRI.getType(Src0Reg).getSizeInBits(); 3986 unsigned Src1Size = MRI.getType(Src1Reg).getSizeInBits(); 3987 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3988 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, DstSize); 3989 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Src0Size); 3990 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Src1Size); 3991 break; 3992 } 3993 case Intrinsic::amdgcn_icmp: 3994 case Intrinsic::amdgcn_fcmp: { 3995 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3996 // This is not VCCRegBank because this is not used in boolean contexts. 3997 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, DstSize); 3998 unsigned OpSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3999 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, OpSize); 4000 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, OpSize); 4001 break; 4002 } 4003 case Intrinsic::amdgcn_readlane: { 4004 // This must be an SGPR, but accept a VGPR. 4005 Register IdxReg = MI.getOperand(3).getReg(); 4006 unsigned IdxSize = MRI.getType(IdxReg).getSizeInBits(); 4007 unsigned IdxBank = getRegBankID(IdxReg, MRI, AMDGPU::SGPRRegBankID); 4008 OpdsMapping[3] = AMDGPU::getValueMapping(IdxBank, IdxSize); 4009 LLVM_FALLTHROUGH; 4010 } 4011 case Intrinsic::amdgcn_readfirstlane: { 4012 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4013 unsigned SrcSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 4014 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, DstSize); 4015 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 4016 break; 4017 } 4018 case Intrinsic::amdgcn_writelane: { 4019 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4020 Register SrcReg = MI.getOperand(2).getReg(); 4021 unsigned SrcSize = MRI.getType(SrcReg).getSizeInBits(); 4022 unsigned SrcBank = getRegBankID(SrcReg, MRI, AMDGPU::SGPRRegBankID); 4023 Register IdxReg = MI.getOperand(3).getReg(); 4024 unsigned IdxSize = MRI.getType(IdxReg).getSizeInBits(); 4025 unsigned IdxBank = getRegBankID(IdxReg, MRI, AMDGPU::SGPRRegBankID); 4026 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 4027 4028 // These 2 must be SGPRs, but accept VGPRs. Readfirstlane will be inserted 4029 // to legalize. 4030 OpdsMapping[2] = AMDGPU::getValueMapping(SrcBank, SrcSize); 4031 OpdsMapping[3] = AMDGPU::getValueMapping(IdxBank, IdxSize); 4032 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 4033 break; 4034 } 4035 case Intrinsic::amdgcn_if_break: { 4036 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 4037 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4038 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 4039 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4040 break; 4041 } 4042 case Intrinsic::amdgcn_permlane16: 4043 case Intrinsic::amdgcn_permlanex16: { 4044 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 4045 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 4046 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 4047 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 4048 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4049 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4050 break; 4051 } 4052 case Intrinsic::amdgcn_mfma_f32_4x4x1f32: 4053 case Intrinsic::amdgcn_mfma_f32_4x4x4f16: 4054 case Intrinsic::amdgcn_mfma_i32_4x4x4i8: 4055 case Intrinsic::amdgcn_mfma_f32_4x4x2bf16: 4056 case Intrinsic::amdgcn_mfma_f32_16x16x1f32: 4057 case Intrinsic::amdgcn_mfma_f32_16x16x4f32: 4058 case Intrinsic::amdgcn_mfma_f32_16x16x4f16: 4059 case Intrinsic::amdgcn_mfma_f32_16x16x16f16: 4060 case Intrinsic::amdgcn_mfma_i32_16x16x4i8: 4061 case Intrinsic::amdgcn_mfma_i32_16x16x16i8: 4062 case Intrinsic::amdgcn_mfma_f32_16x16x2bf16: 4063 case Intrinsic::amdgcn_mfma_f32_16x16x8bf16: 4064 case Intrinsic::amdgcn_mfma_f32_32x32x1f32: 4065 case Intrinsic::amdgcn_mfma_f32_32x32x2f32: 4066 case Intrinsic::amdgcn_mfma_f32_32x32x4f16: 4067 case Intrinsic::amdgcn_mfma_f32_32x32x8f16: 4068 case Intrinsic::amdgcn_mfma_i32_32x32x4i8: 4069 case Intrinsic::amdgcn_mfma_i32_32x32x8i8: 4070 case Intrinsic::amdgcn_mfma_f32_32x32x2bf16: 4071 case Intrinsic::amdgcn_mfma_f32_32x32x4bf16: 4072 case Intrinsic::amdgcn_mfma_f32_32x32x4bf16_1k: 4073 case Intrinsic::amdgcn_mfma_f32_16x16x4bf16_1k: 4074 case Intrinsic::amdgcn_mfma_f32_4x4x4bf16_1k: 4075 case Intrinsic::amdgcn_mfma_f32_32x32x8bf16_1k: 4076 case Intrinsic::amdgcn_mfma_f32_16x16x16bf16_1k: 4077 case Intrinsic::amdgcn_mfma_f64_16x16x4f64: 4078 case Intrinsic::amdgcn_mfma_f64_4x4x4f64: { 4079 // Default for MAI intrinsics. 4080 // srcC can also be an immediate which can be folded later. 4081 // FIXME: Should we eventually add an alternative mapping with AGPR src 4082 // for srcA/srcB? 4083 // 4084 // vdst, srcA, srcB, srcC 4085 OpdsMapping[0] = getAGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 4086 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4087 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4088 OpdsMapping[4] = getAGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4089 break; 4090 } 4091 case Intrinsic::amdgcn_interp_p1: 4092 case Intrinsic::amdgcn_interp_p2: 4093 case Intrinsic::amdgcn_interp_mov: 4094 case Intrinsic::amdgcn_interp_p1_f16: 4095 case Intrinsic::amdgcn_interp_p2_f16: { 4096 const int M0Idx = MI.getNumOperands() - 1; 4097 Register M0Reg = MI.getOperand(M0Idx).getReg(); 4098 unsigned M0Bank = getRegBankID(M0Reg, MRI, AMDGPU::SGPRRegBankID); 4099 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4100 4101 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 4102 for (int I = 2; I != M0Idx && MI.getOperand(I).isReg(); ++I) 4103 OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4104 4105 // Must be SGPR, but we must take whatever the original bank is and fix it 4106 // later. 4107 OpdsMapping[M0Idx] = AMDGPU::getValueMapping(M0Bank, 32); 4108 break; 4109 } 4110 case Intrinsic::amdgcn_ballot: { 4111 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4112 unsigned SrcSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 4113 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, DstSize); 4114 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, SrcSize); 4115 break; 4116 } 4117 } 4118 break; 4119 } 4120 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD: 4121 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE: { 4122 auto IntrID = MI.getIntrinsicID(); 4123 const AMDGPU::RsrcIntrinsic *RSrcIntrin = AMDGPU::lookupRsrcIntrinsic(IntrID); 4124 assert(RSrcIntrin && "missing RsrcIntrinsic for image intrinsic"); 4125 // Non-images can have complications from operands that allow both SGPR 4126 // and VGPR. For now it's too complicated to figure out the final opcode 4127 // to derive the register bank from the MCInstrDesc. 4128 assert(RSrcIntrin->IsImage); 4129 return getImageMapping(MRI, MI, RSrcIntrin->RsrcArg); 4130 } 4131 case AMDGPU::G_AMDGPU_INTRIN_BVH_INTERSECT_RAY: { 4132 unsigned N = MI.getNumExplicitOperands() - 2; 4133 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 128); 4134 OpdsMapping[N] = getSGPROpMapping(MI.getOperand(N).getReg(), MRI, *TRI); 4135 for (unsigned I = 2; I < N; ++I) 4136 OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4137 break; 4138 } 4139 case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: { 4140 auto IntrID = MI.getIntrinsicID(); 4141 switch (IntrID) { 4142 case Intrinsic::amdgcn_s_getreg: 4143 case Intrinsic::amdgcn_s_memtime: 4144 case Intrinsic::amdgcn_s_memrealtime: 4145 case Intrinsic::amdgcn_s_get_waveid_in_workgroup: { 4146 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4147 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4148 break; 4149 } 4150 case Intrinsic::amdgcn_global_atomic_fadd: 4151 case Intrinsic::amdgcn_global_atomic_csub: 4152 case Intrinsic::amdgcn_global_atomic_fmin: 4153 case Intrinsic::amdgcn_global_atomic_fmax: 4154 case Intrinsic::amdgcn_flat_atomic_fadd: 4155 case Intrinsic::amdgcn_flat_atomic_fmin: 4156 case Intrinsic::amdgcn_flat_atomic_fmax: 4157 return getDefaultMappingAllVGPR(MI); 4158 case Intrinsic::amdgcn_ds_ordered_add: 4159 case Intrinsic::amdgcn_ds_ordered_swap: { 4160 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4161 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 4162 unsigned M0Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, 4163 AMDGPU::SGPRRegBankID); 4164 OpdsMapping[2] = AMDGPU::getValueMapping(M0Bank, 32); 4165 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4166 break; 4167 } 4168 case Intrinsic::amdgcn_ds_append: 4169 case Intrinsic::amdgcn_ds_consume: { 4170 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4171 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 4172 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4173 break; 4174 } 4175 case Intrinsic::amdgcn_exp_compr: 4176 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4177 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4178 break; 4179 case Intrinsic::amdgcn_exp: 4180 // FIXME: Could we support packed types here? 4181 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4182 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4183 OpdsMapping[5] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4184 OpdsMapping[6] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4185 break; 4186 case Intrinsic::amdgcn_s_sendmsg: 4187 case Intrinsic::amdgcn_s_sendmsghalt: { 4188 // This must be an SGPR, but accept a VGPR. 4189 unsigned Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, 4190 AMDGPU::SGPRRegBankID); 4191 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, 32); 4192 break; 4193 } 4194 case Intrinsic::amdgcn_s_setreg: { 4195 // This must be an SGPR, but accept a VGPR. 4196 unsigned Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, 4197 AMDGPU::SGPRRegBankID); 4198 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, 32); 4199 break; 4200 } 4201 case Intrinsic::amdgcn_end_cf: { 4202 unsigned Size = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 4203 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4204 break; 4205 } 4206 case Intrinsic::amdgcn_else: { 4207 unsigned WaveSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 4208 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 4209 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, WaveSize); 4210 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, WaveSize); 4211 break; 4212 } 4213 case Intrinsic::amdgcn_live_mask: { 4214 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 4215 break; 4216 } 4217 case Intrinsic::amdgcn_wqm_demote: 4218 case Intrinsic::amdgcn_kill: { 4219 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 4220 break; 4221 } 4222 case Intrinsic::amdgcn_raw_buffer_load: 4223 case Intrinsic::amdgcn_raw_tbuffer_load: { 4224 // FIXME: Should make intrinsic ID the last operand of the instruction, 4225 // then this would be the same as store 4226 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 4227 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4228 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4229 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4230 break; 4231 } 4232 case Intrinsic::amdgcn_raw_buffer_store: 4233 case Intrinsic::amdgcn_raw_buffer_store_format: 4234 case Intrinsic::amdgcn_raw_tbuffer_store: { 4235 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 4236 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4237 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4238 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4239 break; 4240 } 4241 case Intrinsic::amdgcn_struct_buffer_load: 4242 case Intrinsic::amdgcn_struct_tbuffer_load: { 4243 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 4244 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4245 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4246 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4247 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 4248 break; 4249 } 4250 case Intrinsic::amdgcn_struct_buffer_store: 4251 case Intrinsic::amdgcn_struct_tbuffer_store: { 4252 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 4253 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4254 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4255 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4256 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 4257 break; 4258 } 4259 case Intrinsic::amdgcn_init_exec_from_input: { 4260 unsigned Size = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 4261 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4262 break; 4263 } 4264 case Intrinsic::amdgcn_ds_gws_init: 4265 case Intrinsic::amdgcn_ds_gws_barrier: 4266 case Intrinsic::amdgcn_ds_gws_sema_br: { 4267 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4268 4269 // This must be an SGPR, but accept a VGPR. 4270 unsigned Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, 4271 AMDGPU::SGPRRegBankID); 4272 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, 32); 4273 break; 4274 } 4275 case Intrinsic::amdgcn_ds_gws_sema_v: 4276 case Intrinsic::amdgcn_ds_gws_sema_p: 4277 case Intrinsic::amdgcn_ds_gws_sema_release_all: { 4278 // This must be an SGPR, but accept a VGPR. 4279 unsigned Bank = getRegBankID(MI.getOperand(1).getReg(), MRI, 4280 AMDGPU::SGPRRegBankID); 4281 OpdsMapping[1] = AMDGPU::getValueMapping(Bank, 32); 4282 break; 4283 } 4284 default: 4285 return getInvalidInstructionMapping(); 4286 } 4287 break; 4288 } 4289 case AMDGPU::G_SELECT: { 4290 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4291 unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, 4292 AMDGPU::SGPRRegBankID); 4293 unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, 4294 AMDGPU::SGPRRegBankID); 4295 bool SGPRSrcs = Op2Bank == AMDGPU::SGPRRegBankID && 4296 Op3Bank == AMDGPU::SGPRRegBankID; 4297 4298 unsigned CondBankDefault = SGPRSrcs ? 4299 AMDGPU::SGPRRegBankID : AMDGPU::VCCRegBankID; 4300 unsigned CondBank = getRegBankID(MI.getOperand(1).getReg(), MRI, 4301 CondBankDefault); 4302 if (CondBank == AMDGPU::SGPRRegBankID) 4303 CondBank = SGPRSrcs ? AMDGPU::SGPRRegBankID : AMDGPU::VCCRegBankID; 4304 else if (CondBank == AMDGPU::VGPRRegBankID) 4305 CondBank = AMDGPU::VCCRegBankID; 4306 4307 unsigned Bank = SGPRSrcs && CondBank == AMDGPU::SGPRRegBankID ? 4308 AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID; 4309 4310 assert(CondBank == AMDGPU::VCCRegBankID || CondBank == AMDGPU::SGPRRegBankID); 4311 4312 // TODO: Should report 32-bit for scalar condition type. 4313 if (Size == 64) { 4314 OpdsMapping[0] = AMDGPU::getValueMappingSGPR64Only(Bank, Size); 4315 OpdsMapping[1] = AMDGPU::getValueMapping(CondBank, 1); 4316 OpdsMapping[2] = AMDGPU::getValueMappingSGPR64Only(Bank, Size); 4317 OpdsMapping[3] = AMDGPU::getValueMappingSGPR64Only(Bank, Size); 4318 } else { 4319 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, Size); 4320 OpdsMapping[1] = AMDGPU::getValueMapping(CondBank, 1); 4321 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, Size); 4322 OpdsMapping[3] = AMDGPU::getValueMapping(Bank, Size); 4323 } 4324 4325 break; 4326 } 4327 4328 case AMDGPU::G_LOAD: 4329 case AMDGPU::G_ZEXTLOAD: 4330 case AMDGPU::G_SEXTLOAD: 4331 return getInstrMappingForLoad(MI); 4332 4333 case AMDGPU::G_ATOMICRMW_XCHG: 4334 case AMDGPU::G_ATOMICRMW_ADD: 4335 case AMDGPU::G_ATOMICRMW_SUB: 4336 case AMDGPU::G_ATOMICRMW_AND: 4337 case AMDGPU::G_ATOMICRMW_OR: 4338 case AMDGPU::G_ATOMICRMW_XOR: 4339 case AMDGPU::G_ATOMICRMW_MAX: 4340 case AMDGPU::G_ATOMICRMW_MIN: 4341 case AMDGPU::G_ATOMICRMW_UMAX: 4342 case AMDGPU::G_ATOMICRMW_UMIN: 4343 case AMDGPU::G_ATOMICRMW_FADD: 4344 case AMDGPU::G_AMDGPU_ATOMIC_CMPXCHG: 4345 case AMDGPU::G_AMDGPU_ATOMIC_INC: 4346 case AMDGPU::G_AMDGPU_ATOMIC_DEC: 4347 case AMDGPU::G_AMDGPU_ATOMIC_FMIN: 4348 case AMDGPU::G_AMDGPU_ATOMIC_FMAX: { 4349 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 4350 OpdsMapping[1] = getValueMappingForPtr(MRI, MI.getOperand(1).getReg()); 4351 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4352 break; 4353 } 4354 case AMDGPU::G_ATOMIC_CMPXCHG: { 4355 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 4356 OpdsMapping[1] = getValueMappingForPtr(MRI, MI.getOperand(1).getReg()); 4357 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4358 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4359 break; 4360 } 4361 case AMDGPU::G_BRCOND: { 4362 unsigned Bank = getRegBankID(MI.getOperand(0).getReg(), MRI, 4363 AMDGPU::SGPRRegBankID); 4364 assert(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 1); 4365 if (Bank != AMDGPU::SGPRRegBankID) 4366 Bank = AMDGPU::VCCRegBankID; 4367 4368 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, 1); 4369 break; 4370 } 4371 } 4372 4373 return getInstructionMapping(/*ID*/1, /*Cost*/1, 4374 getOperandsMapping(OpdsMapping), 4375 MI.getNumOperands()); 4376 } 4377