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