1 //===- AMDGPURegisterBankInfo.cpp -------------------------------*- C++ -*-==// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements the targeting of the RegisterBankInfo class for 10 /// AMDGPU. 11 /// 12 /// \par 13 /// 14 /// AMDGPU has unique register bank constraints that require special high level 15 /// strategies to deal with. There are two main true physical register banks 16 /// VGPR (vector), and SGPR (scalar). Additionally the VCC register bank is a 17 /// sort of pseudo-register bank needed to represent SGPRs used in a vector 18 /// boolean context. There is also the AGPR bank, which is a special purpose 19 /// physical register bank present on some subtargets. 20 /// 21 /// Copying from VGPR to SGPR is generally illegal, unless the value is known to 22 /// be uniform. It is generally not valid to legalize operands by inserting 23 /// copies as on other targets. Operations which require uniform, SGPR operands 24 /// generally require scalarization by repeatedly executing the instruction, 25 /// activating each set of lanes using a unique set of input values. This is 26 /// referred to as a waterfall loop. 27 /// 28 /// \par Booleans 29 /// 30 /// Booleans (s1 values) requires special consideration. A vector compare result 31 /// is naturally a bitmask with one bit per lane, in a 32 or 64-bit 32 /// register. These are represented with the VCC bank. During selection, we need 33 /// to be able to unambiguously go back from a register class to a register 34 /// bank. To distinguish whether an SGPR should use the SGPR or VCC register 35 /// bank, we need to know the use context type. An SGPR s1 value always means a 36 /// VCC bank value, otherwise it will be the SGPR bank. A scalar compare sets 37 /// SCC, which is a 1-bit unaddressable register. This will need to be copied to 38 /// a 32-bit virtual register. Taken together, this means we need to adjust the 39 /// type of boolean operations to be regbank legal. All SALU booleans need to be 40 /// widened to 32-bits, and all VALU booleans need to be s1 values. 41 /// 42 /// A noteworthy exception to the s1-means-vcc rule is for legalization artifact 43 /// casts. G_TRUNC s1 results, and G_SEXT/G_ZEXT/G_ANYEXT sources are never vcc 44 /// bank. A non-boolean source (such as a truncate from a 1-bit load from 45 /// memory) will require a copy to the VCC bank which will require clearing the 46 /// high bits and inserting a compare. 47 /// 48 /// \par Constant bus restriction 49 /// 50 /// VALU instructions have a limitation known as the constant bus 51 /// restriction. Most VALU instructions can use SGPR operands, but may read at 52 /// most 1 SGPR or constant literal value (this to 2 in gfx10 for most 53 /// instructions). This is one unique SGPR, so the same SGPR may be used for 54 /// multiple operands. From a register bank perspective, any combination of 55 /// operands should be legal as an SGPR, but this is contextually dependent on 56 /// the SGPR operands all being the same register. There is therefore optimal to 57 /// choose the SGPR with the most uses to minimize the number of copies. 58 /// 59 /// We avoid trying to solve this problem in RegBankSelect. Any VALU G_* 60 /// operation should have its source operands all mapped to VGPRs (except for 61 /// VCC), inserting copies from any SGPR operands. This the most trival legal 62 /// mapping. Anything beyond the simplest 1:1 instruction selection would be too 63 /// complicated to solve here. Every optimization pattern or instruction 64 /// selected to multiple outputs would have to enforce this rule, and there 65 /// would be additional complexity in tracking this rule for every G_* 66 /// operation. By forcing all inputs to VGPRs, it also simplifies the task of 67 /// picking the optimal operand combination from a post-isel optimization pass. 68 /// 69 //===----------------------------------------------------------------------===// 70 71 #include "AMDGPURegisterBankInfo.h" 72 73 #include "AMDGPUGlobalISelUtils.h" 74 #include "AMDGPUInstrInfo.h" 75 #include "AMDGPUSubtarget.h" 76 #include "MCTargetDesc/AMDGPUMCTargetDesc.h" 77 #include "SIMachineFunctionInfo.h" 78 #include "SIRegisterInfo.h" 79 #include "llvm/CodeGen/GlobalISel/LegalizationArtifactCombiner.h" 80 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 81 #include "llvm/CodeGen/GlobalISel/MIPatternMatch.h" 82 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 83 #include "llvm/CodeGen/GlobalISel/RegisterBank.h" 84 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h" 85 #include "llvm/CodeGen/TargetRegisterInfo.h" 86 #include "llvm/CodeGen/TargetSubtargetInfo.h" 87 #include "llvm/IR/Constants.h" 88 89 #define GET_TARGET_REGBANK_IMPL 90 #include "AMDGPUGenRegisterBank.inc" 91 92 // This file will be TableGen'ed at some point. 93 #include "AMDGPUGenRegisterBankInfo.def" 94 95 using namespace llvm; 96 using namespace MIPatternMatch; 97 98 namespace { 99 100 // Observer to apply a register bank to new registers created by LegalizerHelper. 101 class ApplyRegBankMapping final : public GISelChangeObserver { 102 private: 103 const AMDGPURegisterBankInfo &RBI; 104 MachineRegisterInfo &MRI; 105 const RegisterBank *NewBank; 106 SmallVector<MachineInstr *, 4> NewInsts; 107 108 public: 109 ApplyRegBankMapping(const AMDGPURegisterBankInfo &RBI_, 110 MachineRegisterInfo &MRI_, const RegisterBank *RB) 111 : RBI(RBI_), MRI(MRI_), NewBank(RB) {} 112 113 ~ApplyRegBankMapping() { 114 for (MachineInstr *MI : NewInsts) 115 applyBank(*MI); 116 } 117 118 /// Set any registers that don't have a set register class or bank to SALU. 119 void applyBank(MachineInstr &MI) { 120 const unsigned Opc = MI.getOpcode(); 121 if (Opc == AMDGPU::G_ANYEXT || Opc == AMDGPU::G_ZEXT || 122 Opc == AMDGPU::G_SEXT) { 123 // LegalizerHelper wants to use the basic legalization artifacts when 124 // widening etc. We don't handle selection with vcc in artifact sources, 125 // so we need to use a sslect instead to handle these properly. 126 Register DstReg = MI.getOperand(0).getReg(); 127 Register SrcReg = MI.getOperand(1).getReg(); 128 const RegisterBank *SrcBank = RBI.getRegBank(SrcReg, MRI, *RBI.TRI); 129 if (SrcBank == &AMDGPU::VCCRegBank) { 130 const LLT S32 = LLT::scalar(32); 131 assert(MRI.getType(SrcReg) == LLT::scalar(1)); 132 assert(MRI.getType(DstReg) == S32); 133 assert(NewBank == &AMDGPU::VGPRRegBank); 134 135 // Replace the extension with a select, which really uses the boolean 136 // source. 137 MachineIRBuilder B(MI); 138 auto True = B.buildConstant(S32, Opc == AMDGPU::G_SEXT ? -1 : 1); 139 auto False = B.buildConstant(S32, 0); 140 B.buildSelect(DstReg, SrcReg, True, False); 141 MRI.setRegBank(True.getReg(0), *NewBank); 142 MRI.setRegBank(False.getReg(0), *NewBank); 143 MI.eraseFromParent(); 144 } 145 146 assert(!MRI.getRegClassOrRegBank(DstReg)); 147 MRI.setRegBank(DstReg, *NewBank); 148 return; 149 } 150 151 #ifndef NDEBUG 152 if (Opc == AMDGPU::G_TRUNC) { 153 Register DstReg = MI.getOperand(0).getReg(); 154 const RegisterBank *DstBank = RBI.getRegBank(DstReg, MRI, *RBI.TRI); 155 assert(DstBank != &AMDGPU::VCCRegBank); 156 } 157 #endif 158 159 for (MachineOperand &Op : MI.operands()) { 160 if (!Op.isReg()) 161 continue; 162 163 // We may see physical registers if building a real MI 164 Register Reg = Op.getReg(); 165 if (Reg.isPhysical() || MRI.getRegClassOrRegBank(Reg)) 166 continue; 167 168 const RegisterBank *RB = NewBank; 169 if (MRI.getType(Reg) == LLT::scalar(1)) { 170 assert(NewBank == &AMDGPU::VGPRRegBank && 171 "s1 operands should only be used for vector bools"); 172 assert((MI.getOpcode() != AMDGPU::G_TRUNC && 173 MI.getOpcode() != AMDGPU::G_ANYEXT) && 174 "not expecting legalization artifacts here"); 175 RB = &AMDGPU::VCCRegBank; 176 } 177 178 MRI.setRegBank(Reg, *RB); 179 } 180 } 181 182 void erasingInstr(MachineInstr &MI) override {} 183 184 void createdInstr(MachineInstr &MI) override { 185 // At this point, the instruction was just inserted and has no operands. 186 NewInsts.push_back(&MI); 187 } 188 189 void changingInstr(MachineInstr &MI) override {} 190 void changedInstr(MachineInstr &MI) override {} 191 }; 192 193 } 194 AMDGPURegisterBankInfo::AMDGPURegisterBankInfo(const GCNSubtarget &ST) 195 : AMDGPUGenRegisterBankInfo(), 196 Subtarget(ST), 197 TRI(Subtarget.getRegisterInfo()), 198 TII(Subtarget.getInstrInfo()) { 199 200 // HACK: Until this is fully tablegen'd. 201 static llvm::once_flag InitializeRegisterBankFlag; 202 203 static auto InitializeRegisterBankOnce = [this]() { 204 assert(&getRegBank(AMDGPU::SGPRRegBankID) == &AMDGPU::SGPRRegBank && 205 &getRegBank(AMDGPU::VGPRRegBankID) == &AMDGPU::VGPRRegBank && 206 &getRegBank(AMDGPU::AGPRRegBankID) == &AMDGPU::AGPRRegBank); 207 (void)this; 208 }; 209 210 llvm::call_once(InitializeRegisterBankFlag, InitializeRegisterBankOnce); 211 } 212 213 static bool isVectorRegisterBank(const RegisterBank &Bank) { 214 unsigned BankID = Bank.getID(); 215 return BankID == AMDGPU::VGPRRegBankID || BankID == AMDGPU::AGPRRegBankID; 216 } 217 218 unsigned AMDGPURegisterBankInfo::copyCost(const RegisterBank &Dst, 219 const RegisterBank &Src, 220 unsigned Size) const { 221 // TODO: Should there be a UniformVGPRRegBank which can use readfirstlane? 222 if (Dst.getID() == AMDGPU::SGPRRegBankID && 223 (isVectorRegisterBank(Src) || Src.getID() == AMDGPU::VCCRegBankID)) { 224 return std::numeric_limits<unsigned>::max(); 225 } 226 227 // Bool values are tricky, because the meaning is based on context. The SCC 228 // and VCC banks are for the natural scalar and vector conditions produced by 229 // a compare. 230 // 231 // Legalization doesn't know about the necessary context, so an s1 use may 232 // have been a truncate from an arbitrary value, in which case a copy (lowered 233 // as a compare with 0) needs to be inserted. 234 if (Size == 1 && 235 (Dst.getID() == AMDGPU::SGPRRegBankID) && 236 (isVectorRegisterBank(Src) || 237 Src.getID() == AMDGPU::SGPRRegBankID || 238 Src.getID() == AMDGPU::VCCRegBankID)) 239 return std::numeric_limits<unsigned>::max(); 240 241 // There is no direct copy between AGPRs. 242 if (Dst.getID() == AMDGPU::AGPRRegBankID && 243 Src.getID() == AMDGPU::AGPRRegBankID) 244 return 4; 245 246 return RegisterBankInfo::copyCost(Dst, Src, Size); 247 } 248 249 unsigned AMDGPURegisterBankInfo::getBreakDownCost( 250 const ValueMapping &ValMapping, 251 const RegisterBank *CurBank) const { 252 // Check if this is a breakdown for G_LOAD to move the pointer from SGPR to 253 // VGPR. 254 // FIXME: Is there a better way to do this? 255 if (ValMapping.NumBreakDowns >= 2 || ValMapping.BreakDown[0].Length >= 64) 256 return 10; // This is expensive. 257 258 assert(ValMapping.NumBreakDowns == 2 && 259 ValMapping.BreakDown[0].Length == 32 && 260 ValMapping.BreakDown[0].StartIdx == 0 && 261 ValMapping.BreakDown[1].Length == 32 && 262 ValMapping.BreakDown[1].StartIdx == 32 && 263 ValMapping.BreakDown[0].RegBank == ValMapping.BreakDown[1].RegBank); 264 265 // 32-bit extract of a 64-bit value is just access of a subregister, so free. 266 // TODO: Cost of 0 hits assert, though it's not clear it's what we really 267 // want. 268 269 // TODO: 32-bit insert to a 64-bit SGPR may incur a non-free copy due to SGPR 270 // alignment restrictions, but this probably isn't important. 271 return 1; 272 } 273 274 const RegisterBank & 275 AMDGPURegisterBankInfo::getRegBankFromRegClass(const TargetRegisterClass &RC, 276 LLT Ty) const { 277 if (&RC == &AMDGPU::SReg_1RegClass) 278 return AMDGPU::VCCRegBank; 279 280 // We promote real scalar booleans to SReg_32. Any SGPR using s1 is really a 281 // VCC-like use. 282 if (TRI->isSGPRClass(&RC)) { 283 // FIXME: This probably came from a copy from a physical register, which 284 // should be inferrrable from the copied to-type. We don't have many boolean 285 // physical register constraints so just assume a normal SGPR for now. 286 if (!Ty.isValid()) 287 return AMDGPU::SGPRRegBank; 288 289 return Ty == LLT::scalar(1) ? AMDGPU::VCCRegBank : AMDGPU::SGPRRegBank; 290 } 291 292 return TRI->isAGPRClass(&RC) ? AMDGPU::AGPRRegBank : AMDGPU::VGPRRegBank; 293 } 294 295 template <unsigned NumOps> 296 RegisterBankInfo::InstructionMappings 297 AMDGPURegisterBankInfo::addMappingFromTable( 298 const MachineInstr &MI, const MachineRegisterInfo &MRI, 299 const std::array<unsigned, NumOps> RegSrcOpIdx, 300 ArrayRef<OpRegBankEntry<NumOps>> Table) const { 301 302 InstructionMappings AltMappings; 303 304 SmallVector<const ValueMapping *, 10> Operands(MI.getNumOperands()); 305 306 unsigned Sizes[NumOps]; 307 for (unsigned I = 0; I < NumOps; ++I) { 308 Register Reg = MI.getOperand(RegSrcOpIdx[I]).getReg(); 309 Sizes[I] = getSizeInBits(Reg, MRI, *TRI); 310 } 311 312 for (unsigned I = 0, E = MI.getNumExplicitDefs(); I != E; ++I) { 313 unsigned SizeI = getSizeInBits(MI.getOperand(I).getReg(), MRI, *TRI); 314 Operands[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SizeI); 315 } 316 317 // getInstrMapping's default mapping uses ID 1, so start at 2. 318 unsigned MappingID = 2; 319 for (const auto &Entry : Table) { 320 for (unsigned I = 0; I < NumOps; ++I) { 321 int OpIdx = RegSrcOpIdx[I]; 322 Operands[OpIdx] = AMDGPU::getValueMapping(Entry.RegBanks[I], Sizes[I]); 323 } 324 325 AltMappings.push_back(&getInstructionMapping(MappingID++, Entry.Cost, 326 getOperandsMapping(Operands), 327 Operands.size())); 328 } 329 330 return AltMappings; 331 } 332 333 RegisterBankInfo::InstructionMappings 334 AMDGPURegisterBankInfo::getInstrAlternativeMappingsIntrinsic( 335 const MachineInstr &MI, const MachineRegisterInfo &MRI) const { 336 switch (MI.getIntrinsicID()) { 337 case Intrinsic::amdgcn_readlane: { 338 static const OpRegBankEntry<3> Table[2] = { 339 // Perfectly legal. 340 { { AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID }, 1 }, 341 342 // Need a readfirstlane for the index. 343 { { AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 2 } 344 }; 345 346 const std::array<unsigned, 3> RegSrcOpIdx = { { 0, 2, 3 } }; 347 return addMappingFromTable<3>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 348 } 349 case Intrinsic::amdgcn_writelane: { 350 static const OpRegBankEntry<4> Table[4] = { 351 // Perfectly legal. 352 { { AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID }, 1 }, 353 354 // Need readfirstlane of first op 355 { { AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID }, 2 }, 356 357 // Need readfirstlane of second op 358 { { AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 2 }, 359 360 // Need readfirstlane of both ops 361 { { AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 3 } 362 }; 363 364 // rsrc, voffset, offset 365 const std::array<unsigned, 4> RegSrcOpIdx = { { 0, 2, 3, 4 } }; 366 return addMappingFromTable<4>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 367 } 368 default: 369 return RegisterBankInfo::getInstrAlternativeMappings(MI); 370 } 371 } 372 373 RegisterBankInfo::InstructionMappings 374 AMDGPURegisterBankInfo::getInstrAlternativeMappingsIntrinsicWSideEffects( 375 const MachineInstr &MI, const MachineRegisterInfo &MRI) const { 376 377 switch (MI.getIntrinsicID()) { 378 case Intrinsic::amdgcn_s_buffer_load: { 379 static const OpRegBankEntry<2> Table[4] = { 380 // Perfectly legal. 381 { { AMDGPU::SGPRRegBankID, AMDGPU::SGPRRegBankID }, 1 }, 382 383 // Only need 1 register in loop 384 { { AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID }, 300 }, 385 386 // Have to waterfall the resource. 387 { { AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID }, 1000 }, 388 389 // Have to waterfall the resource, and the offset. 390 { { AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 1500 } 391 }; 392 393 // rsrc, offset 394 const std::array<unsigned, 2> RegSrcOpIdx = { { 2, 3 } }; 395 return addMappingFromTable<2>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 396 } 397 case Intrinsic::amdgcn_ds_ordered_add: 398 case Intrinsic::amdgcn_ds_ordered_swap: { 399 // VGPR = M0, VGPR 400 static const OpRegBankEntry<3> Table[2] = { 401 // Perfectly legal. 402 { { AMDGPU::VGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::VGPRRegBankID }, 1 }, 403 404 // Need a readfirstlane for m0 405 { { AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 2 } 406 }; 407 408 const std::array<unsigned, 3> RegSrcOpIdx = { { 0, 2, 3 } }; 409 return addMappingFromTable<3>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 410 } 411 case Intrinsic::amdgcn_s_sendmsg: 412 case Intrinsic::amdgcn_s_sendmsghalt: { 413 // FIXME: Should have no register for immediate 414 static const OpRegBankEntry<1> Table[2] = { 415 // Perfectly legal. 416 { { AMDGPU::SGPRRegBankID }, 1 }, 417 418 // Need readlane 419 { { AMDGPU::VGPRRegBankID }, 3 } 420 }; 421 422 const std::array<unsigned, 1> RegSrcOpIdx = { { 2 } }; 423 return addMappingFromTable<1>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 424 } 425 default: 426 return RegisterBankInfo::getInstrAlternativeMappings(MI); 427 } 428 } 429 430 static bool memOpHasNoClobbered(const MachineMemOperand *MMO) { 431 const Instruction *I = dyn_cast_or_null<Instruction>(MMO->getValue()); 432 return I && I->getMetadata("amdgpu.noclobber"); 433 } 434 435 // FIXME: Returns uniform if there's no source value information. This is 436 // probably wrong. 437 static bool isScalarLoadLegal(const MachineInstr &MI) { 438 if (!MI.hasOneMemOperand()) 439 return false; 440 441 const MachineMemOperand *MMO = *MI.memoperands_begin(); 442 const unsigned AS = MMO->getAddrSpace(); 443 const bool IsConst = AS == AMDGPUAS::CONSTANT_ADDRESS || 444 AS == AMDGPUAS::CONSTANT_ADDRESS_32BIT; 445 446 // There are no extending SMRD/SMEM loads, and they require 4-byte alignment. 447 return MMO->getSize() >= 4 && MMO->getAlign() >= Align(4) && 448 // Can't do a scalar atomic load. 449 !MMO->isAtomic() && 450 // Don't use scalar loads for volatile accesses to non-constant address 451 // spaces. 452 (IsConst || !MMO->isVolatile()) && 453 // Memory must be known constant, or not written before this load. 454 (IsConst || MMO->isInvariant() || memOpHasNoClobbered(MMO)) && 455 AMDGPUInstrInfo::isUniformMMO(MMO); 456 } 457 458 RegisterBankInfo::InstructionMappings 459 AMDGPURegisterBankInfo::getInstrAlternativeMappings( 460 const MachineInstr &MI) const { 461 462 const MachineFunction &MF = *MI.getParent()->getParent(); 463 const MachineRegisterInfo &MRI = MF.getRegInfo(); 464 465 466 InstructionMappings AltMappings; 467 switch (MI.getOpcode()) { 468 case TargetOpcode::G_CONSTANT: { 469 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 470 if (Size == 1) { 471 static const OpRegBankEntry<1> Table[3] = { 472 { { AMDGPU::VGPRRegBankID }, 1 }, 473 { { AMDGPU::SGPRRegBankID }, 1 }, 474 { { AMDGPU::VCCRegBankID }, 1 } 475 }; 476 477 return addMappingFromTable<1>(MI, MRI, {{ 0 }}, Table); 478 } 479 480 LLVM_FALLTHROUGH; 481 } 482 case TargetOpcode::G_FCONSTANT: 483 case TargetOpcode::G_FRAME_INDEX: 484 case TargetOpcode::G_GLOBAL_VALUE: { 485 static const OpRegBankEntry<1> Table[2] = { 486 { { AMDGPU::VGPRRegBankID }, 1 }, 487 { { AMDGPU::SGPRRegBankID }, 1 } 488 }; 489 490 return addMappingFromTable<1>(MI, MRI, {{ 0 }}, Table); 491 } 492 case TargetOpcode::G_AND: 493 case TargetOpcode::G_OR: 494 case TargetOpcode::G_XOR: { 495 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 496 497 if (Size == 1) { 498 // s_{and|or|xor}_b32 set scc when the result of the 32-bit op is not 0. 499 const InstructionMapping &SCCMapping = getInstructionMapping( 500 1, 1, getOperandsMapping( 501 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32), 502 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32), 503 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32)}), 504 3); // Num Operands 505 AltMappings.push_back(&SCCMapping); 506 507 const InstructionMapping &VCCMapping0 = getInstructionMapping( 508 2, 1, getOperandsMapping( 509 {AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Size), 510 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Size), 511 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Size)}), 512 3); // Num Operands 513 AltMappings.push_back(&VCCMapping0); 514 return AltMappings; 515 } 516 517 if (Size != 64) 518 break; 519 520 const InstructionMapping &SSMapping = getInstructionMapping( 521 1, 1, getOperandsMapping( 522 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 523 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 524 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}), 525 3); // Num Operands 526 AltMappings.push_back(&SSMapping); 527 528 const InstructionMapping &VVMapping = getInstructionMapping( 529 2, 2, getOperandsMapping( 530 {AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size), 531 AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size), 532 AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size)}), 533 3); // Num Operands 534 AltMappings.push_back(&VVMapping); 535 break; 536 } 537 case TargetOpcode::G_LOAD: 538 case TargetOpcode::G_ZEXTLOAD: 539 case TargetOpcode::G_SEXTLOAD: { 540 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 541 LLT PtrTy = MRI.getType(MI.getOperand(1).getReg()); 542 unsigned PtrSize = PtrTy.getSizeInBits(); 543 unsigned AS = PtrTy.getAddressSpace(); 544 545 if ((AS != AMDGPUAS::LOCAL_ADDRESS && AS != AMDGPUAS::REGION_ADDRESS && 546 AS != AMDGPUAS::PRIVATE_ADDRESS) && 547 isScalarLoadLegal(MI)) { 548 const InstructionMapping &SSMapping = getInstructionMapping( 549 1, 1, getOperandsMapping( 550 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 551 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize)}), 552 2); // Num Operands 553 AltMappings.push_back(&SSMapping); 554 } 555 556 const InstructionMapping &VVMapping = getInstructionMapping( 557 2, 1, 558 getOperandsMapping( 559 {AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 560 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize)}), 561 2); // Num Operands 562 AltMappings.push_back(&VVMapping); 563 564 // It may be possible to have a vgpr = load sgpr mapping here, because 565 // the mubuf instructions support this kind of load, but probably for only 566 // gfx7 and older. However, the addressing mode matching in the instruction 567 // selector should be able to do a better job of detecting and selecting 568 // these kinds of loads from the vgpr = load vgpr mapping. 569 570 return AltMappings; 571 572 } 573 case TargetOpcode::G_SELECT: { 574 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 575 const InstructionMapping &SSMapping = getInstructionMapping(1, 1, 576 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 577 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1), 578 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 579 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size)}), 580 4); // Num Operands 581 AltMappings.push_back(&SSMapping); 582 583 const InstructionMapping &VVMapping = getInstructionMapping(2, 1, 584 getOperandsMapping({AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size), 585 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), 586 AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size), 587 AMDGPU::getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size)}), 588 4); // Num Operands 589 AltMappings.push_back(&VVMapping); 590 591 return AltMappings; 592 } 593 case TargetOpcode::G_SMIN: 594 case TargetOpcode::G_SMAX: 595 case TargetOpcode::G_UMIN: 596 case TargetOpcode::G_UMAX: { 597 static const OpRegBankEntry<3> Table[2] = { 598 { { AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID, AMDGPU::VGPRRegBankID }, 1 }, 599 600 // Scalar requires cmp+select, and extends if 16-bit. 601 // FIXME: Should there be separate costs for 32 and 16-bit 602 { { AMDGPU::SGPRRegBankID, AMDGPU::SGPRRegBankID, AMDGPU::SGPRRegBankID }, 3 } 603 }; 604 605 const std::array<unsigned, 3> RegSrcOpIdx = { { 0, 1, 2 } }; 606 return addMappingFromTable<3>(MI, MRI, RegSrcOpIdx, makeArrayRef(Table)); 607 } 608 case TargetOpcode::G_UADDE: 609 case TargetOpcode::G_USUBE: 610 case TargetOpcode::G_SADDE: 611 case TargetOpcode::G_SSUBE: { 612 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 613 const InstructionMapping &SSMapping = getInstructionMapping(1, 1, 614 getOperandsMapping( 615 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 616 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1), 617 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 618 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size), 619 AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1)}), 620 5); // Num Operands 621 AltMappings.push_back(&SSMapping); 622 623 const InstructionMapping &VVMapping = getInstructionMapping(2, 1, 624 getOperandsMapping({AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 625 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), 626 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 627 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size), 628 AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1)}), 629 5); // Num Operands 630 AltMappings.push_back(&VVMapping); 631 return AltMappings; 632 } 633 case AMDGPU::G_BRCOND: { 634 assert(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 1); 635 636 // TODO: Change type to 32 for scalar 637 const InstructionMapping &SMapping = getInstructionMapping( 638 1, 1, getOperandsMapping( 639 {AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 1), nullptr}), 640 2); // Num Operands 641 AltMappings.push_back(&SMapping); 642 643 const InstructionMapping &VMapping = getInstructionMapping( 644 1, 1, getOperandsMapping( 645 {AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1), nullptr }), 646 2); // Num Operands 647 AltMappings.push_back(&VMapping); 648 return AltMappings; 649 } 650 case AMDGPU::G_INTRINSIC: 651 return getInstrAlternativeMappingsIntrinsic(MI, MRI); 652 case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: 653 return getInstrAlternativeMappingsIntrinsicWSideEffects(MI, MRI); 654 default: 655 break; 656 } 657 return RegisterBankInfo::getInstrAlternativeMappings(MI); 658 } 659 660 void AMDGPURegisterBankInfo::split64BitValueForMapping( 661 MachineIRBuilder &B, 662 SmallVector<Register, 2> &Regs, 663 LLT HalfTy, 664 Register Reg) const { 665 assert(HalfTy.getSizeInBits() == 32); 666 MachineRegisterInfo *MRI = B.getMRI(); 667 Register LoLHS = MRI->createGenericVirtualRegister(HalfTy); 668 Register HiLHS = MRI->createGenericVirtualRegister(HalfTy); 669 const RegisterBank *Bank = getRegBank(Reg, *MRI, *TRI); 670 MRI->setRegBank(LoLHS, *Bank); 671 MRI->setRegBank(HiLHS, *Bank); 672 673 Regs.push_back(LoLHS); 674 Regs.push_back(HiLHS); 675 676 B.buildInstr(AMDGPU::G_UNMERGE_VALUES) 677 .addDef(LoLHS) 678 .addDef(HiLHS) 679 .addUse(Reg); 680 } 681 682 /// Replace the current type each register in \p Regs has with \p NewTy 683 static void setRegsToType(MachineRegisterInfo &MRI, ArrayRef<Register> Regs, 684 LLT NewTy) { 685 for (Register Reg : Regs) { 686 assert(MRI.getType(Reg).getSizeInBits() == NewTy.getSizeInBits()); 687 MRI.setType(Reg, NewTy); 688 } 689 } 690 691 static LLT getHalfSizedType(LLT Ty) { 692 if (Ty.isVector()) { 693 assert(Ty.getNumElements() % 2 == 0); 694 return LLT::scalarOrVector(Ty.getNumElements() / 2, Ty.getElementType()); 695 } 696 697 assert(Ty.getSizeInBits() % 2 == 0); 698 return LLT::scalar(Ty.getSizeInBits() / 2); 699 } 700 701 /// Legalize instruction \p MI where operands in \p OpIndices must be SGPRs. If 702 /// any of the required SGPR operands are VGPRs, perform a waterfall loop to 703 /// execute the instruction for each unique combination of values in all lanes 704 /// in the wave. The block will be split such that rest of the instructions are 705 /// moved to a new block. 706 /// 707 /// Essentially performs this loop: 708 // 709 /// Save Execution Mask 710 /// For (Lane : Wavefront) { 711 /// Enable Lane, Disable all other lanes 712 /// SGPR = read SGPR value for current lane from VGPR 713 /// VGPRResult[Lane] = use_op SGPR 714 /// } 715 /// Restore Execution Mask 716 /// 717 /// There is additional complexity to try for compare values to identify the 718 /// unique values used. 719 bool AMDGPURegisterBankInfo::executeInWaterfallLoop( 720 MachineIRBuilder &B, 721 iterator_range<MachineBasicBlock::iterator> Range, 722 SmallSet<Register, 4> &SGPROperandRegs, 723 MachineRegisterInfo &MRI) const { 724 SmallVector<Register, 4> ResultRegs; 725 SmallVector<Register, 4> InitResultRegs; 726 SmallVector<Register, 4> PhiRegs; 727 728 // Track use registers which have already been expanded with a readfirstlane 729 // sequence. This may have multiple uses if moving a sequence. 730 DenseMap<Register, Register> WaterfalledRegMap; 731 732 MachineBasicBlock &MBB = B.getMBB(); 733 MachineFunction *MF = &B.getMF(); 734 735 const TargetRegisterClass *WaveRC = TRI->getWaveMaskRegClass(); 736 const unsigned WaveAndOpc = Subtarget.isWave32() ? 737 AMDGPU::S_AND_B32 : AMDGPU::S_AND_B64; 738 const unsigned MovTermOpc = Subtarget.isWave32() ? 739 AMDGPU::S_MOV_B32_term : AMDGPU::S_MOV_B64_term; 740 const unsigned XorTermOpc = Subtarget.isWave32() ? 741 AMDGPU::S_XOR_B32_term : AMDGPU::S_XOR_B64_term; 742 const unsigned AndSaveExecOpc = Subtarget.isWave32() ? 743 AMDGPU::S_AND_SAVEEXEC_B32 : AMDGPU::S_AND_SAVEEXEC_B64; 744 const unsigned ExecReg = Subtarget.isWave32() ? 745 AMDGPU::EXEC_LO : AMDGPU::EXEC; 746 747 #ifndef NDEBUG 748 const int OrigRangeSize = std::distance(Range.begin(), Range.end()); 749 #endif 750 751 for (MachineInstr &MI : Range) { 752 for (MachineOperand &Def : MI.defs()) { 753 LLT ResTy = MRI.getType(Def.getReg()); 754 const RegisterBank *DefBank = getRegBank(Def.getReg(), MRI, *TRI); 755 ResultRegs.push_back(Def.getReg()); 756 Register InitReg = B.buildUndef(ResTy).getReg(0); 757 Register PhiReg = MRI.createGenericVirtualRegister(ResTy); 758 InitResultRegs.push_back(InitReg); 759 PhiRegs.push_back(PhiReg); 760 MRI.setRegBank(PhiReg, *DefBank); 761 MRI.setRegBank(InitReg, *DefBank); 762 } 763 } 764 765 Register SaveExecReg = MRI.createVirtualRegister(WaveRC); 766 Register InitSaveExecReg = MRI.createVirtualRegister(WaveRC); 767 768 // Don't bother using generic instructions/registers for the exec mask. 769 B.buildInstr(TargetOpcode::IMPLICIT_DEF) 770 .addDef(InitSaveExecReg); 771 772 Register PhiExec = MRI.createVirtualRegister(WaveRC); 773 Register NewExec = MRI.createVirtualRegister(WaveRC); 774 775 // To insert the loop we need to split the block. Move everything before this 776 // point to a new block, and insert a new empty block before this instruction. 777 MachineBasicBlock *LoopBB = MF->CreateMachineBasicBlock(); 778 MachineBasicBlock *RemainderBB = MF->CreateMachineBasicBlock(); 779 MachineBasicBlock *RestoreExecBB = MF->CreateMachineBasicBlock(); 780 MachineFunction::iterator MBBI(MBB); 781 ++MBBI; 782 MF->insert(MBBI, LoopBB); 783 MF->insert(MBBI, RestoreExecBB); 784 MF->insert(MBBI, RemainderBB); 785 786 LoopBB->addSuccessor(RestoreExecBB); 787 LoopBB->addSuccessor(LoopBB); 788 789 // Move the rest of the block into a new block. 790 RemainderBB->transferSuccessorsAndUpdatePHIs(&MBB); 791 RemainderBB->splice(RemainderBB->begin(), &MBB, Range.end(), MBB.end()); 792 793 MBB.addSuccessor(LoopBB); 794 RestoreExecBB->addSuccessor(RemainderBB); 795 796 B.setInsertPt(*LoopBB, LoopBB->end()); 797 798 B.buildInstr(TargetOpcode::PHI) 799 .addDef(PhiExec) 800 .addReg(InitSaveExecReg) 801 .addMBB(&MBB) 802 .addReg(NewExec) 803 .addMBB(LoopBB); 804 805 for (auto Result : zip(InitResultRegs, ResultRegs, PhiRegs)) { 806 B.buildInstr(TargetOpcode::G_PHI) 807 .addDef(std::get<2>(Result)) 808 .addReg(std::get<0>(Result)) // Initial value / implicit_def 809 .addMBB(&MBB) 810 .addReg(std::get<1>(Result)) // Mid-loop value. 811 .addMBB(LoopBB); 812 } 813 814 const DebugLoc &DL = B.getDL(); 815 816 MachineInstr &FirstInst = *Range.begin(); 817 818 // Move the instruction into the loop. Note we moved everything after 819 // Range.end() already into a new block, so Range.end() is no longer valid. 820 LoopBB->splice(LoopBB->end(), &MBB, Range.begin(), MBB.end()); 821 822 // Figure out the iterator range after splicing the instructions. 823 MachineBasicBlock::iterator NewBegin = FirstInst.getIterator(); 824 auto NewEnd = LoopBB->end(); 825 826 MachineBasicBlock::iterator I = Range.begin(); 827 B.setInsertPt(*LoopBB, I); 828 829 Register CondReg; 830 831 assert(std::distance(NewBegin, NewEnd) == OrigRangeSize); 832 833 for (MachineInstr &MI : make_range(NewBegin, NewEnd)) { 834 for (MachineOperand &Op : MI.uses()) { 835 if (!Op.isReg() || Op.isDef()) 836 continue; 837 838 Register OldReg = Op.getReg(); 839 if (!SGPROperandRegs.count(OldReg)) 840 continue; 841 842 // See if we already processed this register in another instruction in the 843 // sequence. 844 auto OldVal = WaterfalledRegMap.find(OldReg); 845 if (OldVal != WaterfalledRegMap.end()) { 846 Op.setReg(OldVal->second); 847 continue; 848 } 849 850 LLT OpTy = MRI.getType(Op.getReg()); 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(Op.getReg(), 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(Op.getReg()); 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(Op.getReg()); 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, Op.getReg()); 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::VGPRRegBankID) 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::VGPRRegBank) 1087 return; 1088 1089 MachineIRBuilder B(MI); 1090 Register SGPR = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass); 1091 B.buildInstr(AMDGPU::V_READFIRSTLANE_B32) 1092 .addDef(SGPR) 1093 .addReg(Reg); 1094 1095 MRI.setType(SGPR, MRI.getType(Reg)); 1096 1097 const TargetRegisterClass *Constrained = 1098 constrainGenericRegister(Reg, AMDGPU::VGPR_32RegClass, MRI); 1099 (void)Constrained; 1100 assert(Constrained && "Failed to constrain readfirstlane src reg"); 1101 1102 MI.getOperand(OpIdx).setReg(SGPR); 1103 } 1104 1105 /// Split \p Ty into 2 pieces. The first will have \p FirstSize bits, and the 1106 /// rest will be in the remainder. 1107 static std::pair<LLT, LLT> splitUnequalType(LLT Ty, unsigned FirstSize) { 1108 unsigned TotalSize = Ty.getSizeInBits(); 1109 if (!Ty.isVector()) 1110 return {LLT::scalar(FirstSize), LLT::scalar(TotalSize - FirstSize)}; 1111 1112 LLT EltTy = Ty.getElementType(); 1113 unsigned EltSize = EltTy.getSizeInBits(); 1114 assert(FirstSize % EltSize == 0); 1115 1116 unsigned FirstPartNumElts = FirstSize / EltSize; 1117 unsigned RemainderElts = (TotalSize - FirstSize) / EltSize; 1118 1119 return {LLT::scalarOrVector(FirstPartNumElts, EltTy), 1120 LLT::scalarOrVector(RemainderElts, EltTy)}; 1121 } 1122 1123 static LLT widen96To128(LLT Ty) { 1124 if (!Ty.isVector()) 1125 return LLT::scalar(128); 1126 1127 LLT EltTy = Ty.getElementType(); 1128 assert(128 % EltTy.getSizeInBits() == 0); 1129 return LLT::vector(128 / EltTy.getSizeInBits(), EltTy); 1130 } 1131 1132 bool AMDGPURegisterBankInfo::applyMappingLoad(MachineInstr &MI, 1133 const AMDGPURegisterBankInfo::OperandsMapper &OpdMapper, 1134 MachineRegisterInfo &MRI) const { 1135 Register DstReg = MI.getOperand(0).getReg(); 1136 const LLT LoadTy = MRI.getType(DstReg); 1137 unsigned LoadSize = LoadTy.getSizeInBits(); 1138 const unsigned MaxNonSmrdLoadSize = 128; 1139 1140 const RegisterBank *PtrBank = 1141 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 1142 if (PtrBank == &AMDGPU::SGPRRegBank) { 1143 // If the pointer is an SGPR, we ordinarily have nothing to do. 1144 if (LoadSize != 96) 1145 return false; 1146 1147 MachineMemOperand *MMO = *MI.memoperands_begin(); 1148 Register PtrReg = MI.getOperand(1).getReg(); 1149 // 96-bit loads are only available for vector loads. We need to split this 1150 // into a 64-bit part, and 32 (unless we can widen to a 128-bit load). 1151 1152 MachineIRBuilder B(MI); 1153 ApplyRegBankMapping O(*this, MRI, &AMDGPU::SGPRRegBank); 1154 GISelObserverWrapper Observer(&O); 1155 B.setChangeObserver(Observer); 1156 1157 if (MMO->getAlign() < Align(16)) { 1158 LLT Part64, Part32; 1159 std::tie(Part64, Part32) = splitUnequalType(LoadTy, 64); 1160 auto Load0 = B.buildLoadFromOffset(Part64, PtrReg, *MMO, 0); 1161 auto Load1 = B.buildLoadFromOffset(Part32, PtrReg, *MMO, 8); 1162 1163 auto Undef = B.buildUndef(LoadTy); 1164 auto Ins0 = B.buildInsert(LoadTy, Undef, Load0, 0); 1165 B.buildInsert(MI.getOperand(0), Ins0, Load1, 64); 1166 } else { 1167 LLT WiderTy = widen96To128(LoadTy); 1168 auto WideLoad = B.buildLoadFromOffset(WiderTy, PtrReg, *MMO, 0); 1169 B.buildExtract(MI.getOperand(0), WideLoad, 0); 1170 } 1171 1172 MI.eraseFromParent(); 1173 return true; 1174 } 1175 1176 // 128-bit loads are supported for all instruction types. 1177 if (LoadSize <= MaxNonSmrdLoadSize) 1178 return false; 1179 1180 SmallVector<Register, 16> DefRegs(OpdMapper.getVRegs(0)); 1181 SmallVector<Register, 1> SrcRegs(OpdMapper.getVRegs(1)); 1182 1183 if (SrcRegs.empty()) 1184 SrcRegs.push_back(MI.getOperand(1).getReg()); 1185 1186 assert(LoadSize % MaxNonSmrdLoadSize == 0); 1187 1188 // RegBankSelect only emits scalar types, so we need to reset the pointer 1189 // operand to a pointer type. 1190 Register BasePtrReg = SrcRegs[0]; 1191 LLT PtrTy = MRI.getType(MI.getOperand(1).getReg()); 1192 MRI.setType(BasePtrReg, PtrTy); 1193 1194 MachineIRBuilder B(MI); 1195 1196 unsigned NumSplitParts = LoadTy.getSizeInBits() / MaxNonSmrdLoadSize; 1197 const LLT LoadSplitTy = LoadTy.divide(NumSplitParts); 1198 ApplyRegBankMapping O(*this, MRI, &AMDGPU::VGPRRegBank); 1199 GISelObserverWrapper Observer(&O); 1200 B.setChangeObserver(Observer); 1201 LegalizerHelper Helper(B.getMF(), Observer, B); 1202 1203 if (LoadTy.isVector()) { 1204 if (Helper.fewerElementsVector(MI, 0, LoadSplitTy) != LegalizerHelper::Legalized) 1205 return false; 1206 } else { 1207 if (Helper.narrowScalar(MI, 0, LoadSplitTy) != LegalizerHelper::Legalized) 1208 return false; 1209 } 1210 1211 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 1212 return true; 1213 } 1214 1215 bool AMDGPURegisterBankInfo::applyMappingDynStackAlloc( 1216 MachineInstr &MI, 1217 const AMDGPURegisterBankInfo::OperandsMapper &OpdMapper, 1218 MachineRegisterInfo &MRI) const { 1219 const MachineFunction &MF = *MI.getMF(); 1220 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>(); 1221 const auto &TFI = *ST.getFrameLowering(); 1222 1223 // Guard in case the stack growth direction ever changes with scratch 1224 // instructions. 1225 if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsDown) 1226 return false; 1227 1228 Register Dst = MI.getOperand(0).getReg(); 1229 Register AllocSize = MI.getOperand(1).getReg(); 1230 Align Alignment = assumeAligned(MI.getOperand(2).getImm()); 1231 1232 const RegisterBank *SizeBank = getRegBank(AllocSize, MRI, *TRI); 1233 1234 // TODO: Need to emit a wave reduction to get the maximum size. 1235 if (SizeBank != &AMDGPU::SGPRRegBank) 1236 return false; 1237 1238 LLT PtrTy = MRI.getType(Dst); 1239 LLT IntPtrTy = LLT::scalar(PtrTy.getSizeInBits()); 1240 1241 const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>(); 1242 Register SPReg = Info->getStackPtrOffsetReg(); 1243 ApplyRegBankMapping ApplyBank(*this, MRI, &AMDGPU::SGPRRegBank); 1244 GISelObserverWrapper Observer(&ApplyBank); 1245 1246 MachineIRBuilder B(MI); 1247 B.setChangeObserver(Observer); 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 = getConstantVRegVal(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 MachineInstr *Unused; 1329 1330 std::tie(Base, Offset, Unused) 1331 = AMDGPU::getBaseWithConstantOffset(*MRI, CombinedOffset); 1332 1333 uint32_t SOffset, ImmOffset; 1334 if (Offset > 0 && AMDGPU::splitMUBUFOffset(Offset, SOffset, ImmOffset, 1335 &RBI.Subtarget, Alignment)) { 1336 if (RBI.getRegBank(Base, *MRI, *RBI.TRI) == &AMDGPU::VGPRRegBank) { 1337 VOffsetReg = Base; 1338 SOffsetReg = B.buildConstant(S32, SOffset).getReg(0); 1339 B.getMRI()->setRegBank(SOffsetReg, AMDGPU::SGPRRegBank); 1340 InstOffsetVal = ImmOffset; 1341 return 0; // XXX - Why is this 0? 1342 } 1343 1344 // If we have SGPR base, we can use it for soffset. 1345 if (SOffset == 0) { 1346 VOffsetReg = B.buildConstant(S32, 0).getReg(0); 1347 B.getMRI()->setRegBank(VOffsetReg, AMDGPU::VGPRRegBank); 1348 SOffsetReg = Base; 1349 InstOffsetVal = ImmOffset; 1350 return 0; // XXX - Why is this 0? 1351 } 1352 } 1353 1354 // Handle the variable sgpr + vgpr case. 1355 if (MachineInstr *Add = getOpcodeDef(AMDGPU::G_ADD, CombinedOffset, *MRI)) { 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 GISelObserverWrapper Observer(&ApplyBank); 1539 MachineIRBuilder B(MI); 1540 B.setChangeObserver(Observer); 1541 1542 // Ensure the high bits are clear to insert the offset. 1543 auto OffsetMask = B.buildConstant(S32, maskTrailingOnes<unsigned>(6)); 1544 auto ClampOffset = B.buildAnd(S32, OffsetReg, OffsetMask); 1545 1546 // Zeros out the low bits, so don't bother clamping the input value. 1547 auto ShiftWidth = B.buildShl(S32, WidthReg, B.buildConstant(S32, 16)); 1548 1549 // Transformation function, pack the offset and width of a BFE into 1550 // the format expected by the S_BFE_I32 / S_BFE_U32. In the second 1551 // source, bits [5:0] contain the offset and bits [22:16] the width. 1552 auto MergedInputs = B.buildOr(S32, ClampOffset, ShiftWidth); 1553 1554 // TODO: It might be worth using a pseudo here to avoid scc clobber and 1555 // register class constraints. 1556 unsigned Opc = Ty == S32 ? (Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32) : 1557 (Signed ? AMDGPU::S_BFE_I64 : AMDGPU::S_BFE_U64); 1558 1559 auto MIB = B.buildInstr(Opc, {DstReg}, {SrcReg, MergedInputs}); 1560 if (!constrainSelectedInstRegOperands(*MIB, *TII, *TRI, *this)) 1561 llvm_unreachable("failed to constrain BFE"); 1562 1563 MI.eraseFromParent(); 1564 return true; 1565 } 1566 1567 // FIXME: Duplicated from LegalizerHelper 1568 static CmpInst::Predicate minMaxToCompare(unsigned Opc) { 1569 switch (Opc) { 1570 case TargetOpcode::G_SMIN: 1571 return CmpInst::ICMP_SLT; 1572 case TargetOpcode::G_SMAX: 1573 return CmpInst::ICMP_SGT; 1574 case TargetOpcode::G_UMIN: 1575 return CmpInst::ICMP_ULT; 1576 case TargetOpcode::G_UMAX: 1577 return CmpInst::ICMP_UGT; 1578 default: 1579 llvm_unreachable("not in integer min/max"); 1580 } 1581 } 1582 1583 static unsigned minMaxToExtend(unsigned Opc) { 1584 switch (Opc) { 1585 case TargetOpcode::G_SMIN: 1586 case TargetOpcode::G_SMAX: 1587 return TargetOpcode::G_SEXT; 1588 case TargetOpcode::G_UMIN: 1589 case TargetOpcode::G_UMAX: 1590 return TargetOpcode::G_ZEXT; 1591 default: 1592 llvm_unreachable("not in integer min/max"); 1593 } 1594 } 1595 1596 // Emit a legalized extension from <2 x s16> to 2 32-bit components, avoiding 1597 // any illegal vector extend or unmerge operations. 1598 static std::pair<Register, Register> 1599 unpackV2S16ToS32(MachineIRBuilder &B, Register Src, unsigned ExtOpcode) { 1600 const LLT S32 = LLT::scalar(32); 1601 auto Bitcast = B.buildBitcast(S32, Src); 1602 1603 if (ExtOpcode == TargetOpcode::G_SEXT) { 1604 auto ExtLo = B.buildSExtInReg(S32, Bitcast, 16); 1605 auto ShiftHi = B.buildAShr(S32, Bitcast, B.buildConstant(S32, 16)); 1606 return std::make_pair(ExtLo.getReg(0), ShiftHi.getReg(0)); 1607 } 1608 1609 auto ShiftHi = B.buildLShr(S32, Bitcast, B.buildConstant(S32, 16)); 1610 if (ExtOpcode == TargetOpcode::G_ZEXT) { 1611 auto ExtLo = B.buildAnd(S32, Bitcast, B.buildConstant(S32, 0xffff)); 1612 return std::make_pair(ExtLo.getReg(0), ShiftHi.getReg(0)); 1613 } 1614 1615 assert(ExtOpcode == TargetOpcode::G_ANYEXT); 1616 return std::make_pair(Bitcast.getReg(0), ShiftHi.getReg(0)); 1617 } 1618 1619 static MachineInstr *buildExpandedScalarMinMax(MachineIRBuilder &B, 1620 CmpInst::Predicate Pred, 1621 Register Dst, Register Src0, 1622 Register Src1) { 1623 const LLT CmpType = LLT::scalar(32); 1624 auto Cmp = B.buildICmp(Pred, CmpType, Src0, Src1); 1625 return B.buildSelect(Dst, Cmp, Src0, Src1); 1626 } 1627 1628 // FIXME: Duplicated from LegalizerHelper, except changing the boolean type. 1629 void AMDGPURegisterBankInfo::lowerScalarMinMax(MachineIRBuilder &B, 1630 MachineInstr &MI) const { 1631 Register Dst = MI.getOperand(0).getReg(); 1632 Register Src0 = MI.getOperand(1).getReg(); 1633 Register Src1 = MI.getOperand(2).getReg(); 1634 1635 const CmpInst::Predicate Pred = minMaxToCompare(MI.getOpcode()); 1636 MachineInstr *Sel = buildExpandedScalarMinMax(B, Pred, Dst, Src0, Src1); 1637 1638 Register CmpReg = Sel->getOperand(1).getReg(); 1639 B.getMRI()->setRegBank(CmpReg, AMDGPU::SGPRRegBank); 1640 MI.eraseFromParent(); 1641 } 1642 1643 // For cases where only a single copy is inserted for matching register banks. 1644 // Replace the register in the instruction operand 1645 static bool substituteSimpleCopyRegs( 1646 const AMDGPURegisterBankInfo::OperandsMapper &OpdMapper, unsigned OpIdx) { 1647 SmallVector<unsigned, 1> SrcReg(OpdMapper.getVRegs(OpIdx)); 1648 if (!SrcReg.empty()) { 1649 assert(SrcReg.size() == 1); 1650 OpdMapper.getMI().getOperand(OpIdx).setReg(SrcReg[0]); 1651 return true; 1652 } 1653 1654 return false; 1655 } 1656 1657 /// Handle register layout difference for f16 images for some subtargets. 1658 Register AMDGPURegisterBankInfo::handleD16VData(MachineIRBuilder &B, 1659 MachineRegisterInfo &MRI, 1660 Register Reg) const { 1661 if (!Subtarget.hasUnpackedD16VMem()) 1662 return Reg; 1663 1664 const LLT S16 = LLT::scalar(16); 1665 LLT StoreVT = MRI.getType(Reg); 1666 if (!StoreVT.isVector() || StoreVT.getElementType() != S16) 1667 return Reg; 1668 1669 auto Unmerge = B.buildUnmerge(S16, Reg); 1670 1671 1672 SmallVector<Register, 4> WideRegs; 1673 for (int I = 0, E = Unmerge->getNumOperands() - 1; I != E; ++I) 1674 WideRegs.push_back(Unmerge.getReg(I)); 1675 1676 const LLT S32 = LLT::scalar(32); 1677 int NumElts = StoreVT.getNumElements(); 1678 1679 return B.buildMerge(LLT::vector(NumElts, S32), WideRegs).getReg(0); 1680 } 1681 1682 static std::pair<Register, unsigned> 1683 getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg) { 1684 int64_t Const; 1685 if (mi_match(Reg, MRI, m_ICst(Const))) 1686 return std::make_pair(Register(), Const); 1687 1688 Register Base; 1689 if (mi_match(Reg, MRI, m_GAdd(m_Reg(Base), m_ICst(Const)))) 1690 return std::make_pair(Base, Const); 1691 1692 // TODO: Handle G_OR used for add case 1693 return std::make_pair(Reg, 0); 1694 } 1695 1696 std::pair<Register, unsigned> 1697 AMDGPURegisterBankInfo::splitBufferOffsets(MachineIRBuilder &B, 1698 Register OrigOffset) const { 1699 const unsigned MaxImm = 4095; 1700 Register BaseReg; 1701 unsigned ImmOffset; 1702 const LLT S32 = LLT::scalar(32); 1703 1704 std::tie(BaseReg, ImmOffset) = getBaseWithConstantOffset(*B.getMRI(), 1705 OrigOffset); 1706 1707 unsigned C1 = 0; 1708 if (ImmOffset != 0) { 1709 // If the immediate value is too big for the immoffset field, put the value 1710 // and -4096 into the immoffset field so that the value that is copied/added 1711 // for the voffset field is a multiple of 4096, and it stands more chance 1712 // of being CSEd with the copy/add for another similar load/store. 1713 // However, do not do that rounding down to a multiple of 4096 if that is a 1714 // negative number, as it appears to be illegal to have a negative offset 1715 // in the vgpr, even if adding the immediate offset makes it positive. 1716 unsigned Overflow = ImmOffset & ~MaxImm; 1717 ImmOffset -= Overflow; 1718 if ((int32_t)Overflow < 0) { 1719 Overflow += ImmOffset; 1720 ImmOffset = 0; 1721 } 1722 1723 C1 = ImmOffset; 1724 if (Overflow != 0) { 1725 if (!BaseReg) 1726 BaseReg = B.buildConstant(S32, Overflow).getReg(0); 1727 else { 1728 auto OverflowVal = B.buildConstant(S32, Overflow); 1729 BaseReg = B.buildAdd(S32, BaseReg, OverflowVal).getReg(0); 1730 } 1731 } 1732 } 1733 1734 if (!BaseReg) 1735 BaseReg = B.buildConstant(S32, 0).getReg(0); 1736 1737 return {BaseReg, C1}; 1738 } 1739 1740 static bool isZero(Register Reg, MachineRegisterInfo &MRI) { 1741 int64_t C; 1742 return mi_match(Reg, MRI, m_ICst(C)) && C == 0; 1743 } 1744 1745 static unsigned extractGLC(unsigned CachePolicy) { 1746 return CachePolicy & 1; 1747 } 1748 1749 static unsigned extractSLC(unsigned CachePolicy) { 1750 return (CachePolicy >> 1) & 1; 1751 } 1752 1753 static unsigned extractDLC(unsigned CachePolicy) { 1754 return (CachePolicy >> 2) & 1; 1755 } 1756 1757 MachineInstr * 1758 AMDGPURegisterBankInfo::selectStoreIntrinsic(MachineIRBuilder &B, 1759 MachineInstr &MI) const { 1760 MachineRegisterInfo &MRI = *B.getMRI(); 1761 executeInWaterfallLoop(B, MI, MRI, {2, 4}); 1762 1763 // FIXME: DAG lowering brokenly changes opcode based on FP vs. integer. 1764 1765 Register VData = MI.getOperand(1).getReg(); 1766 LLT Ty = MRI.getType(VData); 1767 1768 int EltSize = Ty.getScalarSizeInBits(); 1769 int Size = Ty.getSizeInBits(); 1770 1771 // FIXME: Broken integer truncstore. 1772 if (EltSize != 32) 1773 report_fatal_error("unhandled intrinsic store"); 1774 1775 // FIXME: Verifier should enforce 1 MMO for these intrinsics. 1776 const int MemSize = (*MI.memoperands_begin())->getSize(); 1777 1778 1779 Register RSrc = MI.getOperand(2).getReg(); 1780 Register VOffset = MI.getOperand(3).getReg(); 1781 Register SOffset = MI.getOperand(4).getReg(); 1782 unsigned CachePolicy = MI.getOperand(5).getImm(); 1783 1784 unsigned ImmOffset; 1785 std::tie(VOffset, ImmOffset) = splitBufferOffsets(B, VOffset); 1786 1787 const bool Offen = !isZero(VOffset, MRI); 1788 1789 unsigned Opc = AMDGPU::BUFFER_STORE_DWORD_OFFEN_exact; 1790 switch (8 * MemSize) { 1791 case 8: 1792 Opc = Offen ? AMDGPU::BUFFER_STORE_BYTE_OFFEN_exact : 1793 AMDGPU::BUFFER_STORE_BYTE_OFFSET_exact; 1794 break; 1795 case 16: 1796 Opc = Offen ? AMDGPU::BUFFER_STORE_SHORT_OFFEN_exact : 1797 AMDGPU::BUFFER_STORE_SHORT_OFFSET_exact; 1798 break; 1799 default: 1800 Opc = Offen ? AMDGPU::BUFFER_STORE_DWORD_OFFEN_exact : 1801 AMDGPU::BUFFER_STORE_DWORD_OFFSET_exact; 1802 if (Size > 32) 1803 Opc = AMDGPU::getMUBUFOpcode(Opc, Size / 32); 1804 break; 1805 } 1806 1807 1808 // Set the insertion point back to the instruction in case it was moved into a 1809 // loop. 1810 B.setInstr(MI); 1811 1812 MachineInstrBuilder MIB = B.buildInstr(Opc) 1813 .addUse(VData); 1814 1815 if (Offen) 1816 MIB.addUse(VOffset); 1817 1818 MIB.addUse(RSrc) 1819 .addUse(SOffset) 1820 .addImm(ImmOffset) 1821 .addImm(extractGLC(CachePolicy)) 1822 .addImm(extractSLC(CachePolicy)) 1823 .addImm(0) // tfe: FIXME: Remove from inst 1824 .addImm(extractDLC(CachePolicy)) 1825 .cloneMemRefs(MI); 1826 1827 // FIXME: We need a way to report failure from applyMappingImpl. 1828 // Insert constrain copies before inserting the loop. 1829 if (!constrainSelectedInstRegOperands(*MIB, *TII, *TRI, *this)) 1830 report_fatal_error("failed to constrain selected store intrinsic"); 1831 1832 return MIB; 1833 } 1834 1835 bool AMDGPURegisterBankInfo::buildVCopy(MachineIRBuilder &B, Register DstReg, 1836 Register SrcReg) const { 1837 MachineRegisterInfo &MRI = *B.getMRI(); 1838 LLT SrcTy = MRI.getType(SrcReg); 1839 if (SrcTy.getSizeInBits() == 32) { 1840 // Use a v_mov_b32 here to make the exec dependency explicit. 1841 B.buildInstr(AMDGPU::V_MOV_B32_e32) 1842 .addDef(DstReg) 1843 .addUse(SrcReg); 1844 return constrainGenericRegister(DstReg, AMDGPU::VGPR_32RegClass, MRI) && 1845 constrainGenericRegister(SrcReg, AMDGPU::SReg_32RegClass, MRI); 1846 } 1847 1848 Register TmpReg0 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); 1849 Register TmpReg1 = MRI.createVirtualRegister(&AMDGPU::VGPR_32RegClass); 1850 1851 B.buildInstr(AMDGPU::V_MOV_B32_e32) 1852 .addDef(TmpReg0) 1853 .addUse(SrcReg, 0, AMDGPU::sub0); 1854 B.buildInstr(AMDGPU::V_MOV_B32_e32) 1855 .addDef(TmpReg1) 1856 .addUse(SrcReg, 0, AMDGPU::sub1); 1857 B.buildInstr(AMDGPU::REG_SEQUENCE) 1858 .addDef(DstReg) 1859 .addUse(TmpReg0) 1860 .addImm(AMDGPU::sub0) 1861 .addUse(TmpReg1) 1862 .addImm(AMDGPU::sub1); 1863 1864 return constrainGenericRegister(SrcReg, AMDGPU::SReg_64RegClass, MRI) && 1865 constrainGenericRegister(DstReg, AMDGPU::VReg_64RegClass, MRI); 1866 } 1867 1868 /// Utility function for pushing dynamic vector indexes with a constant offset 1869 /// into waterwall loops. 1870 static void reinsertVectorIndexAdd(MachineIRBuilder &B, 1871 MachineInstr &IdxUseInstr, 1872 unsigned OpIdx, 1873 unsigned ConstOffset) { 1874 MachineRegisterInfo &MRI = *B.getMRI(); 1875 const LLT S32 = LLT::scalar(32); 1876 Register WaterfallIdx = IdxUseInstr.getOperand(OpIdx).getReg(); 1877 B.setInsertPt(*IdxUseInstr.getParent(), IdxUseInstr.getIterator()); 1878 1879 auto MaterializedOffset = B.buildConstant(S32, ConstOffset); 1880 1881 auto Add = B.buildAdd(S32, WaterfallIdx, MaterializedOffset); 1882 MRI.setRegBank(MaterializedOffset.getReg(0), AMDGPU::SGPRRegBank); 1883 MRI.setRegBank(Add.getReg(0), AMDGPU::SGPRRegBank); 1884 IdxUseInstr.getOperand(OpIdx).setReg(Add.getReg(0)); 1885 } 1886 1887 /// Implement extending a 32-bit value to a 64-bit value. \p Lo32Reg is the 1888 /// original 32-bit source value (to be inserted in the low part of the combined 1889 /// 64-bit result), and \p Hi32Reg is the high half of the combined 64-bit 1890 /// value. 1891 static void extendLow32IntoHigh32(MachineIRBuilder &B, 1892 Register Hi32Reg, Register Lo32Reg, 1893 unsigned ExtOpc, 1894 const RegisterBank &RegBank, 1895 bool IsBooleanSrc = false) { 1896 if (ExtOpc == AMDGPU::G_ZEXT) { 1897 B.buildConstant(Hi32Reg, 0); 1898 } else if (ExtOpc == AMDGPU::G_SEXT) { 1899 if (IsBooleanSrc) { 1900 // If we know the original source was an s1, the high half is the same as 1901 // the low. 1902 B.buildCopy(Hi32Reg, Lo32Reg); 1903 } else { 1904 // Replicate sign bit from 32-bit extended part. 1905 auto ShiftAmt = B.buildConstant(LLT::scalar(32), 31); 1906 B.getMRI()->setRegBank(ShiftAmt.getReg(0), RegBank); 1907 B.buildAShr(Hi32Reg, Lo32Reg, ShiftAmt); 1908 } 1909 } else { 1910 assert(ExtOpc == AMDGPU::G_ANYEXT && "not an integer extension"); 1911 B.buildUndef(Hi32Reg); 1912 } 1913 } 1914 1915 bool AMDGPURegisterBankInfo::foldExtractEltToCmpSelect( 1916 MachineInstr &MI, MachineRegisterInfo &MRI, 1917 const OperandsMapper &OpdMapper) const { 1918 1919 Register VecReg = MI.getOperand(1).getReg(); 1920 Register Idx = MI.getOperand(2).getReg(); 1921 1922 const RegisterBank &IdxBank = 1923 *OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 1924 1925 bool IsDivergentIdx = IdxBank == AMDGPU::VGPRRegBank; 1926 1927 LLT VecTy = MRI.getType(VecReg); 1928 unsigned EltSize = VecTy.getScalarSizeInBits(); 1929 unsigned NumElem = VecTy.getNumElements(); 1930 1931 if (!SITargetLowering::shouldExpandVectorDynExt(EltSize, NumElem, 1932 IsDivergentIdx)) 1933 return false; 1934 1935 MachineIRBuilder B(MI); 1936 LLT S32 = LLT::scalar(32); 1937 1938 const RegisterBank &DstBank = 1939 *OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 1940 const RegisterBank &SrcBank = 1941 *OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 1942 1943 const RegisterBank &CCBank = 1944 (DstBank == AMDGPU::SGPRRegBank && 1945 SrcBank == AMDGPU::SGPRRegBank && 1946 IdxBank == AMDGPU::SGPRRegBank) ? AMDGPU::SGPRRegBank 1947 : AMDGPU::VCCRegBank; 1948 LLT CCTy = (CCBank == AMDGPU::SGPRRegBank) ? S32 : LLT::scalar(1); 1949 1950 if (CCBank == AMDGPU::VCCRegBank && IdxBank == AMDGPU::SGPRRegBank) { 1951 Idx = B.buildCopy(S32, Idx)->getOperand(0).getReg(); 1952 MRI.setRegBank(Idx, AMDGPU::VGPRRegBank); 1953 } 1954 1955 LLT EltTy = VecTy.getScalarType(); 1956 SmallVector<Register, 2> DstRegs(OpdMapper.getVRegs(0)); 1957 unsigned NumLanes = DstRegs.size(); 1958 if (!NumLanes) 1959 NumLanes = 1; 1960 else 1961 EltTy = MRI.getType(DstRegs[0]); 1962 1963 auto UnmergeToEltTy = B.buildUnmerge(EltTy, VecReg); 1964 SmallVector<Register, 2> Res(NumLanes); 1965 for (unsigned L = 0; L < NumLanes; ++L) 1966 Res[L] = UnmergeToEltTy.getReg(L); 1967 1968 for (unsigned I = 1; I < NumElem; ++I) { 1969 auto IC = B.buildConstant(S32, I); 1970 MRI.setRegBank(IC->getOperand(0).getReg(), AMDGPU::SGPRRegBank); 1971 auto Cmp = B.buildICmp(CmpInst::ICMP_EQ, CCTy, Idx, IC); 1972 MRI.setRegBank(Cmp->getOperand(0).getReg(), CCBank); 1973 1974 for (unsigned L = 0; L < NumLanes; ++L) { 1975 auto S = B.buildSelect(EltTy, Cmp, 1976 UnmergeToEltTy.getReg(I * NumLanes + L), Res[L]); 1977 1978 for (unsigned N : { 0, 2, 3 }) 1979 MRI.setRegBank(S->getOperand(N).getReg(), DstBank); 1980 1981 Res[L] = S->getOperand(0).getReg(); 1982 } 1983 } 1984 1985 for (unsigned L = 0; L < NumLanes; ++L) { 1986 Register DstReg = (NumLanes == 1) ? MI.getOperand(0).getReg() : DstRegs[L]; 1987 B.buildCopy(DstReg, Res[L]); 1988 MRI.setRegBank(DstReg, DstBank); 1989 } 1990 1991 MRI.setRegBank(MI.getOperand(0).getReg(), DstBank); 1992 MI.eraseFromParent(); 1993 1994 return true; 1995 } 1996 1997 bool AMDGPURegisterBankInfo::foldInsertEltToCmpSelect( 1998 MachineInstr &MI, MachineRegisterInfo &MRI, 1999 const OperandsMapper &OpdMapper) const { 2000 2001 Register VecReg = MI.getOperand(1).getReg(); 2002 Register Idx = MI.getOperand(3).getReg(); 2003 2004 const RegisterBank &IdxBank = 2005 *OpdMapper.getInstrMapping().getOperandMapping(3).BreakDown[0].RegBank; 2006 2007 bool IsDivergentIdx = IdxBank == AMDGPU::VGPRRegBank; 2008 2009 LLT VecTy = MRI.getType(VecReg); 2010 unsigned EltSize = VecTy.getScalarSizeInBits(); 2011 unsigned NumElem = VecTy.getNumElements(); 2012 2013 if (!SITargetLowering::shouldExpandVectorDynExt(EltSize, NumElem, 2014 IsDivergentIdx)) 2015 return false; 2016 2017 MachineIRBuilder B(MI); 2018 LLT S32 = LLT::scalar(32); 2019 2020 const RegisterBank &DstBank = 2021 *OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2022 const RegisterBank &SrcBank = 2023 *OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 2024 const RegisterBank &InsBank = 2025 *OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 2026 2027 const RegisterBank &CCBank = 2028 (DstBank == AMDGPU::SGPRRegBank && 2029 SrcBank == AMDGPU::SGPRRegBank && 2030 InsBank == AMDGPU::SGPRRegBank && 2031 IdxBank == AMDGPU::SGPRRegBank) ? AMDGPU::SGPRRegBank 2032 : AMDGPU::VCCRegBank; 2033 LLT CCTy = (CCBank == AMDGPU::SGPRRegBank) ? S32 : LLT::scalar(1); 2034 2035 if (CCBank == AMDGPU::VCCRegBank && IdxBank == AMDGPU::SGPRRegBank) { 2036 Idx = B.buildCopy(S32, Idx)->getOperand(0).getReg(); 2037 MRI.setRegBank(Idx, AMDGPU::VGPRRegBank); 2038 } 2039 2040 LLT EltTy = VecTy.getScalarType(); 2041 SmallVector<Register, 2> InsRegs(OpdMapper.getVRegs(2)); 2042 unsigned NumLanes = InsRegs.size(); 2043 if (!NumLanes) { 2044 NumLanes = 1; 2045 InsRegs.push_back(MI.getOperand(2).getReg()); 2046 } else { 2047 EltTy = MRI.getType(InsRegs[0]); 2048 } 2049 2050 auto UnmergeToEltTy = B.buildUnmerge(EltTy, VecReg); 2051 SmallVector<Register, 16> Ops(NumElem * NumLanes); 2052 2053 for (unsigned I = 0; I < NumElem; ++I) { 2054 auto IC = B.buildConstant(S32, I); 2055 MRI.setRegBank(IC->getOperand(0).getReg(), AMDGPU::SGPRRegBank); 2056 auto Cmp = B.buildICmp(CmpInst::ICMP_EQ, CCTy, Idx, IC); 2057 MRI.setRegBank(Cmp->getOperand(0).getReg(), CCBank); 2058 2059 for (unsigned L = 0; L < NumLanes; ++L) { 2060 auto S = B.buildSelect(EltTy, Cmp, InsRegs[L], 2061 UnmergeToEltTy.getReg(I * NumLanes + L)); 2062 2063 for (unsigned N : { 0, 2, 3 }) 2064 MRI.setRegBank(S->getOperand(N).getReg(), DstBank); 2065 2066 Ops[I * NumLanes + L] = S->getOperand(0).getReg(); 2067 } 2068 } 2069 2070 LLT MergeTy = LLT::vector(Ops.size(), EltTy); 2071 if (MergeTy == MRI.getType(MI.getOperand(0).getReg())) { 2072 B.buildBuildVector(MI.getOperand(0), Ops); 2073 } else { 2074 auto Vec = B.buildBuildVector(MergeTy, Ops); 2075 MRI.setRegBank(Vec->getOperand(0).getReg(), DstBank); 2076 B.buildBitcast(MI.getOperand(0).getReg(), Vec); 2077 } 2078 2079 MRI.setRegBank(MI.getOperand(0).getReg(), DstBank); 2080 MI.eraseFromParent(); 2081 2082 return true; 2083 } 2084 2085 void AMDGPURegisterBankInfo::applyMappingImpl( 2086 const OperandsMapper &OpdMapper) const { 2087 MachineInstr &MI = OpdMapper.getMI(); 2088 unsigned Opc = MI.getOpcode(); 2089 MachineRegisterInfo &MRI = OpdMapper.getMRI(); 2090 switch (Opc) { 2091 case AMDGPU::G_PHI: { 2092 Register DstReg = MI.getOperand(0).getReg(); 2093 LLT DstTy = MRI.getType(DstReg); 2094 if (DstTy != LLT::scalar(1)) 2095 break; 2096 2097 const LLT S32 = LLT::scalar(32); 2098 const RegisterBank *DstBank = 2099 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2100 if (DstBank == &AMDGPU::VCCRegBank) { 2101 applyDefaultMapping(OpdMapper); 2102 // The standard handling only considers the result register bank for 2103 // phis. For VCC, blindly inserting a copy when the phi is lowered will 2104 // produce an invalid copy. We can only copy with some kind of compare to 2105 // get a vector boolean result. Insert a regitser bank copy that will be 2106 // correctly lowered to a compare. 2107 MachineIRBuilder B(*MI.getParent()->getParent()); 2108 2109 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) { 2110 Register SrcReg = MI.getOperand(I).getReg(); 2111 const RegisterBank *SrcBank = getRegBank(SrcReg, MRI, *TRI); 2112 2113 if (SrcBank != &AMDGPU::VCCRegBank) { 2114 MachineBasicBlock *SrcMBB = MI.getOperand(I + 1).getMBB(); 2115 B.setInsertPt(*SrcMBB, SrcMBB->getFirstTerminator()); 2116 2117 auto Copy = B.buildCopy(LLT::scalar(1), SrcReg); 2118 MRI.setRegBank(Copy.getReg(0), AMDGPU::VCCRegBank); 2119 MI.getOperand(I).setReg(Copy.getReg(0)); 2120 } 2121 } 2122 2123 return; 2124 } 2125 2126 // Phi handling is strange and only considers the bank of the destination. 2127 substituteSimpleCopyRegs(OpdMapper, 0); 2128 2129 // Promote SGPR/VGPR booleans to s32 2130 MachineFunction *MF = MI.getParent()->getParent(); 2131 ApplyRegBankMapping ApplyBank(*this, MRI, DstBank); 2132 GISelObserverWrapper Observer(&ApplyBank); 2133 MachineIRBuilder B(MI); 2134 LegalizerHelper Helper(*MF, Observer, B); 2135 2136 if (Helper.widenScalar(MI, 0, S32) != LegalizerHelper::Legalized) 2137 llvm_unreachable("widen scalar should have succeeded"); 2138 2139 return; 2140 } 2141 case AMDGPU::G_ICMP: 2142 case AMDGPU::G_UADDO: 2143 case AMDGPU::G_USUBO: 2144 case AMDGPU::G_UADDE: 2145 case AMDGPU::G_SADDE: 2146 case AMDGPU::G_USUBE: 2147 case AMDGPU::G_SSUBE: { 2148 unsigned BoolDstOp = Opc == AMDGPU::G_ICMP ? 0 : 1; 2149 Register DstReg = MI.getOperand(BoolDstOp).getReg(); 2150 2151 const RegisterBank *DstBank = 2152 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2153 if (DstBank != &AMDGPU::SGPRRegBank) 2154 break; 2155 2156 const bool HasCarryIn = MI.getNumOperands() == 5; 2157 2158 // If this is a scalar compare, promote the result to s32, as the selection 2159 // will end up using a copy to a 32-bit vreg. 2160 const LLT S32 = LLT::scalar(32); 2161 Register NewDstReg = MRI.createGenericVirtualRegister(S32); 2162 MRI.setRegBank(NewDstReg, AMDGPU::SGPRRegBank); 2163 MI.getOperand(BoolDstOp).setReg(NewDstReg); 2164 MachineIRBuilder B(MI); 2165 2166 if (HasCarryIn) { 2167 Register NewSrcReg = MRI.createGenericVirtualRegister(S32); 2168 MRI.setRegBank(NewSrcReg, AMDGPU::SGPRRegBank); 2169 B.buildZExt(NewSrcReg, MI.getOperand(4).getReg()); 2170 MI.getOperand(4).setReg(NewSrcReg); 2171 } 2172 2173 MachineBasicBlock *MBB = MI.getParent(); 2174 B.setInsertPt(*MBB, std::next(MI.getIterator())); 2175 2176 // If we had a constrained VCC result register, a copy was inserted to VCC 2177 // from SGPR. 2178 SmallVector<Register, 1> DefRegs(OpdMapper.getVRegs(0)); 2179 if (DefRegs.empty()) 2180 DefRegs.push_back(DstReg); 2181 B.buildTrunc(DefRegs[0], NewDstReg); 2182 return; 2183 } 2184 case AMDGPU::G_SELECT: { 2185 Register DstReg = MI.getOperand(0).getReg(); 2186 LLT DstTy = MRI.getType(DstReg); 2187 2188 SmallVector<Register, 1> CondRegs(OpdMapper.getVRegs(1)); 2189 if (CondRegs.empty()) 2190 CondRegs.push_back(MI.getOperand(1).getReg()); 2191 else { 2192 assert(CondRegs.size() == 1); 2193 } 2194 2195 const RegisterBank *CondBank = getRegBank(CondRegs[0], MRI, *TRI); 2196 if (CondBank == &AMDGPU::SGPRRegBank) { 2197 MachineIRBuilder B(MI); 2198 const LLT S32 = LLT::scalar(32); 2199 Register NewCondReg = MRI.createGenericVirtualRegister(S32); 2200 MRI.setRegBank(NewCondReg, AMDGPU::SGPRRegBank); 2201 2202 MI.getOperand(1).setReg(NewCondReg); 2203 B.buildZExt(NewCondReg, CondRegs[0]); 2204 } 2205 2206 if (DstTy.getSizeInBits() != 64) 2207 break; 2208 2209 MachineIRBuilder B(MI); 2210 LLT HalfTy = getHalfSizedType(DstTy); 2211 2212 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 2213 SmallVector<Register, 2> Src1Regs(OpdMapper.getVRegs(2)); 2214 SmallVector<Register, 2> Src2Regs(OpdMapper.getVRegs(3)); 2215 2216 // All inputs are SGPRs, nothing special to do. 2217 if (DefRegs.empty()) { 2218 assert(Src1Regs.empty() && Src2Regs.empty()); 2219 break; 2220 } 2221 2222 if (Src1Regs.empty()) 2223 split64BitValueForMapping(B, Src1Regs, HalfTy, MI.getOperand(2).getReg()); 2224 else { 2225 setRegsToType(MRI, Src1Regs, HalfTy); 2226 } 2227 2228 if (Src2Regs.empty()) 2229 split64BitValueForMapping(B, Src2Regs, HalfTy, MI.getOperand(3).getReg()); 2230 else 2231 setRegsToType(MRI, Src2Regs, HalfTy); 2232 2233 setRegsToType(MRI, DefRegs, HalfTy); 2234 2235 B.buildSelect(DefRegs[0], CondRegs[0], Src1Regs[0], Src2Regs[0]); 2236 B.buildSelect(DefRegs[1], CondRegs[0], Src1Regs[1], Src2Regs[1]); 2237 2238 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 2239 MI.eraseFromParent(); 2240 return; 2241 } 2242 case AMDGPU::G_BRCOND: { 2243 Register CondReg = MI.getOperand(0).getReg(); 2244 // FIXME: Should use legalizer helper, but should change bool ext type. 2245 const RegisterBank *CondBank = 2246 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2247 2248 if (CondBank == &AMDGPU::SGPRRegBank) { 2249 MachineIRBuilder B(MI); 2250 const LLT S32 = LLT::scalar(32); 2251 Register NewCondReg = MRI.createGenericVirtualRegister(S32); 2252 MRI.setRegBank(NewCondReg, AMDGPU::SGPRRegBank); 2253 2254 MI.getOperand(0).setReg(NewCondReg); 2255 B.buildZExt(NewCondReg, CondReg); 2256 return; 2257 } 2258 2259 break; 2260 } 2261 case AMDGPU::G_AND: 2262 case AMDGPU::G_OR: 2263 case AMDGPU::G_XOR: { 2264 // 64-bit and is only available on the SALU, so split into 2 32-bit ops if 2265 // there is a VGPR input. 2266 Register DstReg = MI.getOperand(0).getReg(); 2267 LLT DstTy = MRI.getType(DstReg); 2268 2269 if (DstTy.getSizeInBits() == 1) { 2270 const RegisterBank *DstBank = 2271 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2272 if (DstBank == &AMDGPU::VCCRegBank) 2273 break; 2274 2275 MachineFunction *MF = MI.getParent()->getParent(); 2276 ApplyRegBankMapping ApplyBank(*this, MRI, DstBank); 2277 GISelObserverWrapper Observer(&ApplyBank); 2278 MachineIRBuilder B(MI); 2279 LegalizerHelper Helper(*MF, Observer, B); 2280 2281 if (Helper.widenScalar(MI, 0, LLT::scalar(32)) != 2282 LegalizerHelper::Legalized) 2283 llvm_unreachable("widen scalar should have succeeded"); 2284 return; 2285 } 2286 2287 if (DstTy.getSizeInBits() != 64) 2288 break; 2289 2290 LLT HalfTy = getHalfSizedType(DstTy); 2291 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 2292 SmallVector<Register, 2> Src0Regs(OpdMapper.getVRegs(1)); 2293 SmallVector<Register, 2> Src1Regs(OpdMapper.getVRegs(2)); 2294 2295 // All inputs are SGPRs, nothing special to do. 2296 if (DefRegs.empty()) { 2297 assert(Src0Regs.empty() && Src1Regs.empty()); 2298 break; 2299 } 2300 2301 assert(DefRegs.size() == 2); 2302 assert(Src0Regs.size() == Src1Regs.size() && 2303 (Src0Regs.empty() || Src0Regs.size() == 2)); 2304 2305 // Depending on where the source registers came from, the generic code may 2306 // have decided to split the inputs already or not. If not, we still need to 2307 // extract the values. 2308 MachineIRBuilder B(MI); 2309 2310 if (Src0Regs.empty()) 2311 split64BitValueForMapping(B, Src0Regs, HalfTy, MI.getOperand(1).getReg()); 2312 else 2313 setRegsToType(MRI, Src0Regs, HalfTy); 2314 2315 if (Src1Regs.empty()) 2316 split64BitValueForMapping(B, Src1Regs, HalfTy, MI.getOperand(2).getReg()); 2317 else 2318 setRegsToType(MRI, Src1Regs, HalfTy); 2319 2320 setRegsToType(MRI, DefRegs, HalfTy); 2321 2322 B.buildInstr(Opc, {DefRegs[0]}, {Src0Regs[0], Src1Regs[0]}); 2323 B.buildInstr(Opc, {DefRegs[1]}, {Src0Regs[1], Src1Regs[1]}); 2324 2325 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 2326 MI.eraseFromParent(); 2327 return; 2328 } 2329 case AMDGPU::G_ADD: 2330 case AMDGPU::G_SUB: 2331 case AMDGPU::G_MUL: 2332 case AMDGPU::G_SHL: 2333 case AMDGPU::G_LSHR: 2334 case AMDGPU::G_ASHR: { 2335 Register DstReg = MI.getOperand(0).getReg(); 2336 LLT DstTy = MRI.getType(DstReg); 2337 2338 // 16-bit operations are VALU only, but can be promoted to 32-bit SALU. 2339 // Packed 16-bit operations need to be scalarized and promoted. 2340 if (DstTy != LLT::scalar(16) && DstTy != LLT::vector(2, 16)) 2341 break; 2342 2343 const RegisterBank *DstBank = 2344 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2345 if (DstBank == &AMDGPU::VGPRRegBank) 2346 break; 2347 2348 const LLT S32 = LLT::scalar(32); 2349 MachineBasicBlock *MBB = MI.getParent(); 2350 MachineFunction *MF = MBB->getParent(); 2351 MachineIRBuilder B(MI); 2352 ApplyRegBankMapping ApplySALU(*this, MRI, &AMDGPU::SGPRRegBank); 2353 GISelObserverWrapper Observer(&ApplySALU); 2354 2355 if (DstTy.isVector()) { 2356 B.setChangeObserver(Observer); 2357 2358 Register WideSrc0Lo, WideSrc0Hi; 2359 Register WideSrc1Lo, WideSrc1Hi; 2360 2361 std::tie(WideSrc0Lo, WideSrc0Hi) 2362 = unpackV2S16ToS32(B, MI.getOperand(1).getReg(), AMDGPU::G_ANYEXT); 2363 std::tie(WideSrc1Lo, WideSrc1Hi) 2364 = unpackV2S16ToS32(B, MI.getOperand(2).getReg(), AMDGPU::G_ANYEXT); 2365 auto Lo = B.buildInstr(MI.getOpcode(), {S32}, {WideSrc0Lo, WideSrc1Lo}); 2366 auto Hi = B.buildInstr(MI.getOpcode(), {S32}, {WideSrc0Hi, WideSrc1Hi}); 2367 B.buildBuildVectorTrunc(DstReg, {Lo.getReg(0), Hi.getReg(0)}); 2368 MI.eraseFromParent(); 2369 } else { 2370 LegalizerHelper Helper(*MF, Observer, B); 2371 2372 if (Helper.widenScalar(MI, 0, S32) != LegalizerHelper::Legalized) 2373 llvm_unreachable("widen scalar should have succeeded"); 2374 2375 // FIXME: s16 shift amounts should be legal. 2376 if (Opc == AMDGPU::G_SHL || Opc == AMDGPU::G_LSHR || 2377 Opc == AMDGPU::G_ASHR) { 2378 B.setInsertPt(*MBB, MI.getIterator()); 2379 if (Helper.widenScalar(MI, 1, S32) != LegalizerHelper::Legalized) 2380 llvm_unreachable("widen scalar should have succeeded"); 2381 } 2382 } 2383 2384 return; 2385 } 2386 case AMDGPU::G_SMIN: 2387 case AMDGPU::G_SMAX: 2388 case AMDGPU::G_UMIN: 2389 case AMDGPU::G_UMAX: { 2390 Register DstReg = MI.getOperand(0).getReg(); 2391 const RegisterBank *DstBank = 2392 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2393 if (DstBank == &AMDGPU::VGPRRegBank) 2394 break; 2395 2396 MachineFunction *MF = MI.getParent()->getParent(); 2397 MachineIRBuilder B(MI); 2398 2399 // Turn scalar min/max into a compare and select. 2400 LLT Ty = MRI.getType(DstReg); 2401 const LLT S32 = LLT::scalar(32); 2402 const LLT S16 = LLT::scalar(16); 2403 const LLT V2S16 = LLT::vector(2, 16); 2404 2405 if (Ty == V2S16) { 2406 ApplyRegBankMapping ApplySALU(*this, MRI, &AMDGPU::SGPRRegBank); 2407 GISelObserverWrapper Observer(&ApplySALU); 2408 B.setChangeObserver(Observer); 2409 2410 // Need to widen to s32, and expand as cmp + select, and avoid producing 2411 // illegal vector extends or unmerges that would need further 2412 // legalization. 2413 // 2414 // TODO: Should we just readfirstlane? That should probably be handled 2415 // with a UniformVGPR register bank that wouldn't need special 2416 // consideration here. 2417 2418 Register Dst = MI.getOperand(0).getReg(); 2419 Register Src0 = MI.getOperand(1).getReg(); 2420 Register Src1 = MI.getOperand(2).getReg(); 2421 2422 Register WideSrc0Lo, WideSrc0Hi; 2423 Register WideSrc1Lo, WideSrc1Hi; 2424 2425 unsigned ExtendOp = minMaxToExtend(MI.getOpcode()); 2426 2427 std::tie(WideSrc0Lo, WideSrc0Hi) = unpackV2S16ToS32(B, Src0, ExtendOp); 2428 std::tie(WideSrc1Lo, WideSrc1Hi) = unpackV2S16ToS32(B, Src1, ExtendOp); 2429 2430 Register Lo = MRI.createGenericVirtualRegister(S32); 2431 Register Hi = MRI.createGenericVirtualRegister(S32); 2432 const CmpInst::Predicate Pred = minMaxToCompare(MI.getOpcode()); 2433 buildExpandedScalarMinMax(B, Pred, Lo, WideSrc0Lo, WideSrc1Lo); 2434 buildExpandedScalarMinMax(B, Pred, Hi, WideSrc0Hi, WideSrc1Hi); 2435 2436 B.buildBuildVectorTrunc(Dst, {Lo, Hi}); 2437 MI.eraseFromParent(); 2438 } else if (Ty == S16) { 2439 ApplyRegBankMapping ApplySALU(*this, MRI, &AMDGPU::SGPRRegBank); 2440 GISelObserverWrapper Observer(&ApplySALU); 2441 LegalizerHelper Helper(*MF, Observer, B); 2442 2443 // Need to widen to s32, and expand as cmp + select. 2444 if (Helper.widenScalar(MI, 0, S32) != LegalizerHelper::Legalized) 2445 llvm_unreachable("widenScalar should have succeeded"); 2446 2447 // FIXME: This is relying on widenScalar leaving MI in place. 2448 lowerScalarMinMax(B, MI); 2449 } else 2450 lowerScalarMinMax(B, MI); 2451 2452 return; 2453 } 2454 case AMDGPU::G_SEXT_INREG: { 2455 SmallVector<Register, 2> SrcRegs(OpdMapper.getVRegs(1)); 2456 if (SrcRegs.empty()) 2457 break; // Nothing to repair 2458 2459 const LLT S32 = LLT::scalar(32); 2460 MachineIRBuilder B(MI); 2461 ApplyRegBankMapping O(*this, MRI, &AMDGPU::VGPRRegBank); 2462 GISelObserverWrapper Observer(&O); 2463 B.setChangeObserver(Observer); 2464 2465 // Don't use LegalizerHelper's narrowScalar. It produces unwanted G_SEXTs 2466 // we would need to further expand, and doesn't let us directly set the 2467 // result registers. 2468 SmallVector<Register, 2> DstRegs(OpdMapper.getVRegs(0)); 2469 2470 int Amt = MI.getOperand(2).getImm(); 2471 if (Amt <= 32) { 2472 if (Amt == 32) { 2473 // The low bits are unchanged. 2474 B.buildCopy(DstRegs[0], SrcRegs[0]); 2475 } else { 2476 // Extend in the low bits and propagate the sign bit to the high half. 2477 B.buildSExtInReg(DstRegs[0], SrcRegs[0], Amt); 2478 } 2479 2480 B.buildAShr(DstRegs[1], DstRegs[0], B.buildConstant(S32, 31)); 2481 } else { 2482 // The low bits are unchanged, and extend in the high bits. 2483 B.buildCopy(DstRegs[0], SrcRegs[0]); 2484 B.buildSExtInReg(DstRegs[1], DstRegs[0], Amt - 32); 2485 } 2486 2487 Register DstReg = MI.getOperand(0).getReg(); 2488 MRI.setRegBank(DstReg, AMDGPU::VGPRRegBank); 2489 MI.eraseFromParent(); 2490 return; 2491 } 2492 case AMDGPU::G_CTPOP: 2493 case AMDGPU::G_CTLZ_ZERO_UNDEF: 2494 case AMDGPU::G_CTTZ_ZERO_UNDEF: { 2495 MachineIRBuilder B(MI); 2496 MachineFunction &MF = B.getMF(); 2497 2498 const RegisterBank *DstBank = 2499 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2500 if (DstBank == &AMDGPU::SGPRRegBank) 2501 break; 2502 2503 Register SrcReg = MI.getOperand(1).getReg(); 2504 const LLT S32 = LLT::scalar(32); 2505 LLT Ty = MRI.getType(SrcReg); 2506 if (Ty == S32) 2507 break; 2508 2509 ApplyRegBankMapping ApplyVALU(*this, MRI, &AMDGPU::VGPRRegBank); 2510 GISelObserverWrapper Observer(&ApplyVALU); 2511 LegalizerHelper Helper(MF, Observer, B); 2512 2513 if (Helper.narrowScalar(MI, 1, S32) != LegalizerHelper::Legalized) 2514 llvm_unreachable("narrowScalar should have succeeded"); 2515 return; 2516 } 2517 case AMDGPU::G_SEXT: 2518 case AMDGPU::G_ZEXT: 2519 case AMDGPU::G_ANYEXT: { 2520 Register SrcReg = MI.getOperand(1).getReg(); 2521 LLT SrcTy = MRI.getType(SrcReg); 2522 const bool Signed = Opc == AMDGPU::G_SEXT; 2523 2524 assert(empty(OpdMapper.getVRegs(1))); 2525 2526 MachineIRBuilder B(MI); 2527 const RegisterBank *SrcBank = 2528 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 2529 2530 Register DstReg = MI.getOperand(0).getReg(); 2531 LLT DstTy = MRI.getType(DstReg); 2532 if (DstTy.isScalar() && 2533 SrcBank != &AMDGPU::SGPRRegBank && 2534 SrcBank != &AMDGPU::VCCRegBank && 2535 // FIXME: Should handle any type that round to s64 when irregular 2536 // breakdowns supported. 2537 DstTy.getSizeInBits() == 64 && 2538 SrcTy.getSizeInBits() <= 32) { 2539 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 2540 2541 // Extend to 32-bit, and then extend the low half. 2542 if (Signed) { 2543 // TODO: Should really be buildSExtOrCopy 2544 B.buildSExtOrTrunc(DefRegs[0], SrcReg); 2545 } else if (Opc == AMDGPU::G_ZEXT) { 2546 B.buildZExtOrTrunc(DefRegs[0], SrcReg); 2547 } else { 2548 B.buildAnyExtOrTrunc(DefRegs[0], SrcReg); 2549 } 2550 2551 extendLow32IntoHigh32(B, DefRegs[1], DefRegs[0], Opc, *SrcBank); 2552 MRI.setRegBank(DstReg, *SrcBank); 2553 MI.eraseFromParent(); 2554 return; 2555 } 2556 2557 if (SrcTy != LLT::scalar(1)) 2558 return; 2559 2560 // It is not legal to have a legalization artifact with a VCC source. Rather 2561 // than introducing a copy, insert the select we would have to select the 2562 // copy to. 2563 if (SrcBank == &AMDGPU::VCCRegBank) { 2564 SmallVector<Register, 2> DefRegs(OpdMapper.getVRegs(0)); 2565 2566 const RegisterBank *DstBank = &AMDGPU::VGPRRegBank; 2567 2568 unsigned DstSize = DstTy.getSizeInBits(); 2569 // 64-bit select is SGPR only 2570 const bool UseSel64 = DstSize > 32 && 2571 SrcBank->getID() == AMDGPU::SGPRRegBankID; 2572 2573 // TODO: Should s16 select be legal? 2574 LLT SelType = UseSel64 ? LLT::scalar(64) : LLT::scalar(32); 2575 auto True = B.buildConstant(SelType, Signed ? -1 : 1); 2576 auto False = B.buildConstant(SelType, 0); 2577 2578 MRI.setRegBank(True.getReg(0), *DstBank); 2579 MRI.setRegBank(False.getReg(0), *DstBank); 2580 MRI.setRegBank(DstReg, *DstBank); 2581 2582 if (DstSize > 32) { 2583 B.buildSelect(DefRegs[0], SrcReg, True, False); 2584 extendLow32IntoHigh32(B, DefRegs[1], DefRegs[0], Opc, *SrcBank, true); 2585 } else if (DstSize < 32) { 2586 auto Sel = B.buildSelect(SelType, SrcReg, True, False); 2587 MRI.setRegBank(Sel.getReg(0), *DstBank); 2588 B.buildTrunc(DstReg, Sel); 2589 } else { 2590 B.buildSelect(DstReg, SrcReg, True, False); 2591 } 2592 2593 MI.eraseFromParent(); 2594 return; 2595 } 2596 2597 break; 2598 } 2599 case AMDGPU::G_BUILD_VECTOR: 2600 case AMDGPU::G_BUILD_VECTOR_TRUNC: { 2601 Register DstReg = MI.getOperand(0).getReg(); 2602 LLT DstTy = MRI.getType(DstReg); 2603 if (DstTy != LLT::vector(2, 16)) 2604 break; 2605 2606 assert(MI.getNumOperands() == 3 && OpdMapper.getVRegs(0).empty()); 2607 substituteSimpleCopyRegs(OpdMapper, 1); 2608 substituteSimpleCopyRegs(OpdMapper, 2); 2609 2610 const RegisterBank *DstBank = 2611 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2612 if (DstBank == &AMDGPU::SGPRRegBank) 2613 break; // Can use S_PACK_* instructions. 2614 2615 MachineIRBuilder B(MI); 2616 2617 Register Lo = MI.getOperand(1).getReg(); 2618 Register Hi = MI.getOperand(2).getReg(); 2619 const LLT S32 = LLT::scalar(32); 2620 2621 const RegisterBank *BankLo = 2622 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 2623 const RegisterBank *BankHi = 2624 OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 2625 2626 Register ZextLo; 2627 Register ShiftHi; 2628 2629 if (Opc == AMDGPU::G_BUILD_VECTOR) { 2630 ZextLo = B.buildZExt(S32, Lo).getReg(0); 2631 MRI.setRegBank(ZextLo, *BankLo); 2632 2633 Register ZextHi = B.buildZExt(S32, Hi).getReg(0); 2634 MRI.setRegBank(ZextHi, *BankHi); 2635 2636 auto ShiftAmt = B.buildConstant(S32, 16); 2637 MRI.setRegBank(ShiftAmt.getReg(0), *BankHi); 2638 2639 ShiftHi = B.buildShl(S32, ZextHi, ShiftAmt).getReg(0); 2640 MRI.setRegBank(ShiftHi, *BankHi); 2641 } else { 2642 Register MaskLo = B.buildConstant(S32, 0xffff).getReg(0); 2643 MRI.setRegBank(MaskLo, *BankLo); 2644 2645 auto ShiftAmt = B.buildConstant(S32, 16); 2646 MRI.setRegBank(ShiftAmt.getReg(0), *BankHi); 2647 2648 ShiftHi = B.buildShl(S32, Hi, ShiftAmt).getReg(0); 2649 MRI.setRegBank(ShiftHi, *BankHi); 2650 2651 ZextLo = B.buildAnd(S32, Lo, MaskLo).getReg(0); 2652 MRI.setRegBank(ZextLo, *BankLo); 2653 } 2654 2655 auto Or = B.buildOr(S32, ZextLo, ShiftHi); 2656 MRI.setRegBank(Or.getReg(0), *DstBank); 2657 2658 B.buildBitcast(DstReg, Or); 2659 MI.eraseFromParent(); 2660 return; 2661 } 2662 case AMDGPU::G_EXTRACT_VECTOR_ELT: { 2663 SmallVector<Register, 2> DstRegs(OpdMapper.getVRegs(0)); 2664 2665 assert(OpdMapper.getVRegs(1).empty() && OpdMapper.getVRegs(2).empty()); 2666 2667 Register DstReg = MI.getOperand(0).getReg(); 2668 Register SrcReg = MI.getOperand(1).getReg(); 2669 2670 const LLT S32 = LLT::scalar(32); 2671 LLT DstTy = MRI.getType(DstReg); 2672 LLT SrcTy = MRI.getType(SrcReg); 2673 2674 if (foldExtractEltToCmpSelect(MI, MRI, OpdMapper)) 2675 return; 2676 2677 MachineIRBuilder B(MI); 2678 2679 const ValueMapping &DstMapping 2680 = OpdMapper.getInstrMapping().getOperandMapping(0); 2681 const RegisterBank *DstBank = DstMapping.BreakDown[0].RegBank; 2682 const RegisterBank *SrcBank = 2683 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 2684 const RegisterBank *IdxBank = 2685 OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 2686 2687 Register BaseIdxReg; 2688 unsigned ConstOffset; 2689 MachineInstr *OffsetDef; 2690 std::tie(BaseIdxReg, ConstOffset, OffsetDef) = 2691 AMDGPU::getBaseWithConstantOffset(MRI, MI.getOperand(2).getReg()); 2692 2693 // See if the index is an add of a constant which will be foldable by moving 2694 // the base register of the index later if this is going to be executed in a 2695 // waterfall loop. This is essentially to reassociate the add of a constant 2696 // with the readfirstlane. 2697 bool ShouldMoveIndexIntoLoop = IdxBank != &AMDGPU::SGPRRegBank && 2698 ConstOffset > 0 && 2699 ConstOffset < SrcTy.getNumElements(); 2700 2701 // Move the base register. We'll re-insert the add later. 2702 if (ShouldMoveIndexIntoLoop) 2703 MI.getOperand(2).setReg(BaseIdxReg); 2704 2705 // If this is a VGPR result only because the index was a VGPR result, the 2706 // actual indexing will be done on the SGPR source vector, which will 2707 // produce a scalar result. We need to copy to the VGPR result inside the 2708 // waterfall loop. 2709 const bool NeedCopyToVGPR = DstBank == &AMDGPU::VGPRRegBank && 2710 SrcBank == &AMDGPU::SGPRRegBank; 2711 if (DstRegs.empty()) { 2712 applyDefaultMapping(OpdMapper); 2713 2714 executeInWaterfallLoop(MI, MRI, { 2 }); 2715 2716 if (NeedCopyToVGPR) { 2717 // We don't want a phi for this temporary reg. 2718 Register TmpReg = MRI.createGenericVirtualRegister(DstTy); 2719 MRI.setRegBank(TmpReg, AMDGPU::SGPRRegBank); 2720 MI.getOperand(0).setReg(TmpReg); 2721 B.setInsertPt(*MI.getParent(), ++MI.getIterator()); 2722 2723 // Use a v_mov_b32 here to make the exec dependency explicit. 2724 buildVCopy(B, DstReg, TmpReg); 2725 } 2726 2727 // Re-insert the constant offset add inside the waterfall loop. 2728 if (ShouldMoveIndexIntoLoop) 2729 reinsertVectorIndexAdd(B, MI, 2, ConstOffset); 2730 2731 return; 2732 } 2733 2734 assert(DstTy.getSizeInBits() == 64); 2735 2736 LLT Vec32 = LLT::vector(2 * SrcTy.getNumElements(), 32); 2737 2738 auto CastSrc = B.buildBitcast(Vec32, SrcReg); 2739 auto One = B.buildConstant(S32, 1); 2740 2741 MachineBasicBlock::iterator MII = MI.getIterator(); 2742 2743 // Split the vector index into 32-bit pieces. Prepare to move all of the 2744 // new instructions into a waterfall loop if necessary. 2745 // 2746 // Don't put the bitcast or constant in the loop. 2747 MachineInstrSpan Span(MII, &B.getMBB()); 2748 2749 // Compute 32-bit element indices, (2 * OrigIdx, 2 * OrigIdx + 1). 2750 auto IdxLo = B.buildShl(S32, BaseIdxReg, One); 2751 auto IdxHi = B.buildAdd(S32, IdxLo, One); 2752 2753 auto Extract0 = B.buildExtractVectorElement(DstRegs[0], CastSrc, IdxLo); 2754 auto Extract1 = B.buildExtractVectorElement(DstRegs[1], CastSrc, IdxHi); 2755 2756 MRI.setRegBank(DstReg, *DstBank); 2757 MRI.setRegBank(CastSrc.getReg(0), *SrcBank); 2758 MRI.setRegBank(One.getReg(0), AMDGPU::SGPRRegBank); 2759 MRI.setRegBank(IdxLo.getReg(0), AMDGPU::SGPRRegBank); 2760 MRI.setRegBank(IdxHi.getReg(0), AMDGPU::SGPRRegBank); 2761 2762 SmallSet<Register, 4> OpsToWaterfall; 2763 if (!collectWaterfallOperands(OpsToWaterfall, MI, MRI, { 2 })) { 2764 MI.eraseFromParent(); 2765 return; 2766 } 2767 2768 // Remove the original instruction to avoid potentially confusing the 2769 // waterfall loop logic. 2770 B.setInstr(*Span.begin()); 2771 MI.eraseFromParent(); 2772 executeInWaterfallLoop(B, make_range(Span.begin(), Span.end()), 2773 OpsToWaterfall, MRI); 2774 2775 if (NeedCopyToVGPR) { 2776 MachineBasicBlock *LoopBB = Extract1->getParent(); 2777 Register TmpReg0 = MRI.createGenericVirtualRegister(S32); 2778 Register TmpReg1 = MRI.createGenericVirtualRegister(S32); 2779 MRI.setRegBank(TmpReg0, AMDGPU::SGPRRegBank); 2780 MRI.setRegBank(TmpReg1, AMDGPU::SGPRRegBank); 2781 2782 Extract0->getOperand(0).setReg(TmpReg0); 2783 Extract1->getOperand(0).setReg(TmpReg1); 2784 2785 B.setInsertPt(*LoopBB, ++Extract1->getIterator()); 2786 2787 buildVCopy(B, DstRegs[0], TmpReg0); 2788 buildVCopy(B, DstRegs[1], TmpReg1); 2789 } 2790 2791 if (ShouldMoveIndexIntoLoop) 2792 reinsertVectorIndexAdd(B, *IdxLo, 1, ConstOffset); 2793 2794 return; 2795 } 2796 case AMDGPU::G_INSERT_VECTOR_ELT: { 2797 SmallVector<Register, 2> InsRegs(OpdMapper.getVRegs(2)); 2798 2799 Register DstReg = MI.getOperand(0).getReg(); 2800 LLT VecTy = MRI.getType(DstReg); 2801 2802 assert(OpdMapper.getVRegs(0).empty()); 2803 assert(OpdMapper.getVRegs(3).empty()); 2804 2805 if (substituteSimpleCopyRegs(OpdMapper, 1)) 2806 MRI.setType(MI.getOperand(1).getReg(), VecTy); 2807 2808 if (foldInsertEltToCmpSelect(MI, MRI, OpdMapper)) 2809 return; 2810 2811 const RegisterBank *IdxBank = 2812 OpdMapper.getInstrMapping().getOperandMapping(3).BreakDown[0].RegBank; 2813 2814 Register SrcReg = MI.getOperand(1).getReg(); 2815 Register InsReg = MI.getOperand(2).getReg(); 2816 LLT InsTy = MRI.getType(InsReg); 2817 (void)InsTy; 2818 2819 Register BaseIdxReg; 2820 unsigned ConstOffset; 2821 MachineInstr *OffsetDef; 2822 std::tie(BaseIdxReg, ConstOffset, OffsetDef) = 2823 AMDGPU::getBaseWithConstantOffset(MRI, MI.getOperand(3).getReg()); 2824 2825 // See if the index is an add of a constant which will be foldable by moving 2826 // the base register of the index later if this is going to be executed in a 2827 // waterfall loop. This is essentially to reassociate the add of a constant 2828 // with the readfirstlane. 2829 bool ShouldMoveIndexIntoLoop = IdxBank != &AMDGPU::SGPRRegBank && 2830 ConstOffset > 0 && 2831 ConstOffset < VecTy.getNumElements(); 2832 2833 // Move the base register. We'll re-insert the add later. 2834 if (ShouldMoveIndexIntoLoop) 2835 MI.getOperand(3).setReg(BaseIdxReg); 2836 2837 2838 if (InsRegs.empty()) { 2839 executeInWaterfallLoop(MI, MRI, { 3 }); 2840 2841 // Re-insert the constant offset add inside the waterfall loop. 2842 if (ShouldMoveIndexIntoLoop) { 2843 MachineIRBuilder B(MI); 2844 reinsertVectorIndexAdd(B, MI, 3, ConstOffset); 2845 } 2846 2847 return; 2848 } 2849 2850 2851 assert(InsTy.getSizeInBits() == 64); 2852 2853 const LLT S32 = LLT::scalar(32); 2854 LLT Vec32 = LLT::vector(2 * VecTy.getNumElements(), 32); 2855 2856 MachineIRBuilder B(MI); 2857 auto CastSrc = B.buildBitcast(Vec32, SrcReg); 2858 auto One = B.buildConstant(S32, 1); 2859 2860 // Split the vector index into 32-bit pieces. Prepare to move all of the 2861 // new instructions into a waterfall loop if necessary. 2862 // 2863 // Don't put the bitcast or constant in the loop. 2864 MachineInstrSpan Span(MachineBasicBlock::iterator(&MI), &B.getMBB()); 2865 2866 // Compute 32-bit element indices, (2 * OrigIdx, 2 * OrigIdx + 1). 2867 auto IdxLo = B.buildShl(S32, BaseIdxReg, One); 2868 auto IdxHi = B.buildAdd(S32, IdxLo, One); 2869 2870 auto InsLo = B.buildInsertVectorElement(Vec32, CastSrc, InsRegs[0], IdxLo); 2871 auto InsHi = B.buildInsertVectorElement(Vec32, InsLo, InsRegs[1], IdxHi); 2872 2873 const RegisterBank *DstBank = 2874 OpdMapper.getInstrMapping().getOperandMapping(0).BreakDown[0].RegBank; 2875 const RegisterBank *SrcBank = 2876 OpdMapper.getInstrMapping().getOperandMapping(1).BreakDown[0].RegBank; 2877 const RegisterBank *InsSrcBank = 2878 OpdMapper.getInstrMapping().getOperandMapping(2).BreakDown[0].RegBank; 2879 2880 MRI.setRegBank(InsReg, *InsSrcBank); 2881 MRI.setRegBank(CastSrc.getReg(0), *SrcBank); 2882 MRI.setRegBank(InsLo.getReg(0), *DstBank); 2883 MRI.setRegBank(InsHi.getReg(0), *DstBank); 2884 MRI.setRegBank(One.getReg(0), AMDGPU::SGPRRegBank); 2885 MRI.setRegBank(IdxLo.getReg(0), AMDGPU::SGPRRegBank); 2886 MRI.setRegBank(IdxHi.getReg(0), AMDGPU::SGPRRegBank); 2887 2888 2889 SmallSet<Register, 4> OpsToWaterfall; 2890 if (!collectWaterfallOperands(OpsToWaterfall, MI, MRI, { 3 })) { 2891 B.setInsertPt(B.getMBB(), MI); 2892 B.buildBitcast(DstReg, InsHi); 2893 MI.eraseFromParent(); 2894 return; 2895 } 2896 2897 B.setInstr(*Span.begin()); 2898 MI.eraseFromParent(); 2899 2900 // Figure out the point after the waterfall loop before mangling the control 2901 // flow. 2902 executeInWaterfallLoop(B, make_range(Span.begin(), Span.end()), 2903 OpsToWaterfall, MRI); 2904 2905 // The insertion point is now right after the original instruction. 2906 // 2907 // Keep the bitcast to the original vector type out of the loop. Doing this 2908 // saved an extra phi we don't need inside the loop. 2909 B.buildBitcast(DstReg, InsHi); 2910 2911 // Re-insert the constant offset add inside the waterfall loop. 2912 if (ShouldMoveIndexIntoLoop) 2913 reinsertVectorIndexAdd(B, *IdxLo, 1, ConstOffset); 2914 2915 return; 2916 } 2917 case AMDGPU::G_AMDGPU_BUFFER_LOAD: 2918 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT: 2919 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT: 2920 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE: 2921 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE: 2922 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT: 2923 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT_D16: 2924 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT: 2925 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT_D16: 2926 case AMDGPU::G_AMDGPU_BUFFER_STORE: 2927 case AMDGPU::G_AMDGPU_BUFFER_STORE_BYTE: 2928 case AMDGPU::G_AMDGPU_BUFFER_STORE_SHORT: 2929 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT: 2930 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT_D16: 2931 case AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT: 2932 case AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT_D16: { 2933 applyDefaultMapping(OpdMapper); 2934 executeInWaterfallLoop(MI, MRI, {1, 4}); 2935 return; 2936 } 2937 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SWAP: 2938 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_ADD: 2939 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SUB: 2940 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMIN: 2941 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMIN: 2942 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMAX: 2943 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMAX: 2944 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_AND: 2945 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_OR: 2946 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_XOR: 2947 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_INC: 2948 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_DEC: { 2949 applyDefaultMapping(OpdMapper); 2950 executeInWaterfallLoop(MI, MRI, {2, 5}); 2951 return; 2952 } 2953 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FADD: { 2954 applyDefaultMapping(OpdMapper); 2955 executeInWaterfallLoop(MI, MRI, {1, 4}); 2956 return; 2957 } 2958 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_CMPSWAP: { 2959 applyDefaultMapping(OpdMapper); 2960 executeInWaterfallLoop(MI, MRI, {3, 6}); 2961 return; 2962 } 2963 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD: { 2964 applyMappingSBufferLoad(OpdMapper); 2965 return; 2966 } 2967 case AMDGPU::G_INTRINSIC: { 2968 switch (MI.getIntrinsicID()) { 2969 case Intrinsic::amdgcn_readlane: { 2970 substituteSimpleCopyRegs(OpdMapper, 2); 2971 2972 assert(OpdMapper.getVRegs(0).empty()); 2973 assert(OpdMapper.getVRegs(3).empty()); 2974 2975 // Make sure the index is an SGPR. It doesn't make sense to run this in a 2976 // waterfall loop, so assume it's a uniform value. 2977 constrainOpWithReadfirstlane(MI, MRI, 3); // Index 2978 return; 2979 } 2980 case Intrinsic::amdgcn_writelane: { 2981 assert(OpdMapper.getVRegs(0).empty()); 2982 assert(OpdMapper.getVRegs(2).empty()); 2983 assert(OpdMapper.getVRegs(3).empty()); 2984 2985 substituteSimpleCopyRegs(OpdMapper, 4); // VGPR input val 2986 constrainOpWithReadfirstlane(MI, MRI, 2); // Source value 2987 constrainOpWithReadfirstlane(MI, MRI, 3); // Index 2988 return; 2989 } 2990 case Intrinsic::amdgcn_interp_p1: 2991 case Intrinsic::amdgcn_interp_p2: 2992 case Intrinsic::amdgcn_interp_mov: 2993 case Intrinsic::amdgcn_interp_p1_f16: 2994 case Intrinsic::amdgcn_interp_p2_f16: { 2995 applyDefaultMapping(OpdMapper); 2996 2997 // Readlane for m0 value, which is always the last operand. 2998 // FIXME: Should this be a waterfall loop instead? 2999 constrainOpWithReadfirstlane(MI, MRI, MI.getNumOperands() - 1); // Index 3000 return; 3001 } 3002 case Intrinsic::amdgcn_permlane16: 3003 case Intrinsic::amdgcn_permlanex16: { 3004 // Doing a waterfall loop over these wouldn't make any sense. 3005 substituteSimpleCopyRegs(OpdMapper, 2); 3006 substituteSimpleCopyRegs(OpdMapper, 3); 3007 constrainOpWithReadfirstlane(MI, MRI, 4); 3008 constrainOpWithReadfirstlane(MI, MRI, 5); 3009 return; 3010 } 3011 case Intrinsic::amdgcn_sbfe: 3012 applyMappingBFEIntrinsic(OpdMapper, true); 3013 return; 3014 case Intrinsic::amdgcn_ubfe: 3015 applyMappingBFEIntrinsic(OpdMapper, false); 3016 return; 3017 case Intrinsic::amdgcn_ballot: 3018 // Use default handling and insert copy to vcc source. 3019 break; 3020 } 3021 break; 3022 } 3023 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD: 3024 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE: { 3025 const AMDGPU::RsrcIntrinsic *RSrcIntrin 3026 = AMDGPU::lookupRsrcIntrinsic(MI.getIntrinsicID()); 3027 assert(RSrcIntrin && RSrcIntrin->IsImage); 3028 // Non-images can have complications from operands that allow both SGPR 3029 // and VGPR. For now it's too complicated to figure out the final opcode 3030 // to derive the register bank from the MCInstrDesc. 3031 applyMappingImage(MI, OpdMapper, MRI, RSrcIntrin->RsrcArg); 3032 return; 3033 } 3034 case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: { 3035 auto IntrID = MI.getIntrinsicID(); 3036 switch (IntrID) { 3037 case Intrinsic::amdgcn_ds_ordered_add: 3038 case Intrinsic::amdgcn_ds_ordered_swap: { 3039 // This is only allowed to execute with 1 lane, so readfirstlane is safe. 3040 assert(OpdMapper.getVRegs(0).empty()); 3041 substituteSimpleCopyRegs(OpdMapper, 3); 3042 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 3043 return; 3044 } 3045 case Intrinsic::amdgcn_ds_gws_init: 3046 case Intrinsic::amdgcn_ds_gws_barrier: 3047 case Intrinsic::amdgcn_ds_gws_sema_br: { 3048 // Only the first lane is executes, so readfirstlane is safe. 3049 substituteSimpleCopyRegs(OpdMapper, 1); 3050 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 3051 return; 3052 } 3053 case Intrinsic::amdgcn_ds_gws_sema_v: 3054 case Intrinsic::amdgcn_ds_gws_sema_p: 3055 case Intrinsic::amdgcn_ds_gws_sema_release_all: { 3056 // Only the first lane is executes, so readfirstlane is safe. 3057 constrainOpWithReadfirstlane(MI, MRI, 1); // M0 3058 return; 3059 } 3060 case Intrinsic::amdgcn_ds_append: 3061 case Intrinsic::amdgcn_ds_consume: { 3062 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 3063 return; 3064 } 3065 case Intrinsic::amdgcn_s_sendmsg: 3066 case Intrinsic::amdgcn_s_sendmsghalt: { 3067 // FIXME: Should this use a waterfall loop? 3068 constrainOpWithReadfirstlane(MI, MRI, 2); // M0 3069 return; 3070 } 3071 case Intrinsic::amdgcn_s_setreg: { 3072 constrainOpWithReadfirstlane(MI, MRI, 2); 3073 return; 3074 } 3075 default: { 3076 if (const AMDGPU::RsrcIntrinsic *RSrcIntrin = 3077 AMDGPU::lookupRsrcIntrinsic(IntrID)) { 3078 // Non-images can have complications from operands that allow both SGPR 3079 // and VGPR. For now it's too complicated to figure out the final opcode 3080 // to derive the register bank from the MCInstrDesc. 3081 if (RSrcIntrin->IsImage) { 3082 applyMappingImage(MI, OpdMapper, MRI, RSrcIntrin->RsrcArg); 3083 return; 3084 } 3085 } 3086 3087 break; 3088 } 3089 } 3090 break; 3091 } 3092 case AMDGPU::G_LOAD: 3093 case AMDGPU::G_ZEXTLOAD: 3094 case AMDGPU::G_SEXTLOAD: { 3095 if (applyMappingLoad(MI, OpdMapper, MRI)) 3096 return; 3097 break; 3098 } 3099 case AMDGPU::G_DYN_STACKALLOC: 3100 applyMappingDynStackAlloc(MI, OpdMapper, MRI); 3101 return; 3102 default: 3103 break; 3104 } 3105 3106 return applyDefaultMapping(OpdMapper); 3107 } 3108 3109 // vgpr, sgpr -> vgpr 3110 // vgpr, agpr -> vgpr 3111 // agpr, agpr -> agpr 3112 // agpr, sgpr -> vgpr 3113 static unsigned regBankUnion(unsigned RB0, unsigned RB1) { 3114 if (RB0 == AMDGPU::InvalidRegBankID) 3115 return RB1; 3116 if (RB1 == AMDGPU::InvalidRegBankID) 3117 return RB0; 3118 3119 if (RB0 == AMDGPU::SGPRRegBankID && RB1 == AMDGPU::SGPRRegBankID) 3120 return AMDGPU::SGPRRegBankID; 3121 3122 if (RB0 == AMDGPU::AGPRRegBankID && RB1 == AMDGPU::AGPRRegBankID) 3123 return AMDGPU::AGPRRegBankID; 3124 3125 return AMDGPU::VGPRRegBankID; 3126 } 3127 3128 static unsigned regBankBoolUnion(unsigned RB0, unsigned RB1) { 3129 if (RB0 == AMDGPU::InvalidRegBankID) 3130 return RB1; 3131 if (RB1 == AMDGPU::InvalidRegBankID) 3132 return RB0; 3133 3134 // vcc, vcc -> vcc 3135 // vcc, sgpr -> vcc 3136 // vcc, vgpr -> vcc 3137 if (RB0 == AMDGPU::VCCRegBankID || RB1 == AMDGPU::VCCRegBankID) 3138 return AMDGPU::VCCRegBankID; 3139 3140 // vcc, vgpr -> vgpr 3141 return regBankUnion(RB0, RB1); 3142 } 3143 3144 unsigned AMDGPURegisterBankInfo::getMappingType(const MachineRegisterInfo &MRI, 3145 const MachineInstr &MI) const { 3146 unsigned RegBank = AMDGPU::InvalidRegBankID; 3147 3148 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 3149 if (!MI.getOperand(i).isReg()) 3150 continue; 3151 Register Reg = MI.getOperand(i).getReg(); 3152 if (const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI)) { 3153 RegBank = regBankUnion(RegBank, Bank->getID()); 3154 if (RegBank == AMDGPU::VGPRRegBankID) 3155 break; 3156 } 3157 } 3158 3159 return RegBank; 3160 } 3161 3162 bool AMDGPURegisterBankInfo::isSALUMapping(const MachineInstr &MI) const { 3163 const MachineFunction &MF = *MI.getParent()->getParent(); 3164 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3165 for (unsigned i = 0, e = MI.getNumOperands();i != e; ++i) { 3166 if (!MI.getOperand(i).isReg()) 3167 continue; 3168 Register Reg = MI.getOperand(i).getReg(); 3169 if (const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI)) { 3170 if (Bank->getID() != AMDGPU::SGPRRegBankID) 3171 return false; 3172 } 3173 } 3174 return true; 3175 } 3176 3177 const RegisterBankInfo::InstructionMapping & 3178 AMDGPURegisterBankInfo::getDefaultMappingSOP(const MachineInstr &MI) const { 3179 const MachineFunction &MF = *MI.getParent()->getParent(); 3180 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3181 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 3182 3183 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 3184 const MachineOperand &SrcOp = MI.getOperand(i); 3185 if (!SrcOp.isReg()) 3186 continue; 3187 3188 unsigned Size = getSizeInBits(SrcOp.getReg(), MRI, *TRI); 3189 OpdsMapping[i] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3190 } 3191 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), 3192 MI.getNumOperands()); 3193 } 3194 3195 const RegisterBankInfo::InstructionMapping & 3196 AMDGPURegisterBankInfo::getDefaultMappingVOP(const MachineInstr &MI) const { 3197 const MachineFunction &MF = *MI.getParent()->getParent(); 3198 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3199 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 3200 3201 // Even though we technically could use SGPRs, this would require knowledge of 3202 // the constant bus restriction. Force all sources to VGPR (except for VCC). 3203 // 3204 // TODO: Unary ops are trivially OK, so accept SGPRs? 3205 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 3206 const MachineOperand &Src = MI.getOperand(i); 3207 if (!Src.isReg()) 3208 continue; 3209 3210 unsigned Size = getSizeInBits(Src.getReg(), MRI, *TRI); 3211 unsigned BankID = Size == 1 ? AMDGPU::VCCRegBankID : AMDGPU::VGPRRegBankID; 3212 OpdsMapping[i] = AMDGPU::getValueMapping(BankID, Size); 3213 } 3214 3215 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), 3216 MI.getNumOperands()); 3217 } 3218 3219 const RegisterBankInfo::InstructionMapping & 3220 AMDGPURegisterBankInfo::getDefaultMappingAllVGPR(const MachineInstr &MI) const { 3221 const MachineFunction &MF = *MI.getParent()->getParent(); 3222 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3223 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 3224 3225 for (unsigned I = 0, E = MI.getNumOperands(); I != E; ++I) { 3226 const MachineOperand &Op = MI.getOperand(I); 3227 if (!Op.isReg()) 3228 continue; 3229 3230 unsigned Size = getSizeInBits(Op.getReg(), MRI, *TRI); 3231 OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3232 } 3233 3234 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), 3235 MI.getNumOperands()); 3236 } 3237 3238 const RegisterBankInfo::InstructionMapping & 3239 AMDGPURegisterBankInfo::getImageMapping(const MachineRegisterInfo &MRI, 3240 const MachineInstr &MI, 3241 int RsrcIdx) const { 3242 // The reported argument index is relative to the IR intrinsic call arguments, 3243 // so we need to shift by the number of defs and the intrinsic ID. 3244 RsrcIdx += MI.getNumExplicitDefs() + 1; 3245 3246 const int NumOps = MI.getNumOperands(); 3247 SmallVector<const ValueMapping *, 8> OpdsMapping(NumOps); 3248 3249 // TODO: Should packed/unpacked D16 difference be reported here as part of 3250 // the value mapping? 3251 for (int I = 0; I != NumOps; ++I) { 3252 if (!MI.getOperand(I).isReg()) 3253 continue; 3254 3255 Register OpReg = MI.getOperand(I).getReg(); 3256 // We replace some dead address operands with $noreg 3257 if (!OpReg) 3258 continue; 3259 3260 unsigned Size = getSizeInBits(OpReg, MRI, *TRI); 3261 3262 // FIXME: Probably need a new intrinsic register bank searchable table to 3263 // handle arbitrary intrinsics easily. 3264 // 3265 // If this has a sampler, it immediately follows rsrc. 3266 const bool MustBeSGPR = I == RsrcIdx || I == RsrcIdx + 1; 3267 3268 if (MustBeSGPR) { 3269 // If this must be an SGPR, so we must report whatever it is as legal. 3270 unsigned NewBank = getRegBankID(OpReg, MRI, AMDGPU::SGPRRegBankID); 3271 OpdsMapping[I] = AMDGPU::getValueMapping(NewBank, Size); 3272 } else { 3273 // Some operands must be VGPR, and these are easy to copy to. 3274 OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3275 } 3276 } 3277 3278 return getInstructionMapping(1, 1, getOperandsMapping(OpdsMapping), NumOps); 3279 } 3280 3281 /// Return the mapping for a pointer arugment. 3282 const RegisterBankInfo::ValueMapping * 3283 AMDGPURegisterBankInfo::getValueMappingForPtr(const MachineRegisterInfo &MRI, 3284 Register PtrReg) const { 3285 LLT PtrTy = MRI.getType(PtrReg); 3286 unsigned Size = PtrTy.getSizeInBits(); 3287 if (Subtarget.useFlatForGlobal() || 3288 !AMDGPU::isFlatGlobalAddrSpace(PtrTy.getAddressSpace())) 3289 return AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3290 3291 // If we're using MUBUF instructions for global memory, an SGPR base register 3292 // is possible. Otherwise this needs to be a VGPR. 3293 const RegisterBank *PtrBank = getRegBank(PtrReg, MRI, *TRI); 3294 return AMDGPU::getValueMapping(PtrBank->getID(), Size); 3295 } 3296 3297 const RegisterBankInfo::InstructionMapping & 3298 AMDGPURegisterBankInfo::getInstrMappingForLoad(const MachineInstr &MI) const { 3299 3300 const MachineFunction &MF = *MI.getParent()->getParent(); 3301 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3302 SmallVector<const ValueMapping*, 2> OpdsMapping(2); 3303 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3304 Register PtrReg = MI.getOperand(1).getReg(); 3305 LLT PtrTy = MRI.getType(PtrReg); 3306 unsigned AS = PtrTy.getAddressSpace(); 3307 unsigned PtrSize = PtrTy.getSizeInBits(); 3308 3309 const ValueMapping *ValMapping; 3310 const ValueMapping *PtrMapping; 3311 3312 const RegisterBank *PtrBank = getRegBank(PtrReg, MRI, *TRI); 3313 3314 if (PtrBank == &AMDGPU::SGPRRegBank && AMDGPU::isFlatGlobalAddrSpace(AS)) { 3315 if (isScalarLoadLegal(MI)) { 3316 // We have a uniform instruction so we want to use an SMRD load 3317 ValMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3318 PtrMapping = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, PtrSize); 3319 } else { 3320 ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3321 3322 // If we're using MUBUF instructions for global memory, an SGPR base 3323 // register is possible. Otherwise this needs to be a VGPR. 3324 unsigned PtrBankID = Subtarget.useFlatForGlobal() ? 3325 AMDGPU::VGPRRegBankID : AMDGPU::SGPRRegBankID; 3326 3327 PtrMapping = AMDGPU::getValueMapping(PtrBankID, PtrSize); 3328 } 3329 } else { 3330 ValMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3331 PtrMapping = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, PtrSize); 3332 } 3333 3334 OpdsMapping[0] = ValMapping; 3335 OpdsMapping[1] = PtrMapping; 3336 const RegisterBankInfo::InstructionMapping &Mapping = getInstructionMapping( 3337 1, 1, getOperandsMapping(OpdsMapping), MI.getNumOperands()); 3338 return Mapping; 3339 3340 // FIXME: Do we want to add a mapping for FLAT load, or should we just 3341 // handle that during instruction selection? 3342 } 3343 3344 unsigned 3345 AMDGPURegisterBankInfo::getRegBankID(Register Reg, 3346 const MachineRegisterInfo &MRI, 3347 unsigned Default) const { 3348 const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI); 3349 return Bank ? Bank->getID() : Default; 3350 } 3351 3352 const RegisterBankInfo::ValueMapping * 3353 AMDGPURegisterBankInfo::getSGPROpMapping(Register Reg, 3354 const MachineRegisterInfo &MRI, 3355 const TargetRegisterInfo &TRI) const { 3356 // Lie and claim anything is legal, even though this needs to be an SGPR 3357 // applyMapping will have to deal with it as a waterfall loop. 3358 unsigned Bank = getRegBankID(Reg, MRI, AMDGPU::SGPRRegBankID); 3359 unsigned Size = getSizeInBits(Reg, MRI, TRI); 3360 return AMDGPU::getValueMapping(Bank, Size); 3361 } 3362 3363 const RegisterBankInfo::ValueMapping * 3364 AMDGPURegisterBankInfo::getVGPROpMapping(Register Reg, 3365 const MachineRegisterInfo &MRI, 3366 const TargetRegisterInfo &TRI) const { 3367 unsigned Size = getSizeInBits(Reg, MRI, TRI); 3368 return AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3369 } 3370 3371 const RegisterBankInfo::ValueMapping * 3372 AMDGPURegisterBankInfo::getAGPROpMapping(Register Reg, 3373 const MachineRegisterInfo &MRI, 3374 const TargetRegisterInfo &TRI) const { 3375 unsigned Size = getSizeInBits(Reg, MRI, TRI); 3376 return AMDGPU::getValueMapping(AMDGPU::AGPRRegBankID, Size); 3377 } 3378 3379 /// 3380 /// This function must return a legal mapping, because 3381 /// AMDGPURegisterBankInfo::getInstrAlternativeMappings() is not called 3382 /// in RegBankSelect::Mode::Fast. Any mapping that would cause a 3383 /// VGPR to SGPR generated is illegal. 3384 /// 3385 // Operands that must be SGPRs must accept potentially divergent VGPRs as 3386 // legal. These will be dealt with in applyMappingImpl. 3387 // 3388 const RegisterBankInfo::InstructionMapping & 3389 AMDGPURegisterBankInfo::getInstrMapping(const MachineInstr &MI) const { 3390 const MachineFunction &MF = *MI.getParent()->getParent(); 3391 const MachineRegisterInfo &MRI = MF.getRegInfo(); 3392 3393 if (MI.isCopy() || MI.getOpcode() == AMDGPU::G_FREEZE) { 3394 // The default logic bothers to analyze impossible alternative mappings. We 3395 // want the most straightforward mapping, so just directly handle this. 3396 const RegisterBank *DstBank = getRegBank(MI.getOperand(0).getReg(), MRI, 3397 *TRI); 3398 const RegisterBank *SrcBank = getRegBank(MI.getOperand(1).getReg(), MRI, 3399 *TRI); 3400 assert(SrcBank && "src bank should have been assigned already"); 3401 if (!DstBank) 3402 DstBank = SrcBank; 3403 3404 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3405 if (cannotCopy(*DstBank, *SrcBank, Size)) 3406 return getInvalidInstructionMapping(); 3407 3408 const ValueMapping &ValMap = getValueMapping(0, Size, *DstBank); 3409 unsigned OpdsMappingSize = MI.isCopy() ? 1 : 2; 3410 SmallVector<const ValueMapping *, 1> OpdsMapping(OpdsMappingSize); 3411 OpdsMapping[0] = &ValMap; 3412 if (MI.getOpcode() == AMDGPU::G_FREEZE) 3413 OpdsMapping[1] = &ValMap; 3414 3415 return getInstructionMapping( 3416 1, /*Cost*/ 1, 3417 /*OperandsMapping*/ getOperandsMapping(OpdsMapping), OpdsMappingSize); 3418 } 3419 3420 if (MI.isRegSequence()) { 3421 // If any input is a VGPR, the result must be a VGPR. The default handling 3422 // assumes any copy between banks is legal. 3423 unsigned BankID = AMDGPU::SGPRRegBankID; 3424 3425 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) { 3426 auto OpBank = getRegBankID(MI.getOperand(I).getReg(), MRI); 3427 // It doesn't make sense to use vcc or scc banks here, so just ignore 3428 // them. 3429 if (OpBank != AMDGPU::SGPRRegBankID) { 3430 BankID = AMDGPU::VGPRRegBankID; 3431 break; 3432 } 3433 } 3434 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3435 3436 const ValueMapping &ValMap = getValueMapping(0, Size, getRegBank(BankID)); 3437 return getInstructionMapping( 3438 1, /*Cost*/ 1, 3439 /*OperandsMapping*/ getOperandsMapping({&ValMap}), 1); 3440 } 3441 3442 // The default handling is broken and doesn't handle illegal SGPR->VGPR copies 3443 // properly. 3444 // 3445 // TODO: There are additional exec masking dependencies to analyze. 3446 if (MI.getOpcode() == TargetOpcode::G_PHI) { 3447 unsigned ResultBank = AMDGPU::InvalidRegBankID; 3448 Register DstReg = MI.getOperand(0).getReg(); 3449 3450 // Sometimes the result may have already been assigned a bank. 3451 if (const RegisterBank *DstBank = getRegBank(DstReg, MRI, *TRI)) 3452 ResultBank = DstBank->getID(); 3453 3454 for (unsigned I = 1, E = MI.getNumOperands(); I != E; I += 2) { 3455 Register Reg = MI.getOperand(I).getReg(); 3456 const RegisterBank *Bank = getRegBank(Reg, MRI, *TRI); 3457 3458 // FIXME: Assuming VGPR for any undetermined inputs. 3459 if (!Bank || Bank->getID() == AMDGPU::VGPRRegBankID) { 3460 ResultBank = AMDGPU::VGPRRegBankID; 3461 break; 3462 } 3463 3464 // FIXME: Need to promote SGPR case to s32 3465 unsigned OpBank = Bank->getID(); 3466 ResultBank = regBankBoolUnion(ResultBank, OpBank); 3467 } 3468 3469 assert(ResultBank != AMDGPU::InvalidRegBankID); 3470 3471 unsigned Size = MRI.getType(DstReg).getSizeInBits(); 3472 3473 const ValueMapping &ValMap = 3474 getValueMapping(0, Size, getRegBank(ResultBank)); 3475 return getInstructionMapping( 3476 1, /*Cost*/ 1, 3477 /*OperandsMapping*/ getOperandsMapping({&ValMap}), 1); 3478 } 3479 3480 const RegisterBankInfo::InstructionMapping &Mapping = getInstrMappingImpl(MI); 3481 if (Mapping.isValid()) 3482 return Mapping; 3483 3484 SmallVector<const ValueMapping*, 8> OpdsMapping(MI.getNumOperands()); 3485 3486 switch (MI.getOpcode()) { 3487 default: 3488 return getInvalidInstructionMapping(); 3489 3490 case AMDGPU::G_AND: 3491 case AMDGPU::G_OR: 3492 case AMDGPU::G_XOR: { 3493 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3494 if (Size == 1) { 3495 const RegisterBank *DstBank 3496 = getRegBank(MI.getOperand(0).getReg(), MRI, *TRI); 3497 3498 unsigned TargetBankID = AMDGPU::InvalidRegBankID; 3499 unsigned BankLHS = AMDGPU::InvalidRegBankID; 3500 unsigned BankRHS = AMDGPU::InvalidRegBankID; 3501 if (DstBank) { 3502 TargetBankID = DstBank->getID(); 3503 if (DstBank == &AMDGPU::VCCRegBank) { 3504 TargetBankID = AMDGPU::VCCRegBankID; 3505 BankLHS = AMDGPU::VCCRegBankID; 3506 BankRHS = AMDGPU::VCCRegBankID; 3507 } else { 3508 BankLHS = getRegBankID(MI.getOperand(1).getReg(), MRI, 3509 AMDGPU::SGPRRegBankID); 3510 BankRHS = getRegBankID(MI.getOperand(2).getReg(), MRI, 3511 AMDGPU::SGPRRegBankID); 3512 } 3513 } else { 3514 BankLHS = getRegBankID(MI.getOperand(1).getReg(), MRI, 3515 AMDGPU::VCCRegBankID); 3516 BankRHS = getRegBankID(MI.getOperand(2).getReg(), MRI, 3517 AMDGPU::VCCRegBankID); 3518 3519 // Both inputs should be true booleans to produce a boolean result. 3520 if (BankLHS == AMDGPU::VGPRRegBankID || BankRHS == AMDGPU::VGPRRegBankID) { 3521 TargetBankID = AMDGPU::VGPRRegBankID; 3522 } else if (BankLHS == AMDGPU::VCCRegBankID || BankRHS == AMDGPU::VCCRegBankID) { 3523 TargetBankID = AMDGPU::VCCRegBankID; 3524 BankLHS = AMDGPU::VCCRegBankID; 3525 BankRHS = AMDGPU::VCCRegBankID; 3526 } else if (BankLHS == AMDGPU::SGPRRegBankID && BankRHS == AMDGPU::SGPRRegBankID) { 3527 TargetBankID = AMDGPU::SGPRRegBankID; 3528 } 3529 } 3530 3531 OpdsMapping[0] = AMDGPU::getValueMapping(TargetBankID, Size); 3532 OpdsMapping[1] = AMDGPU::getValueMapping(BankLHS, Size); 3533 OpdsMapping[2] = AMDGPU::getValueMapping(BankRHS, Size); 3534 break; 3535 } 3536 3537 if (Size == 64) { 3538 3539 if (isSALUMapping(MI)) { 3540 OpdsMapping[0] = getValueMappingSGPR64Only(AMDGPU::SGPRRegBankID, Size); 3541 OpdsMapping[1] = OpdsMapping[2] = OpdsMapping[0]; 3542 } else { 3543 OpdsMapping[0] = getValueMappingSGPR64Only(AMDGPU::VGPRRegBankID, Size); 3544 unsigned Bank1 = getRegBankID(MI.getOperand(1).getReg(), MRI /*, DefaultBankID*/); 3545 OpdsMapping[1] = AMDGPU::getValueMapping(Bank1, Size); 3546 3547 unsigned Bank2 = getRegBankID(MI.getOperand(2).getReg(), MRI /*, DefaultBankID*/); 3548 OpdsMapping[2] = AMDGPU::getValueMapping(Bank2, Size); 3549 } 3550 3551 break; 3552 } 3553 3554 LLVM_FALLTHROUGH; 3555 } 3556 case AMDGPU::G_PTR_ADD: 3557 case AMDGPU::G_PTRMASK: 3558 case AMDGPU::G_ADD: 3559 case AMDGPU::G_SUB: 3560 case AMDGPU::G_MUL: 3561 case AMDGPU::G_SHL: 3562 case AMDGPU::G_LSHR: 3563 case AMDGPU::G_ASHR: 3564 case AMDGPU::G_UADDO: 3565 case AMDGPU::G_USUBO: 3566 case AMDGPU::G_UADDE: 3567 case AMDGPU::G_SADDE: 3568 case AMDGPU::G_USUBE: 3569 case AMDGPU::G_SSUBE: 3570 case AMDGPU::G_SMIN: 3571 case AMDGPU::G_SMAX: 3572 case AMDGPU::G_UMIN: 3573 case AMDGPU::G_UMAX: 3574 case AMDGPU::G_SHUFFLE_VECTOR: 3575 if (isSALUMapping(MI)) 3576 return getDefaultMappingSOP(MI); 3577 LLVM_FALLTHROUGH; 3578 3579 case AMDGPU::G_SADDSAT: // FIXME: Could lower sat ops for SALU 3580 case AMDGPU::G_SSUBSAT: 3581 case AMDGPU::G_UADDSAT: 3582 case AMDGPU::G_USUBSAT: 3583 case AMDGPU::G_FADD: 3584 case AMDGPU::G_FSUB: 3585 case AMDGPU::G_FPTOSI: 3586 case AMDGPU::G_FPTOUI: 3587 case AMDGPU::G_FMUL: 3588 case AMDGPU::G_FMA: 3589 case AMDGPU::G_FMAD: 3590 case AMDGPU::G_FSQRT: 3591 case AMDGPU::G_FFLOOR: 3592 case AMDGPU::G_FCEIL: 3593 case AMDGPU::G_FRINT: 3594 case AMDGPU::G_SITOFP: 3595 case AMDGPU::G_UITOFP: 3596 case AMDGPU::G_FPTRUNC: 3597 case AMDGPU::G_FPEXT: 3598 case AMDGPU::G_FEXP2: 3599 case AMDGPU::G_FLOG2: 3600 case AMDGPU::G_FMINNUM: 3601 case AMDGPU::G_FMAXNUM: 3602 case AMDGPU::G_FMINNUM_IEEE: 3603 case AMDGPU::G_FMAXNUM_IEEE: 3604 case AMDGPU::G_FCANONICALIZE: 3605 case AMDGPU::G_INTRINSIC_TRUNC: 3606 case AMDGPU::G_BSWAP: // TODO: Somehow expand for scalar? 3607 case AMDGPU::G_FSHR: // TODO: Expand for scalar 3608 case AMDGPU::G_AMDGPU_FFBH_U32: 3609 case AMDGPU::G_AMDGPU_FMIN_LEGACY: 3610 case AMDGPU::G_AMDGPU_FMAX_LEGACY: 3611 case AMDGPU::G_AMDGPU_RCP_IFLAG: 3612 case AMDGPU::G_AMDGPU_CVT_F32_UBYTE0: 3613 case AMDGPU::G_AMDGPU_CVT_F32_UBYTE1: 3614 case AMDGPU::G_AMDGPU_CVT_F32_UBYTE2: 3615 case AMDGPU::G_AMDGPU_CVT_F32_UBYTE3: 3616 return getDefaultMappingVOP(MI); 3617 case AMDGPU::G_UMULH: 3618 case AMDGPU::G_SMULH: { 3619 if (Subtarget.hasScalarMulHiInsts() && isSALUMapping(MI)) 3620 return getDefaultMappingSOP(MI); 3621 return getDefaultMappingVOP(MI); 3622 } 3623 case AMDGPU::G_IMPLICIT_DEF: { 3624 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3625 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3626 break; 3627 } 3628 case AMDGPU::G_FCONSTANT: 3629 case AMDGPU::G_CONSTANT: 3630 case AMDGPU::G_GLOBAL_VALUE: 3631 case AMDGPU::G_BLOCK_ADDR: 3632 case AMDGPU::G_READCYCLECOUNTER: { 3633 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3634 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 3635 break; 3636 } 3637 case AMDGPU::G_FRAME_INDEX: { 3638 // TODO: This should be the same as other constants, but eliminateFrameIndex 3639 // currently assumes VALU uses. 3640 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3641 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3642 break; 3643 } 3644 case AMDGPU::G_DYN_STACKALLOC: { 3645 // Result is always uniform, and a wave reduction is needed for the source. 3646 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, 32); 3647 unsigned SrcBankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3648 OpdsMapping[1] = AMDGPU::getValueMapping(SrcBankID, 32); 3649 break; 3650 } 3651 case AMDGPU::G_INSERT: { 3652 unsigned BankID = getMappingType(MRI, MI); 3653 unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3654 unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 3655 unsigned EltSize = getSizeInBits(MI.getOperand(2).getReg(), MRI, *TRI); 3656 OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize); 3657 OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize); 3658 OpdsMapping[2] = AMDGPU::getValueMapping(BankID, EltSize); 3659 OpdsMapping[3] = nullptr; 3660 break; 3661 } 3662 case AMDGPU::G_EXTRACT: { 3663 unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3664 unsigned DstSize = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 3665 unsigned SrcSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 3666 OpdsMapping[0] = AMDGPU::getValueMapping(BankID, DstSize); 3667 OpdsMapping[1] = AMDGPU::getValueMapping(BankID, SrcSize); 3668 OpdsMapping[2] = nullptr; 3669 break; 3670 } 3671 case AMDGPU::G_BUILD_VECTOR: 3672 case AMDGPU::G_BUILD_VECTOR_TRUNC: { 3673 LLT DstTy = MRI.getType(MI.getOperand(0).getReg()); 3674 if (DstTy == LLT::vector(2, 16)) { 3675 unsigned DstSize = DstTy.getSizeInBits(); 3676 unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 3677 unsigned Src0BankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3678 unsigned Src1BankID = getRegBankID(MI.getOperand(2).getReg(), MRI); 3679 unsigned DstBankID = regBankUnion(Src0BankID, Src1BankID); 3680 3681 OpdsMapping[0] = AMDGPU::getValueMapping(DstBankID, DstSize); 3682 OpdsMapping[1] = AMDGPU::getValueMapping(Src0BankID, SrcSize); 3683 OpdsMapping[2] = AMDGPU::getValueMapping(Src1BankID, SrcSize); 3684 break; 3685 } 3686 3687 LLVM_FALLTHROUGH; 3688 } 3689 case AMDGPU::G_MERGE_VALUES: 3690 case AMDGPU::G_CONCAT_VECTORS: { 3691 unsigned Bank = getMappingType(MRI, MI); 3692 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3693 unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 3694 3695 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize); 3696 // Op1 and Dst should use the same register bank. 3697 for (unsigned i = 1, e = MI.getNumOperands(); i != e; ++i) 3698 OpdsMapping[i] = AMDGPU::getValueMapping(Bank, SrcSize); 3699 break; 3700 } 3701 case AMDGPU::G_BITCAST: 3702 case AMDGPU::G_INTTOPTR: 3703 case AMDGPU::G_PTRTOINT: 3704 case AMDGPU::G_BITREVERSE: 3705 case AMDGPU::G_FABS: 3706 case AMDGPU::G_FNEG: { 3707 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3708 unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3709 OpdsMapping[0] = OpdsMapping[1] = AMDGPU::getValueMapping(BankID, Size); 3710 break; 3711 } 3712 case AMDGPU::G_CTLZ_ZERO_UNDEF: 3713 case AMDGPU::G_CTTZ_ZERO_UNDEF: 3714 case AMDGPU::G_CTPOP: { 3715 unsigned Size = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 3716 unsigned BankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3717 OpdsMapping[0] = AMDGPU::getValueMapping(BankID, 32); 3718 3719 // This should really be getValueMappingSGPR64Only, but allowing the generic 3720 // code to handle the register split just makes using LegalizerHelper more 3721 // difficult. 3722 OpdsMapping[1] = AMDGPU::getValueMapping(BankID, Size); 3723 break; 3724 } 3725 case AMDGPU::G_TRUNC: { 3726 Register Dst = MI.getOperand(0).getReg(); 3727 Register Src = MI.getOperand(1).getReg(); 3728 unsigned Bank = getRegBankID(Src, MRI); 3729 unsigned DstSize = getSizeInBits(Dst, MRI, *TRI); 3730 unsigned SrcSize = getSizeInBits(Src, MRI, *TRI); 3731 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, DstSize); 3732 OpdsMapping[1] = AMDGPU::getValueMapping(Bank, SrcSize); 3733 break; 3734 } 3735 case AMDGPU::G_ZEXT: 3736 case AMDGPU::G_SEXT: 3737 case AMDGPU::G_ANYEXT: 3738 case AMDGPU::G_SEXT_INREG: { 3739 Register Dst = MI.getOperand(0).getReg(); 3740 Register Src = MI.getOperand(1).getReg(); 3741 unsigned DstSize = getSizeInBits(Dst, MRI, *TRI); 3742 unsigned SrcSize = getSizeInBits(Src, MRI, *TRI); 3743 3744 unsigned DstBank; 3745 const RegisterBank *SrcBank = getRegBank(Src, MRI, *TRI); 3746 assert(SrcBank); 3747 switch (SrcBank->getID()) { 3748 case AMDGPU::SGPRRegBankID: 3749 DstBank = AMDGPU::SGPRRegBankID; 3750 break; 3751 default: 3752 DstBank = AMDGPU::VGPRRegBankID; 3753 break; 3754 } 3755 3756 // Scalar extend can use 64-bit BFE, but VGPRs require extending to 3757 // 32-bits, and then to 64. 3758 OpdsMapping[0] = AMDGPU::getValueMappingSGPR64Only(DstBank, DstSize); 3759 OpdsMapping[1] = AMDGPU::getValueMappingSGPR64Only(SrcBank->getID(), 3760 SrcSize); 3761 break; 3762 } 3763 case AMDGPU::G_FCMP: { 3764 unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3765 unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI); 3766 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 3767 OpdsMapping[1] = nullptr; // Predicate Operand. 3768 OpdsMapping[2] = AMDGPU::getValueMapping(Op2Bank, Size); 3769 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3770 break; 3771 } 3772 case AMDGPU::G_STORE: { 3773 assert(MI.getOperand(0).isReg()); 3774 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3775 3776 // FIXME: We need to specify a different reg bank once scalar stores are 3777 // supported. 3778 const ValueMapping *ValMapping = 3779 AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 3780 OpdsMapping[0] = ValMapping; 3781 OpdsMapping[1] = getValueMappingForPtr(MRI, MI.getOperand(1).getReg()); 3782 break; 3783 } 3784 case AMDGPU::G_ICMP: { 3785 auto Pred = static_cast<CmpInst::Predicate>(MI.getOperand(1).getPredicate()); 3786 unsigned Size = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3787 3788 // See if the result register has already been constrained to vcc, which may 3789 // happen due to control flow intrinsic lowering. 3790 unsigned DstBank = getRegBankID(MI.getOperand(0).getReg(), MRI, 3791 AMDGPU::SGPRRegBankID); 3792 unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI); 3793 unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI); 3794 3795 bool CanUseSCC = DstBank == AMDGPU::SGPRRegBankID && 3796 Op2Bank == AMDGPU::SGPRRegBankID && 3797 Op3Bank == AMDGPU::SGPRRegBankID && 3798 (Size == 32 || (Size == 64 && 3799 (Pred == CmpInst::ICMP_EQ || Pred == CmpInst::ICMP_NE) && 3800 Subtarget.hasScalarCompareEq64())); 3801 3802 DstBank = CanUseSCC ? AMDGPU::SGPRRegBankID : AMDGPU::VCCRegBankID; 3803 unsigned SrcBank = CanUseSCC ? AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID; 3804 3805 // TODO: Use 32-bit for scalar output size. 3806 // SCC results will need to be copied to a 32-bit SGPR virtual register. 3807 const unsigned ResultSize = 1; 3808 3809 OpdsMapping[0] = AMDGPU::getValueMapping(DstBank, ResultSize); 3810 OpdsMapping[2] = AMDGPU::getValueMapping(SrcBank, Size); 3811 OpdsMapping[3] = AMDGPU::getValueMapping(SrcBank, Size); 3812 break; 3813 } 3814 case AMDGPU::G_EXTRACT_VECTOR_ELT: { 3815 // VGPR index can be used for waterfall when indexing a SGPR vector. 3816 unsigned SrcBankID = getRegBankID(MI.getOperand(1).getReg(), MRI); 3817 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3818 unsigned SrcSize = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 3819 unsigned IdxSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3820 unsigned IdxBank = getRegBankID(MI.getOperand(2).getReg(), MRI); 3821 unsigned OutputBankID = regBankUnion(SrcBankID, IdxBank); 3822 3823 OpdsMapping[0] = AMDGPU::getValueMappingSGPR64Only(OutputBankID, DstSize); 3824 OpdsMapping[1] = AMDGPU::getValueMapping(SrcBankID, SrcSize); 3825 3826 // The index can be either if the source vector is VGPR. 3827 OpdsMapping[2] = AMDGPU::getValueMapping(IdxBank, IdxSize); 3828 break; 3829 } 3830 case AMDGPU::G_INSERT_VECTOR_ELT: { 3831 unsigned OutputBankID = isSALUMapping(MI) ? 3832 AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID; 3833 3834 unsigned VecSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3835 unsigned InsertSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 3836 unsigned IdxSize = MRI.getType(MI.getOperand(3).getReg()).getSizeInBits(); 3837 unsigned InsertEltBankID = getRegBankID(MI.getOperand(2).getReg(), MRI); 3838 unsigned IdxBankID = getRegBankID(MI.getOperand(3).getReg(), MRI); 3839 3840 OpdsMapping[0] = AMDGPU::getValueMapping(OutputBankID, VecSize); 3841 OpdsMapping[1] = AMDGPU::getValueMapping(OutputBankID, VecSize); 3842 3843 // This is a weird case, because we need to break down the mapping based on 3844 // the register bank of a different operand. 3845 if (InsertSize == 64 && OutputBankID == AMDGPU::VGPRRegBankID) { 3846 OpdsMapping[2] = AMDGPU::getValueMappingSplit64(InsertEltBankID, 3847 InsertSize); 3848 } else { 3849 assert(InsertSize == 32 || InsertSize == 64); 3850 OpdsMapping[2] = AMDGPU::getValueMapping(InsertEltBankID, InsertSize); 3851 } 3852 3853 // The index can be either if the source vector is VGPR. 3854 OpdsMapping[3] = AMDGPU::getValueMapping(IdxBankID, IdxSize); 3855 break; 3856 } 3857 case AMDGPU::G_UNMERGE_VALUES: { 3858 unsigned Bank = getMappingType(MRI, MI); 3859 3860 // Op1 and Dst should use the same register bank. 3861 // FIXME: Shouldn't this be the default? Why do we need to handle this? 3862 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) { 3863 unsigned Size = getSizeInBits(MI.getOperand(i).getReg(), MRI, *TRI); 3864 OpdsMapping[i] = AMDGPU::getValueMapping(Bank, Size); 3865 } 3866 break; 3867 } 3868 case AMDGPU::G_AMDGPU_BUFFER_LOAD: 3869 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE: 3870 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE: 3871 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT: 3872 case AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT: 3873 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT: 3874 case AMDGPU::G_AMDGPU_BUFFER_LOAD_FORMAT_D16: 3875 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT: 3876 case AMDGPU::G_AMDGPU_TBUFFER_LOAD_FORMAT_D16: 3877 case AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT: 3878 case AMDGPU::G_AMDGPU_TBUFFER_STORE_FORMAT_D16: 3879 case AMDGPU::G_AMDGPU_BUFFER_STORE: 3880 case AMDGPU::G_AMDGPU_BUFFER_STORE_BYTE: 3881 case AMDGPU::G_AMDGPU_BUFFER_STORE_SHORT: 3882 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT: 3883 case AMDGPU::G_AMDGPU_BUFFER_STORE_FORMAT_D16: { 3884 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3885 3886 // rsrc 3887 OpdsMapping[1] = getSGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3888 3889 // vindex 3890 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3891 3892 // voffset 3893 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3894 3895 // soffset 3896 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3897 3898 // Any remaining operands are immediates and were correctly null 3899 // initialized. 3900 break; 3901 } 3902 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SWAP: 3903 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_ADD: 3904 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SUB: 3905 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMIN: 3906 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMIN: 3907 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_SMAX: 3908 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_UMAX: 3909 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_AND: 3910 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_OR: 3911 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_XOR: 3912 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_INC: 3913 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_DEC: { 3914 // vdata_out 3915 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3916 3917 // vdata_in 3918 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3919 3920 // rsrc 3921 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3922 3923 // vindex 3924 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3925 3926 // voffset 3927 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3928 3929 // soffset 3930 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 3931 3932 // Any remaining operands are immediates and were correctly null 3933 // initialized. 3934 break; 3935 } 3936 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_FADD: { 3937 // vdata_in 3938 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3939 3940 // rsrc 3941 OpdsMapping[1] = getSGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3942 3943 // vindex 3944 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3945 3946 // voffset 3947 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3948 3949 // soffset 3950 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3951 break; 3952 } 3953 case AMDGPU::G_AMDGPU_BUFFER_ATOMIC_CMPSWAP: { 3954 // vdata_out 3955 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 3956 3957 // vdata_in 3958 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3959 3960 // cmp 3961 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3962 3963 // rsrc 3964 OpdsMapping[3] = getSGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 3965 3966 // vindex 3967 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 3968 3969 // voffset 3970 OpdsMapping[5] = getVGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 3971 3972 // soffset 3973 OpdsMapping[6] = getSGPROpMapping(MI.getOperand(6).getReg(), MRI, *TRI); 3974 3975 // Any remaining operands are immediates and were correctly null 3976 // initialized. 3977 break; 3978 } 3979 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD: { 3980 // Lie and claim everything is legal, even though some need to be 3981 // SGPRs. applyMapping will have to deal with it as a waterfall loop. 3982 OpdsMapping[1] = getSGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 3983 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 3984 3985 // We need to convert this to a MUBUF if either the resource of offset is 3986 // VGPR. 3987 unsigned RSrcBank = OpdsMapping[1]->BreakDown[0].RegBank->getID(); 3988 unsigned OffsetBank = OpdsMapping[2]->BreakDown[0].RegBank->getID(); 3989 unsigned ResultBank = regBankUnion(RSrcBank, OffsetBank); 3990 3991 unsigned Size0 = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 3992 OpdsMapping[0] = AMDGPU::getValueMapping(ResultBank, Size0); 3993 break; 3994 } 3995 case AMDGPU::G_INTRINSIC: { 3996 switch (MI.getIntrinsicID()) { 3997 default: 3998 return getInvalidInstructionMapping(); 3999 case Intrinsic::amdgcn_div_fmas: 4000 case Intrinsic::amdgcn_div_fixup: 4001 case Intrinsic::amdgcn_trig_preop: 4002 case Intrinsic::amdgcn_sin: 4003 case Intrinsic::amdgcn_cos: 4004 case Intrinsic::amdgcn_log_clamp: 4005 case Intrinsic::amdgcn_rcp: 4006 case Intrinsic::amdgcn_rcp_legacy: 4007 case Intrinsic::amdgcn_sqrt: 4008 case Intrinsic::amdgcn_rsq: 4009 case Intrinsic::amdgcn_rsq_legacy: 4010 case Intrinsic::amdgcn_rsq_clamp: 4011 case Intrinsic::amdgcn_fmul_legacy: 4012 case Intrinsic::amdgcn_ldexp: 4013 case Intrinsic::amdgcn_frexp_mant: 4014 case Intrinsic::amdgcn_frexp_exp: 4015 case Intrinsic::amdgcn_fract: 4016 case Intrinsic::amdgcn_cvt_pkrtz: 4017 case Intrinsic::amdgcn_cvt_pknorm_i16: 4018 case Intrinsic::amdgcn_cvt_pknorm_u16: 4019 case Intrinsic::amdgcn_cvt_pk_i16: 4020 case Intrinsic::amdgcn_cvt_pk_u16: 4021 case Intrinsic::amdgcn_fmed3: 4022 case Intrinsic::amdgcn_cubeid: 4023 case Intrinsic::amdgcn_cubema: 4024 case Intrinsic::amdgcn_cubesc: 4025 case Intrinsic::amdgcn_cubetc: 4026 case Intrinsic::amdgcn_sffbh: 4027 case Intrinsic::amdgcn_fmad_ftz: 4028 case Intrinsic::amdgcn_mbcnt_lo: 4029 case Intrinsic::amdgcn_mbcnt_hi: 4030 case Intrinsic::amdgcn_mul_u24: 4031 case Intrinsic::amdgcn_mul_i24: 4032 case Intrinsic::amdgcn_lerp: 4033 case Intrinsic::amdgcn_sad_u8: 4034 case Intrinsic::amdgcn_msad_u8: 4035 case Intrinsic::amdgcn_sad_hi_u8: 4036 case Intrinsic::amdgcn_sad_u16: 4037 case Intrinsic::amdgcn_qsad_pk_u16_u8: 4038 case Intrinsic::amdgcn_mqsad_pk_u16_u8: 4039 case Intrinsic::amdgcn_mqsad_u32_u8: 4040 case Intrinsic::amdgcn_cvt_pk_u8_f32: 4041 case Intrinsic::amdgcn_alignbit: 4042 case Intrinsic::amdgcn_alignbyte: 4043 case Intrinsic::amdgcn_fdot2: 4044 case Intrinsic::amdgcn_sdot2: 4045 case Intrinsic::amdgcn_udot2: 4046 case Intrinsic::amdgcn_sdot4: 4047 case Intrinsic::amdgcn_udot4: 4048 case Intrinsic::amdgcn_sdot8: 4049 case Intrinsic::amdgcn_udot8: 4050 return getDefaultMappingVOP(MI); 4051 case Intrinsic::amdgcn_sbfe: 4052 case Intrinsic::amdgcn_ubfe: 4053 if (isSALUMapping(MI)) 4054 return getDefaultMappingSOP(MI); 4055 return getDefaultMappingVOP(MI); 4056 case Intrinsic::amdgcn_ds_swizzle: 4057 case Intrinsic::amdgcn_ds_permute: 4058 case Intrinsic::amdgcn_ds_bpermute: 4059 case Intrinsic::amdgcn_update_dpp: 4060 case Intrinsic::amdgcn_mov_dpp8: 4061 case Intrinsic::amdgcn_mov_dpp: 4062 case Intrinsic::amdgcn_wwm: 4063 case Intrinsic::amdgcn_wqm: 4064 case Intrinsic::amdgcn_softwqm: 4065 case Intrinsic::amdgcn_set_inactive: 4066 return getDefaultMappingAllVGPR(MI); 4067 case Intrinsic::amdgcn_kernarg_segment_ptr: 4068 case Intrinsic::amdgcn_s_getpc: 4069 case Intrinsic::amdgcn_groupstaticsize: 4070 case Intrinsic::amdgcn_reloc_constant: 4071 case Intrinsic::returnaddress: { 4072 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4073 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4074 break; 4075 } 4076 case Intrinsic::amdgcn_wqm_vote: { 4077 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4078 OpdsMapping[0] = OpdsMapping[2] 4079 = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Size); 4080 break; 4081 } 4082 case Intrinsic::amdgcn_ps_live: { 4083 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 4084 break; 4085 } 4086 case Intrinsic::amdgcn_div_scale: { 4087 unsigned Dst0Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4088 unsigned Dst1Size = MRI.getType(MI.getOperand(1).getReg()).getSizeInBits(); 4089 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Dst0Size); 4090 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, Dst1Size); 4091 4092 unsigned SrcSize = MRI.getType(MI.getOperand(3).getReg()).getSizeInBits(); 4093 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 4094 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 4095 break; 4096 } 4097 case Intrinsic::amdgcn_class: { 4098 Register Src0Reg = MI.getOperand(2).getReg(); 4099 Register Src1Reg = MI.getOperand(3).getReg(); 4100 unsigned Src0Size = MRI.getType(Src0Reg).getSizeInBits(); 4101 unsigned Src1Size = MRI.getType(Src1Reg).getSizeInBits(); 4102 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4103 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, DstSize); 4104 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Src0Size); 4105 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Src1Size); 4106 break; 4107 } 4108 case Intrinsic::amdgcn_icmp: 4109 case Intrinsic::amdgcn_fcmp: { 4110 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4111 // This is not VCCRegBank because this is not used in boolean contexts. 4112 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, DstSize); 4113 unsigned OpSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 4114 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, OpSize); 4115 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, OpSize); 4116 break; 4117 } 4118 case Intrinsic::amdgcn_readlane: { 4119 // This must be an SGPR, but accept a VGPR. 4120 Register IdxReg = MI.getOperand(3).getReg(); 4121 unsigned IdxSize = MRI.getType(IdxReg).getSizeInBits(); 4122 unsigned IdxBank = getRegBankID(IdxReg, MRI, AMDGPU::SGPRRegBankID); 4123 OpdsMapping[3] = AMDGPU::getValueMapping(IdxBank, IdxSize); 4124 LLVM_FALLTHROUGH; 4125 } 4126 case Intrinsic::amdgcn_readfirstlane: { 4127 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4128 unsigned SrcSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 4129 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, DstSize); 4130 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 4131 break; 4132 } 4133 case Intrinsic::amdgcn_writelane: { 4134 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4135 Register SrcReg = MI.getOperand(2).getReg(); 4136 unsigned SrcSize = MRI.getType(SrcReg).getSizeInBits(); 4137 unsigned SrcBank = getRegBankID(SrcReg, MRI, AMDGPU::SGPRRegBankID); 4138 Register IdxReg = MI.getOperand(3).getReg(); 4139 unsigned IdxSize = MRI.getType(IdxReg).getSizeInBits(); 4140 unsigned IdxBank = getRegBankID(IdxReg, MRI, AMDGPU::SGPRRegBankID); 4141 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 4142 4143 // These 2 must be SGPRs, but accept VGPRs. Readfirstlane will be inserted 4144 // to legalize. 4145 OpdsMapping[2] = AMDGPU::getValueMapping(SrcBank, SrcSize); 4146 OpdsMapping[3] = AMDGPU::getValueMapping(IdxBank, IdxSize); 4147 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, SrcSize); 4148 break; 4149 } 4150 case Intrinsic::amdgcn_if_break: { 4151 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 4152 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4153 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 4154 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4155 break; 4156 } 4157 case Intrinsic::amdgcn_permlane16: 4158 case Intrinsic::amdgcn_permlanex16: { 4159 unsigned Size = getSizeInBits(MI.getOperand(0).getReg(), MRI, *TRI); 4160 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 4161 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 4162 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, Size); 4163 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4164 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4165 break; 4166 } 4167 case Intrinsic::amdgcn_mfma_f32_4x4x1f32: 4168 case Intrinsic::amdgcn_mfma_f32_4x4x4f16: 4169 case Intrinsic::amdgcn_mfma_i32_4x4x4i8: 4170 case Intrinsic::amdgcn_mfma_f32_4x4x2bf16: 4171 case Intrinsic::amdgcn_mfma_f32_16x16x1f32: 4172 case Intrinsic::amdgcn_mfma_f32_16x16x4f32: 4173 case Intrinsic::amdgcn_mfma_f32_16x16x4f16: 4174 case Intrinsic::amdgcn_mfma_f32_16x16x16f16: 4175 case Intrinsic::amdgcn_mfma_i32_16x16x4i8: 4176 case Intrinsic::amdgcn_mfma_i32_16x16x16i8: 4177 case Intrinsic::amdgcn_mfma_f32_16x16x2bf16: 4178 case Intrinsic::amdgcn_mfma_f32_16x16x8bf16: 4179 case Intrinsic::amdgcn_mfma_f32_32x32x1f32: 4180 case Intrinsic::amdgcn_mfma_f32_32x32x2f32: 4181 case Intrinsic::amdgcn_mfma_f32_32x32x4f16: 4182 case Intrinsic::amdgcn_mfma_f32_32x32x8f16: 4183 case Intrinsic::amdgcn_mfma_i32_32x32x4i8: 4184 case Intrinsic::amdgcn_mfma_i32_32x32x8i8: 4185 case Intrinsic::amdgcn_mfma_f32_32x32x2bf16: 4186 case Intrinsic::amdgcn_mfma_f32_32x32x4bf16: { 4187 // Default for MAI intrinsics. 4188 // srcC can also be an immediate which can be folded later. 4189 // FIXME: Should we eventually add an alternative mapping with AGPR src 4190 // for srcA/srcB? 4191 // 4192 // vdst, srcA, srcB, srcC 4193 OpdsMapping[0] = getAGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 4194 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4195 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4196 OpdsMapping[4] = getAGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4197 break; 4198 } 4199 case Intrinsic::amdgcn_interp_p1: 4200 case Intrinsic::amdgcn_interp_p2: 4201 case Intrinsic::amdgcn_interp_mov: 4202 case Intrinsic::amdgcn_interp_p1_f16: 4203 case Intrinsic::amdgcn_interp_p2_f16: { 4204 const int M0Idx = MI.getNumOperands() - 1; 4205 Register M0Reg = MI.getOperand(M0Idx).getReg(); 4206 unsigned M0Bank = getRegBankID(M0Reg, MRI, AMDGPU::SGPRRegBankID); 4207 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4208 4209 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 4210 for (int I = 2; I != M0Idx && MI.getOperand(I).isReg(); ++I) 4211 OpdsMapping[I] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4212 4213 // Must be SGPR, but we must take whatever the original bank is and fix it 4214 // later. 4215 OpdsMapping[M0Idx] = AMDGPU::getValueMapping(M0Bank, 32); 4216 break; 4217 } 4218 case Intrinsic::amdgcn_ballot: { 4219 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4220 unsigned SrcSize = MRI.getType(MI.getOperand(2).getReg()).getSizeInBits(); 4221 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, DstSize); 4222 OpdsMapping[2] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, SrcSize); 4223 break; 4224 } 4225 } 4226 break; 4227 } 4228 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD: 4229 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE: { 4230 auto IntrID = MI.getIntrinsicID(); 4231 const AMDGPU::RsrcIntrinsic *RSrcIntrin = AMDGPU::lookupRsrcIntrinsic(IntrID); 4232 assert(RSrcIntrin && "missing RsrcIntrinsic for image intrinsic"); 4233 // Non-images can have complications from operands that allow both SGPR 4234 // and VGPR. For now it's too complicated to figure out the final opcode 4235 // to derive the register bank from the MCInstrDesc. 4236 assert(RSrcIntrin->IsImage); 4237 return getImageMapping(MRI, MI, RSrcIntrin->RsrcArg); 4238 } 4239 case AMDGPU::G_INTRINSIC_W_SIDE_EFFECTS: { 4240 auto IntrID = MI.getIntrinsicID(); 4241 switch (IntrID) { 4242 case Intrinsic::amdgcn_s_getreg: 4243 case Intrinsic::amdgcn_s_memtime: 4244 case Intrinsic::amdgcn_s_memrealtime: 4245 case Intrinsic::amdgcn_s_get_waveid_in_workgroup: { 4246 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4247 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4248 break; 4249 } 4250 case Intrinsic::amdgcn_global_atomic_fadd: 4251 case Intrinsic::amdgcn_global_atomic_csub: 4252 return getDefaultMappingAllVGPR(MI); 4253 case Intrinsic::amdgcn_ds_ordered_add: 4254 case Intrinsic::amdgcn_ds_ordered_swap: { 4255 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4256 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 4257 unsigned M0Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, 4258 AMDGPU::SGPRRegBankID); 4259 OpdsMapping[2] = AMDGPU::getValueMapping(M0Bank, 32); 4260 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4261 break; 4262 } 4263 case Intrinsic::amdgcn_ds_append: 4264 case Intrinsic::amdgcn_ds_consume: { 4265 unsigned DstSize = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4266 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, DstSize); 4267 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4268 break; 4269 } 4270 case Intrinsic::amdgcn_exp_compr: 4271 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4272 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4273 break; 4274 case Intrinsic::amdgcn_exp: 4275 // FIXME: Could we support packed types here? 4276 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4277 OpdsMapping[4] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4278 OpdsMapping[5] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4279 OpdsMapping[6] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4280 break; 4281 case Intrinsic::amdgcn_s_sendmsg: 4282 case Intrinsic::amdgcn_s_sendmsghalt: { 4283 // This must be an SGPR, but accept a VGPR. 4284 unsigned Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, 4285 AMDGPU::SGPRRegBankID); 4286 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, 32); 4287 break; 4288 } 4289 case Intrinsic::amdgcn_s_setreg: { 4290 // This must be an SGPR, but accept a VGPR. 4291 unsigned Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, 4292 AMDGPU::SGPRRegBankID); 4293 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, 32); 4294 break; 4295 } 4296 case Intrinsic::amdgcn_end_cf: { 4297 unsigned Size = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 4298 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4299 break; 4300 } 4301 case Intrinsic::amdgcn_else: { 4302 unsigned WaveSize = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 4303 OpdsMapping[0] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 4304 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, WaveSize); 4305 OpdsMapping[3] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, WaveSize); 4306 break; 4307 } 4308 case Intrinsic::amdgcn_kill: { 4309 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::VCCRegBankID, 1); 4310 break; 4311 } 4312 case Intrinsic::amdgcn_raw_buffer_load: 4313 case Intrinsic::amdgcn_raw_tbuffer_load: { 4314 // FIXME: Should make intrinsic ID the last operand of the instruction, 4315 // then this would be the same as store 4316 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 4317 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4318 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4319 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4320 break; 4321 } 4322 case Intrinsic::amdgcn_raw_buffer_store: 4323 case Intrinsic::amdgcn_raw_buffer_store_format: 4324 case Intrinsic::amdgcn_raw_tbuffer_store: { 4325 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 4326 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4327 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4328 OpdsMapping[4] = getSGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4329 break; 4330 } 4331 case Intrinsic::amdgcn_struct_buffer_load: 4332 case Intrinsic::amdgcn_struct_tbuffer_load: { 4333 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 4334 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4335 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4336 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4337 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 4338 break; 4339 } 4340 case Intrinsic::amdgcn_struct_buffer_store: 4341 case Intrinsic::amdgcn_struct_tbuffer_store: { 4342 OpdsMapping[1] = getVGPROpMapping(MI.getOperand(1).getReg(), MRI, *TRI); 4343 OpdsMapping[2] = getSGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4344 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4345 OpdsMapping[4] = getVGPROpMapping(MI.getOperand(4).getReg(), MRI, *TRI); 4346 OpdsMapping[5] = getSGPROpMapping(MI.getOperand(5).getReg(), MRI, *TRI); 4347 break; 4348 } 4349 case Intrinsic::amdgcn_init_exec_from_input: { 4350 unsigned Size = getSizeInBits(MI.getOperand(1).getReg(), MRI, *TRI); 4351 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::SGPRRegBankID, Size); 4352 break; 4353 } 4354 case Intrinsic::amdgcn_ds_gws_init: 4355 case Intrinsic::amdgcn_ds_gws_barrier: 4356 case Intrinsic::amdgcn_ds_gws_sema_br: { 4357 OpdsMapping[1] = AMDGPU::getValueMapping(AMDGPU::VGPRRegBankID, 32); 4358 4359 // This must be an SGPR, but accept a VGPR. 4360 unsigned Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, 4361 AMDGPU::SGPRRegBankID); 4362 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, 32); 4363 break; 4364 } 4365 case Intrinsic::amdgcn_ds_gws_sema_v: 4366 case Intrinsic::amdgcn_ds_gws_sema_p: 4367 case Intrinsic::amdgcn_ds_gws_sema_release_all: { 4368 // This must be an SGPR, but accept a VGPR. 4369 unsigned Bank = getRegBankID(MI.getOperand(1).getReg(), MRI, 4370 AMDGPU::SGPRRegBankID); 4371 OpdsMapping[1] = AMDGPU::getValueMapping(Bank, 32); 4372 break; 4373 } 4374 default: 4375 return getInvalidInstructionMapping(); 4376 } 4377 break; 4378 } 4379 case AMDGPU::G_SELECT: { 4380 unsigned Size = MRI.getType(MI.getOperand(0).getReg()).getSizeInBits(); 4381 unsigned Op2Bank = getRegBankID(MI.getOperand(2).getReg(), MRI, 4382 AMDGPU::SGPRRegBankID); 4383 unsigned Op3Bank = getRegBankID(MI.getOperand(3).getReg(), MRI, 4384 AMDGPU::SGPRRegBankID); 4385 bool SGPRSrcs = Op2Bank == AMDGPU::SGPRRegBankID && 4386 Op3Bank == AMDGPU::SGPRRegBankID; 4387 4388 unsigned CondBankDefault = SGPRSrcs ? 4389 AMDGPU::SGPRRegBankID : AMDGPU::VCCRegBankID; 4390 unsigned CondBank = getRegBankID(MI.getOperand(1).getReg(), MRI, 4391 CondBankDefault); 4392 if (CondBank == AMDGPU::SGPRRegBankID) 4393 CondBank = SGPRSrcs ? AMDGPU::SGPRRegBankID : AMDGPU::VCCRegBankID; 4394 else if (CondBank == AMDGPU::VGPRRegBankID) 4395 CondBank = AMDGPU::VCCRegBankID; 4396 4397 unsigned Bank = SGPRSrcs && CondBank == AMDGPU::SGPRRegBankID ? 4398 AMDGPU::SGPRRegBankID : AMDGPU::VGPRRegBankID; 4399 4400 assert(CondBank == AMDGPU::VCCRegBankID || CondBank == AMDGPU::SGPRRegBankID); 4401 4402 // TODO: Should report 32-bit for scalar condition type. 4403 if (Size == 64) { 4404 OpdsMapping[0] = AMDGPU::getValueMappingSGPR64Only(Bank, Size); 4405 OpdsMapping[1] = AMDGPU::getValueMapping(CondBank, 1); 4406 OpdsMapping[2] = AMDGPU::getValueMappingSGPR64Only(Bank, Size); 4407 OpdsMapping[3] = AMDGPU::getValueMappingSGPR64Only(Bank, Size); 4408 } else { 4409 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, Size); 4410 OpdsMapping[1] = AMDGPU::getValueMapping(CondBank, 1); 4411 OpdsMapping[2] = AMDGPU::getValueMapping(Bank, Size); 4412 OpdsMapping[3] = AMDGPU::getValueMapping(Bank, Size); 4413 } 4414 4415 break; 4416 } 4417 4418 case AMDGPU::G_LOAD: 4419 case AMDGPU::G_ZEXTLOAD: 4420 case AMDGPU::G_SEXTLOAD: 4421 return getInstrMappingForLoad(MI); 4422 4423 case AMDGPU::G_ATOMICRMW_XCHG: 4424 case AMDGPU::G_ATOMICRMW_ADD: 4425 case AMDGPU::G_ATOMICRMW_SUB: 4426 case AMDGPU::G_ATOMICRMW_AND: 4427 case AMDGPU::G_ATOMICRMW_OR: 4428 case AMDGPU::G_ATOMICRMW_XOR: 4429 case AMDGPU::G_ATOMICRMW_MAX: 4430 case AMDGPU::G_ATOMICRMW_MIN: 4431 case AMDGPU::G_ATOMICRMW_UMAX: 4432 case AMDGPU::G_ATOMICRMW_UMIN: 4433 case AMDGPU::G_ATOMICRMW_FADD: 4434 case AMDGPU::G_AMDGPU_ATOMIC_CMPXCHG: 4435 case AMDGPU::G_AMDGPU_ATOMIC_INC: 4436 case AMDGPU::G_AMDGPU_ATOMIC_DEC: 4437 case AMDGPU::G_AMDGPU_ATOMIC_FMIN: 4438 case AMDGPU::G_AMDGPU_ATOMIC_FMAX: { 4439 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 4440 OpdsMapping[1] = getValueMappingForPtr(MRI, MI.getOperand(1).getReg()); 4441 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4442 break; 4443 } 4444 case AMDGPU::G_ATOMIC_CMPXCHG: { 4445 OpdsMapping[0] = getVGPROpMapping(MI.getOperand(0).getReg(), MRI, *TRI); 4446 OpdsMapping[1] = getValueMappingForPtr(MRI, MI.getOperand(1).getReg()); 4447 OpdsMapping[2] = getVGPROpMapping(MI.getOperand(2).getReg(), MRI, *TRI); 4448 OpdsMapping[3] = getVGPROpMapping(MI.getOperand(3).getReg(), MRI, *TRI); 4449 break; 4450 } 4451 case AMDGPU::G_BRCOND: { 4452 unsigned Bank = getRegBankID(MI.getOperand(0).getReg(), MRI, 4453 AMDGPU::SGPRRegBankID); 4454 assert(MRI.getType(MI.getOperand(0).getReg()).getSizeInBits() == 1); 4455 if (Bank != AMDGPU::SGPRRegBankID) 4456 Bank = AMDGPU::VCCRegBankID; 4457 4458 OpdsMapping[0] = AMDGPU::getValueMapping(Bank, 1); 4459 break; 4460 } 4461 } 4462 4463 return getInstructionMapping(/*ID*/1, /*Cost*/1, 4464 getOperandsMapping(OpdsMapping), 4465 MI.getNumOperands()); 4466 } 4467