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