brintos

brintos / llvm-project-archived public Read only

0
0
Text · 248.8 KiB · c575714 Raw
7185 lines · cpp
1//===- AMDGPUInstructionSelector.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-exception6//7//===----------------------------------------------------------------------===//8/// \file9/// This file implements the targeting of the InstructionSelector class for10/// AMDGPU.11/// \todo This should be generated by TableGen.12//===----------------------------------------------------------------------===//13 14#include "AMDGPUInstructionSelector.h"15#include "AMDGPU.h"16#include "AMDGPUGlobalISelUtils.h"17#include "AMDGPUInstrInfo.h"18#include "AMDGPURegisterBankInfo.h"19#include "AMDGPUTargetMachine.h"20#include "SIMachineFunctionInfo.h"21#include "Utils/AMDGPUBaseInfo.h"22#include "llvm/CodeGen/GlobalISel/GIMatchTableExecutorImpl.h"23#include "llvm/CodeGen/GlobalISel/GISelValueTracking.h"24#include "llvm/CodeGen/GlobalISel/GenericMachineInstrs.h"25#include "llvm/CodeGen/GlobalISel/MIPatternMatch.h"26#include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"27#include "llvm/CodeGen/MachineFrameInfo.h"28#include "llvm/IR/DiagnosticInfo.h"29#include "llvm/IR/IntrinsicsAMDGPU.h"30#include <optional>31 32#define DEBUG_TYPE "amdgpu-isel"33 34using namespace llvm;35using namespace MIPatternMatch;36 37#define GET_GLOBALISEL_IMPL38#define AMDGPUSubtarget GCNSubtarget39#include "AMDGPUGenGlobalISel.inc"40#undef GET_GLOBALISEL_IMPL41#undef AMDGPUSubtarget42 43AMDGPUInstructionSelector::AMDGPUInstructionSelector(44    const GCNSubtarget &STI, const AMDGPURegisterBankInfo &RBI,45    const AMDGPUTargetMachine &TM)46    : TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI), TM(TM),47      STI(STI),48#define GET_GLOBALISEL_PREDICATES_INIT49#include "AMDGPUGenGlobalISel.inc"50#undef GET_GLOBALISEL_PREDICATES_INIT51#define GET_GLOBALISEL_TEMPORARIES_INIT52#include "AMDGPUGenGlobalISel.inc"53#undef GET_GLOBALISEL_TEMPORARIES_INIT54{55}56 57const char *AMDGPUInstructionSelector::getName() { return DEBUG_TYPE; }58 59void AMDGPUInstructionSelector::setupMF(MachineFunction &MF,60                                        GISelValueTracking *VT,61                                        CodeGenCoverage *CoverageInfo,62                                        ProfileSummaryInfo *PSI,63                                        BlockFrequencyInfo *BFI) {64  MRI = &MF.getRegInfo();65  Subtarget = &MF.getSubtarget<GCNSubtarget>();66  Subtarget->checkSubtargetFeatures(MF.getFunction());67  InstructionSelector::setupMF(MF, VT, CoverageInfo, PSI, BFI);68}69 70// Return the wave level SGPR base address if this is a wave address.71static Register getWaveAddress(const MachineInstr *Def) {72  return Def->getOpcode() == AMDGPU::G_AMDGPU_WAVE_ADDRESS73             ? Def->getOperand(1).getReg()74             : Register();75}76 77bool AMDGPUInstructionSelector::isVCC(Register Reg,78                                      const MachineRegisterInfo &MRI) const {79  // The verifier is oblivious to s1 being a valid value for wavesize registers.80  if (Reg.isPhysical())81    return false;82 83  auto &RegClassOrBank = MRI.getRegClassOrRegBank(Reg);84  const TargetRegisterClass *RC =85      dyn_cast<const TargetRegisterClass *>(RegClassOrBank);86  if (RC) {87    const LLT Ty = MRI.getType(Reg);88    if (!Ty.isValid() || Ty.getSizeInBits() != 1)89      return false;90    // G_TRUNC s1 result is never vcc.91    return MRI.getVRegDef(Reg)->getOpcode() != AMDGPU::G_TRUNC &&92           RC->hasSuperClassEq(TRI.getBoolRC());93  }94 95  const RegisterBank *RB = cast<const RegisterBank *>(RegClassOrBank);96  return RB->getID() == AMDGPU::VCCRegBankID;97}98 99bool AMDGPUInstructionSelector::constrainCopyLikeIntrin(MachineInstr &MI,100                                                        unsigned NewOpc) const {101  MI.setDesc(TII.get(NewOpc));102  MI.removeOperand(1); // Remove intrinsic ID.103  MI.addOperand(*MF, MachineOperand::CreateReg(AMDGPU::EXEC, false, true));104 105  MachineOperand &Dst = MI.getOperand(0);106  MachineOperand &Src = MI.getOperand(1);107 108  // TODO: This should be legalized to s32 if needed109  if (MRI->getType(Dst.getReg()) == LLT::scalar(1))110    return false;111 112  const TargetRegisterClass *DstRC113    = TRI.getConstrainedRegClassForOperand(Dst, *MRI);114  const TargetRegisterClass *SrcRC115    = TRI.getConstrainedRegClassForOperand(Src, *MRI);116  if (!DstRC || DstRC != SrcRC)117    return false;118 119  if (!RBI.constrainGenericRegister(Dst.getReg(), *DstRC, *MRI) ||120      !RBI.constrainGenericRegister(Src.getReg(), *SrcRC, *MRI))121    return false;122  const MCInstrDesc &MCID = MI.getDesc();123  if (MCID.getOperandConstraint(0, MCOI::EARLY_CLOBBER) != -1) {124    MI.getOperand(0).setIsEarlyClobber(true);125  }126  return true;127}128 129bool AMDGPUInstructionSelector::selectCOPY(MachineInstr &I) const {130  const DebugLoc &DL = I.getDebugLoc();131  MachineBasicBlock *BB = I.getParent();132  I.setDesc(TII.get(TargetOpcode::COPY));133 134  const MachineOperand &Src = I.getOperand(1);135  MachineOperand &Dst = I.getOperand(0);136  Register DstReg = Dst.getReg();137  Register SrcReg = Src.getReg();138 139  if (isVCC(DstReg, *MRI)) {140    if (SrcReg == AMDGPU::SCC) {141      const TargetRegisterClass *RC142        = TRI.getConstrainedRegClassForOperand(Dst, *MRI);143      if (!RC)144        return true;145      return RBI.constrainGenericRegister(DstReg, *RC, *MRI);146    }147 148    if (!isVCC(SrcReg, *MRI)) {149      // TODO: Should probably leave the copy and let copyPhysReg expand it.150      if (!RBI.constrainGenericRegister(DstReg, *TRI.getBoolRC(), *MRI))151        return false;152 153      const TargetRegisterClass *SrcRC154        = TRI.getConstrainedRegClassForOperand(Src, *MRI);155 156      std::optional<ValueAndVReg> ConstVal =157          getIConstantVRegValWithLookThrough(SrcReg, *MRI, true);158      if (ConstVal) {159        unsigned MovOpc =160            STI.isWave64() ? AMDGPU::S_MOV_B64 : AMDGPU::S_MOV_B32;161        BuildMI(*BB, &I, DL, TII.get(MovOpc), DstReg)162            .addImm(ConstVal->Value.getBoolValue() ? -1 : 0);163      } else {164        Register MaskedReg = MRI->createVirtualRegister(SrcRC);165 166        // We can't trust the high bits at this point, so clear them.167 168        // TODO: Skip masking high bits if def is known boolean.169 170        if (AMDGPU::getRegBitWidth(SrcRC->getID()) == 16) {171          assert(Subtarget->useRealTrue16Insts());172          const int64_t NoMods = 0;173          BuildMI(*BB, &I, DL, TII.get(AMDGPU::V_AND_B16_t16_e64), MaskedReg)174              .addImm(NoMods)175              .addImm(1)176              .addImm(NoMods)177              .addReg(SrcReg)178              .addImm(NoMods);179          BuildMI(*BB, &I, DL, TII.get(AMDGPU::V_CMP_NE_U16_t16_e64), DstReg)180              .addImm(NoMods)181              .addImm(0)182              .addImm(NoMods)183              .addReg(MaskedReg)184              .addImm(NoMods);185        } else {186          bool IsSGPR = TRI.isSGPRClass(SrcRC);187          unsigned AndOpc = IsSGPR ? AMDGPU::S_AND_B32 : AMDGPU::V_AND_B32_e32;188          auto And = BuildMI(*BB, &I, DL, TII.get(AndOpc), MaskedReg)189                         .addImm(1)190                         .addReg(SrcReg);191          if (IsSGPR)192            And.setOperandDead(3); // Dead scc193 194          BuildMI(*BB, &I, DL, TII.get(AMDGPU::V_CMP_NE_U32_e64), DstReg)195              .addImm(0)196              .addReg(MaskedReg);197        }198      }199 200      if (!MRI->getRegClassOrNull(SrcReg))201        MRI->setRegClass(SrcReg, SrcRC);202      I.eraseFromParent();203      return true;204    }205 206    const TargetRegisterClass *RC =207      TRI.getConstrainedRegClassForOperand(Dst, *MRI);208    if (RC && !RBI.constrainGenericRegister(DstReg, *RC, *MRI))209      return false;210 211    return true;212  }213 214  for (const MachineOperand &MO : I.operands()) {215    if (MO.getReg().isPhysical())216      continue;217 218    const TargetRegisterClass *RC =219            TRI.getConstrainedRegClassForOperand(MO, *MRI);220    if (!RC)221      continue;222    RBI.constrainGenericRegister(MO.getReg(), *RC, *MRI);223  }224  return true;225}226 227bool AMDGPUInstructionSelector::selectCOPY_SCC_VCC(MachineInstr &I) const {228  const DebugLoc &DL = I.getDebugLoc();229  MachineBasicBlock *BB = I.getParent();230  Register VCCReg = I.getOperand(1).getReg();231  MachineInstr *Cmp;232 233  // Set SCC as a side effect with S_CMP or S_OR.234  if (STI.hasScalarCompareEq64()) {235    unsigned CmpOpc =236        STI.isWave64() ? AMDGPU::S_CMP_LG_U64 : AMDGPU::S_CMP_LG_U32;237    Cmp = BuildMI(*BB, &I, DL, TII.get(CmpOpc)).addReg(VCCReg).addImm(0);238  } else {239    Register DeadDst = MRI->createVirtualRegister(&AMDGPU::SReg_64RegClass);240    Cmp = BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_OR_B64), DeadDst)241              .addReg(VCCReg)242              .addReg(VCCReg);243  }244 245  if (!constrainSelectedInstRegOperands(*Cmp, TII, TRI, RBI))246    return false;247 248  Register DstReg = I.getOperand(0).getReg();249  BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), DstReg).addReg(AMDGPU::SCC);250 251  I.eraseFromParent();252  return RBI.constrainGenericRegister(DstReg, AMDGPU::SReg_32RegClass, *MRI);253}254 255bool AMDGPUInstructionSelector::selectCOPY_VCC_SCC(MachineInstr &I) const {256  const DebugLoc &DL = I.getDebugLoc();257  MachineBasicBlock *BB = I.getParent();258 259  Register DstReg = I.getOperand(0).getReg();260  Register SrcReg = I.getOperand(1).getReg();261  std::optional<ValueAndVReg> Arg =262      getIConstantVRegValWithLookThrough(I.getOperand(1).getReg(), *MRI);263 264  if (Arg) {265    const int64_t Value = Arg->Value.getZExtValue();266    if (Value == 0) {267      unsigned Opcode = STI.isWave64() ? AMDGPU::S_MOV_B64 : AMDGPU::S_MOV_B32;268      BuildMI(*BB, &I, DL, TII.get(Opcode), DstReg).addImm(0);269    } else {270      assert(Value == 1);271      BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), DstReg).addReg(TRI.getExec());272    }273    I.eraseFromParent();274    return RBI.constrainGenericRegister(DstReg, *TRI.getBoolRC(), *MRI);275  }276 277  // RegBankLegalize ensures that SrcReg is bool in reg (high bits are 0).278  BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), AMDGPU::SCC).addReg(SrcReg);279 280  unsigned SelectOpcode =281      STI.isWave64() ? AMDGPU::S_CSELECT_B64 : AMDGPU::S_CSELECT_B32;282  MachineInstr *Select = BuildMI(*BB, &I, DL, TII.get(SelectOpcode), DstReg)283                             .addReg(TRI.getExec())284                             .addImm(0);285 286  I.eraseFromParent();287  return constrainSelectedInstRegOperands(*Select, TII, TRI, RBI);288}289 290bool AMDGPUInstructionSelector::selectReadAnyLane(MachineInstr &I) const {291  Register DstReg = I.getOperand(0).getReg();292  Register SrcReg = I.getOperand(1).getReg();293 294  const DebugLoc &DL = I.getDebugLoc();295  MachineBasicBlock *BB = I.getParent();296 297  auto RFL = BuildMI(*BB, &I, DL, TII.get(AMDGPU::V_READFIRSTLANE_B32), DstReg)298                 .addReg(SrcReg);299 300  I.eraseFromParent();301  return constrainSelectedInstRegOperands(*RFL, TII, TRI, RBI);302}303 304bool AMDGPUInstructionSelector::selectPHI(MachineInstr &I) const {305  const Register DefReg = I.getOperand(0).getReg();306  const LLT DefTy = MRI->getType(DefReg);307 308  // S1 G_PHIs should not be selected in instruction-select, instead:309  // - divergent S1 G_PHI should go through lane mask merging algorithm310  //   and be fully inst-selected in AMDGPUGlobalISelDivergenceLowering311  // - uniform S1 G_PHI should be lowered into S32 G_PHI in AMDGPURegBankSelect312  if (DefTy == LLT::scalar(1))313    return false;314 315  // TODO: Verify this doesn't have insane operands (i.e. VGPR to SGPR copy)316 317  const RegClassOrRegBank &RegClassOrBank =318    MRI->getRegClassOrRegBank(DefReg);319 320  const TargetRegisterClass *DefRC =321      dyn_cast<const TargetRegisterClass *>(RegClassOrBank);322  if (!DefRC) {323    if (!DefTy.isValid()) {324      LLVM_DEBUG(dbgs() << "PHI operand has no type, not a gvreg?\n");325      return false;326    }327 328    const RegisterBank &RB = *cast<const RegisterBank *>(RegClassOrBank);329    DefRC = TRI.getRegClassForTypeOnBank(DefTy, RB);330    if (!DefRC) {331      LLVM_DEBUG(dbgs() << "PHI operand has unexpected size/bank\n");332      return false;333    }334  }335 336  // If inputs have register bank, assign corresponding reg class.337  // Note: registers don't need to have the same reg bank.338  for (unsigned i = 1; i != I.getNumOperands(); i += 2) {339    const Register SrcReg = I.getOperand(i).getReg();340 341    const RegisterBank *RB = MRI->getRegBankOrNull(SrcReg);342    if (RB) {343      const LLT SrcTy = MRI->getType(SrcReg);344      const TargetRegisterClass *SrcRC =345          TRI.getRegClassForTypeOnBank(SrcTy, *RB);346      if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI))347        return false;348    }349  }350 351  I.setDesc(TII.get(TargetOpcode::PHI));352  return RBI.constrainGenericRegister(DefReg, *DefRC, *MRI);353}354 355MachineOperand356AMDGPUInstructionSelector::getSubOperand64(MachineOperand &MO,357                                           const TargetRegisterClass &SubRC,358                                           unsigned SubIdx) const {359 360  MachineInstr *MI = MO.getParent();361  MachineBasicBlock *BB = MO.getParent()->getParent();362  Register DstReg = MRI->createVirtualRegister(&SubRC);363 364  if (MO.isReg()) {365    unsigned ComposedSubIdx = TRI.composeSubRegIndices(MO.getSubReg(), SubIdx);366    Register Reg = MO.getReg();367    BuildMI(*BB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), DstReg)368            .addReg(Reg, 0, ComposedSubIdx);369 370    return MachineOperand::CreateReg(DstReg, MO.isDef(), MO.isImplicit(),371                                     MO.isKill(), MO.isDead(), MO.isUndef(),372                                     MO.isEarlyClobber(), 0, MO.isDebug(),373                                     MO.isInternalRead());374  }375 376  assert(MO.isImm());377 378  APInt Imm(64, MO.getImm());379 380  switch (SubIdx) {381  default:382    llvm_unreachable("do not know to split immediate with this sub index.");383  case AMDGPU::sub0:384    return MachineOperand::CreateImm(Imm.getLoBits(32).getSExtValue());385  case AMDGPU::sub1:386    return MachineOperand::CreateImm(Imm.getHiBits(32).getSExtValue());387  }388}389 390static unsigned getLogicalBitOpcode(unsigned Opc, bool Is64) {391  switch (Opc) {392  case AMDGPU::G_AND:393    return Is64 ? AMDGPU::S_AND_B64 : AMDGPU::S_AND_B32;394  case AMDGPU::G_OR:395    return Is64 ? AMDGPU::S_OR_B64 : AMDGPU::S_OR_B32;396  case AMDGPU::G_XOR:397    return Is64 ? AMDGPU::S_XOR_B64 : AMDGPU::S_XOR_B32;398  default:399    llvm_unreachable("not a bit op");400  }401}402 403bool AMDGPUInstructionSelector::selectG_AND_OR_XOR(MachineInstr &I) const {404  Register DstReg = I.getOperand(0).getReg();405  unsigned Size = RBI.getSizeInBits(DstReg, *MRI, TRI);406 407  const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);408  if (DstRB->getID() != AMDGPU::SGPRRegBankID &&409      DstRB->getID() != AMDGPU::VCCRegBankID)410    return false;411 412  bool Is64 = Size > 32 || (DstRB->getID() == AMDGPU::VCCRegBankID &&413                            STI.isWave64());414  I.setDesc(TII.get(getLogicalBitOpcode(I.getOpcode(), Is64)));415 416  // Dead implicit-def of scc417  I.addOperand(MachineOperand::CreateReg(AMDGPU::SCC, true, // isDef418                                         true, // isImp419                                         false, // isKill420                                         true)); // isDead421  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);422}423 424bool AMDGPUInstructionSelector::selectG_ADD_SUB(MachineInstr &I) const {425  MachineBasicBlock *BB = I.getParent();426  MachineFunction *MF = BB->getParent();427  Register DstReg = I.getOperand(0).getReg();428  const DebugLoc &DL = I.getDebugLoc();429  LLT Ty = MRI->getType(DstReg);430  if (Ty.isVector())431    return false;432 433  unsigned Size = Ty.getSizeInBits();434  const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);435  const bool IsSALU = DstRB->getID() == AMDGPU::SGPRRegBankID;436  const bool Sub = I.getOpcode() == TargetOpcode::G_SUB;437 438  if (Size == 32) {439    if (IsSALU) {440      const unsigned Opc = Sub ? AMDGPU::S_SUB_U32 : AMDGPU::S_ADD_U32;441      MachineInstr *Add =442        BuildMI(*BB, &I, DL, TII.get(Opc), DstReg)443        .add(I.getOperand(1))444        .add(I.getOperand(2))445        .setOperandDead(3); // Dead scc446      I.eraseFromParent();447      return constrainSelectedInstRegOperands(*Add, TII, TRI, RBI);448    }449 450    if (STI.hasAddNoCarry()) {451      const unsigned Opc = Sub ? AMDGPU::V_SUB_U32_e64 : AMDGPU::V_ADD_U32_e64;452      I.setDesc(TII.get(Opc));453      I.addOperand(*MF, MachineOperand::CreateImm(0));454      I.addOperand(*MF, MachineOperand::CreateReg(AMDGPU::EXEC, false, true));455      return constrainSelectedInstRegOperands(I, TII, TRI, RBI);456    }457 458    const unsigned Opc = Sub ? AMDGPU::V_SUB_CO_U32_e64 : AMDGPU::V_ADD_CO_U32_e64;459 460    Register UnusedCarry = MRI->createVirtualRegister(TRI.getWaveMaskRegClass());461    MachineInstr *Add462      = BuildMI(*BB, &I, DL, TII.get(Opc), DstReg)463      .addDef(UnusedCarry, RegState::Dead)464      .add(I.getOperand(1))465      .add(I.getOperand(2))466      .addImm(0);467    I.eraseFromParent();468    return constrainSelectedInstRegOperands(*Add, TII, TRI, RBI);469  }470 471  assert(!Sub && "illegal sub should not reach here");472 473  const TargetRegisterClass &RC474    = IsSALU ? AMDGPU::SReg_64_XEXECRegClass : AMDGPU::VReg_64RegClass;475  const TargetRegisterClass &HalfRC476    = IsSALU ? AMDGPU::SReg_32RegClass : AMDGPU::VGPR_32RegClass;477 478  MachineOperand Lo1(getSubOperand64(I.getOperand(1), HalfRC, AMDGPU::sub0));479  MachineOperand Lo2(getSubOperand64(I.getOperand(2), HalfRC, AMDGPU::sub0));480  MachineOperand Hi1(getSubOperand64(I.getOperand(1), HalfRC, AMDGPU::sub1));481  MachineOperand Hi2(getSubOperand64(I.getOperand(2), HalfRC, AMDGPU::sub1));482 483  Register DstLo = MRI->createVirtualRegister(&HalfRC);484  Register DstHi = MRI->createVirtualRegister(&HalfRC);485 486  if (IsSALU) {487    BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADD_U32), DstLo)488      .add(Lo1)489      .add(Lo2);490    BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADDC_U32), DstHi)491      .add(Hi1)492      .add(Hi2)493      .setOperandDead(3); // Dead scc494  } else {495    const TargetRegisterClass *CarryRC = TRI.getWaveMaskRegClass();496    Register CarryReg = MRI->createVirtualRegister(CarryRC);497    BuildMI(*BB, &I, DL, TII.get(AMDGPU::V_ADD_CO_U32_e64), DstLo)498      .addDef(CarryReg)499      .add(Lo1)500      .add(Lo2)501      .addImm(0);502    MachineInstr *Addc = BuildMI(*BB, &I, DL, TII.get(AMDGPU::V_ADDC_U32_e64), DstHi)503      .addDef(MRI->createVirtualRegister(CarryRC), RegState::Dead)504      .add(Hi1)505      .add(Hi2)506      .addReg(CarryReg, RegState::Kill)507      .addImm(0);508 509    if (!constrainSelectedInstRegOperands(*Addc, TII, TRI, RBI))510      return false;511  }512 513  BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)514    .addReg(DstLo)515    .addImm(AMDGPU::sub0)516    .addReg(DstHi)517    .addImm(AMDGPU::sub1);518 519 520  if (!RBI.constrainGenericRegister(DstReg, RC, *MRI))521    return false;522 523  I.eraseFromParent();524  return true;525}526 527bool AMDGPUInstructionSelector::selectG_UADDO_USUBO_UADDE_USUBE(528  MachineInstr &I) const {529  MachineBasicBlock *BB = I.getParent();530  MachineFunction *MF = BB->getParent();531  const DebugLoc &DL = I.getDebugLoc();532  Register Dst0Reg = I.getOperand(0).getReg();533  Register Dst1Reg = I.getOperand(1).getReg();534  const bool IsAdd = I.getOpcode() == AMDGPU::G_UADDO ||535                     I.getOpcode() == AMDGPU::G_UADDE;536  const bool HasCarryIn = I.getOpcode() == AMDGPU::G_UADDE ||537                          I.getOpcode() == AMDGPU::G_USUBE;538 539  if (isVCC(Dst1Reg, *MRI)) {540    unsigned NoCarryOpc =541        IsAdd ? AMDGPU::V_ADD_CO_U32_e64 : AMDGPU::V_SUB_CO_U32_e64;542    unsigned CarryOpc = IsAdd ? AMDGPU::V_ADDC_U32_e64 : AMDGPU::V_SUBB_U32_e64;543    I.setDesc(TII.get(HasCarryIn ? CarryOpc : NoCarryOpc));544    I.addOperand(*MF, MachineOperand::CreateReg(AMDGPU::EXEC, false, true));545    I.addOperand(*MF, MachineOperand::CreateImm(0));546    return constrainSelectedInstRegOperands(I, TII, TRI, RBI);547  }548 549  Register Src0Reg = I.getOperand(2).getReg();550  Register Src1Reg = I.getOperand(3).getReg();551 552  if (HasCarryIn) {553    BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), AMDGPU::SCC)554      .addReg(I.getOperand(4).getReg());555  }556 557  unsigned NoCarryOpc = IsAdd ? AMDGPU::S_ADD_U32 : AMDGPU::S_SUB_U32;558  unsigned CarryOpc = IsAdd ? AMDGPU::S_ADDC_U32 : AMDGPU::S_SUBB_U32;559 560  auto CarryInst = BuildMI(*BB, &I, DL, TII.get(HasCarryIn ? CarryOpc : NoCarryOpc), Dst0Reg)561    .add(I.getOperand(2))562    .add(I.getOperand(3));563 564  if (MRI->use_nodbg_empty(Dst1Reg)) {565    CarryInst.setOperandDead(3); // Dead scc566  } else {567    BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), Dst1Reg)568      .addReg(AMDGPU::SCC);569    if (!MRI->getRegClassOrNull(Dst1Reg))570      MRI->setRegClass(Dst1Reg, &AMDGPU::SReg_32RegClass);571  }572 573  if (!RBI.constrainGenericRegister(Dst0Reg, AMDGPU::SReg_32RegClass, *MRI) ||574      !RBI.constrainGenericRegister(Src0Reg, AMDGPU::SReg_32RegClass, *MRI) ||575      !RBI.constrainGenericRegister(Src1Reg, AMDGPU::SReg_32RegClass, *MRI))576    return false;577 578  if (HasCarryIn &&579      !RBI.constrainGenericRegister(I.getOperand(4).getReg(),580                                    AMDGPU::SReg_32RegClass, *MRI))581    return false;582 583  I.eraseFromParent();584  return true;585}586 587bool AMDGPUInstructionSelector::selectG_AMDGPU_MAD_64_32(588    MachineInstr &I) const {589  MachineBasicBlock *BB = I.getParent();590  MachineFunction *MF = BB->getParent();591  const bool IsUnsigned = I.getOpcode() == AMDGPU::G_AMDGPU_MAD_U64_U32;592  bool UseNoCarry = Subtarget->hasMadU64U32NoCarry() &&593                    MRI->use_nodbg_empty(I.getOperand(1).getReg());594 595  unsigned Opc;596  if (Subtarget->hasMADIntraFwdBug())597    Opc = IsUnsigned ? AMDGPU::V_MAD_U64_U32_gfx11_e64598                     : AMDGPU::V_MAD_I64_I32_gfx11_e64;599  else if (UseNoCarry)600    Opc = IsUnsigned ? AMDGPU::V_MAD_NC_U64_U32_e64601                     : AMDGPU::V_MAD_NC_I64_I32_e64;602  else603    Opc = IsUnsigned ? AMDGPU::V_MAD_U64_U32_e64 : AMDGPU::V_MAD_I64_I32_e64;604 605  if (UseNoCarry)606    I.removeOperand(1);607 608  I.setDesc(TII.get(Opc));609  I.addOperand(*MF, MachineOperand::CreateImm(0));610  I.addImplicitDefUseOperands(*MF);611  I.getOperand(0).setIsEarlyClobber(true);612  return constrainSelectedInstRegOperands(I, TII, TRI, RBI);613}614 615// TODO: We should probably legalize these to only using 32-bit results.616bool AMDGPUInstructionSelector::selectG_EXTRACT(MachineInstr &I) const {617  MachineBasicBlock *BB = I.getParent();618  Register DstReg = I.getOperand(0).getReg();619  Register SrcReg = I.getOperand(1).getReg();620  LLT DstTy = MRI->getType(DstReg);621  LLT SrcTy = MRI->getType(SrcReg);622  const unsigned SrcSize = SrcTy.getSizeInBits();623  unsigned DstSize = DstTy.getSizeInBits();624 625  // TODO: Should handle any multiple of 32 offset.626  unsigned Offset = I.getOperand(2).getImm();627  if (Offset % 32 != 0 || DstSize > 128)628    return false;629 630  // 16-bit operations really use 32-bit registers.631  // FIXME: Probably should not allow 16-bit G_EXTRACT results.632  if (DstSize == 16)633    DstSize = 32;634 635  const TargetRegisterClass *DstRC =636    TRI.getConstrainedRegClassForOperand(I.getOperand(0), *MRI);637  if (!DstRC || !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))638    return false;639 640  const RegisterBank *SrcBank = RBI.getRegBank(SrcReg, *MRI, TRI);641  const TargetRegisterClass *SrcRC =642      TRI.getRegClassForSizeOnBank(SrcSize, *SrcBank);643  if (!SrcRC)644    return false;645  unsigned SubReg = SIRegisterInfo::getSubRegFromChannel(Offset / 32,646                                                         DstSize / 32);647  SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubReg);648  if (!SrcRC)649    return false;650 651  SrcReg = constrainOperandRegClass(*MF, TRI, *MRI, TII, RBI, I,652                                    *SrcRC, I.getOperand(1));653  const DebugLoc &DL = I.getDebugLoc();654  BuildMI(*BB, &I, DL, TII.get(TargetOpcode::COPY), DstReg)655    .addReg(SrcReg, 0, SubReg);656 657  I.eraseFromParent();658  return true;659}660 661bool AMDGPUInstructionSelector::selectG_MERGE_VALUES(MachineInstr &MI) const {662  MachineBasicBlock *BB = MI.getParent();663  Register DstReg = MI.getOperand(0).getReg();664  LLT DstTy = MRI->getType(DstReg);665  LLT SrcTy = MRI->getType(MI.getOperand(1).getReg());666 667  const unsigned SrcSize = SrcTy.getSizeInBits();668  if (SrcSize < 32)669    return selectImpl(MI, *CoverageInfo);670 671  const DebugLoc &DL = MI.getDebugLoc();672  const RegisterBank *DstBank = RBI.getRegBank(DstReg, *MRI, TRI);673  const unsigned DstSize = DstTy.getSizeInBits();674  const TargetRegisterClass *DstRC =675      TRI.getRegClassForSizeOnBank(DstSize, *DstBank);676  if (!DstRC)677    return false;678 679  ArrayRef<int16_t> SubRegs = TRI.getRegSplitParts(DstRC, SrcSize / 8);680  MachineInstrBuilder MIB =681    BuildMI(*BB, &MI, DL, TII.get(TargetOpcode::REG_SEQUENCE), DstReg);682  for (int I = 0, E = MI.getNumOperands() - 1; I != E; ++I) {683    MachineOperand &Src = MI.getOperand(I + 1);684    MIB.addReg(Src.getReg(), getUndefRegState(Src.isUndef()));685    MIB.addImm(SubRegs[I]);686 687    const TargetRegisterClass *SrcRC688      = TRI.getConstrainedRegClassForOperand(Src, *MRI);689    if (SrcRC && !RBI.constrainGenericRegister(Src.getReg(), *SrcRC, *MRI))690      return false;691  }692 693  if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))694    return false;695 696  MI.eraseFromParent();697  return true;698}699 700bool AMDGPUInstructionSelector::selectG_UNMERGE_VALUES(MachineInstr &MI) const {701  MachineBasicBlock *BB = MI.getParent();702  const int NumDst = MI.getNumOperands() - 1;703 704  MachineOperand &Src = MI.getOperand(NumDst);705 706  Register SrcReg = Src.getReg();707  Register DstReg0 = MI.getOperand(0).getReg();708  LLT DstTy = MRI->getType(DstReg0);709  LLT SrcTy = MRI->getType(SrcReg);710 711  const unsigned DstSize = DstTy.getSizeInBits();712  const unsigned SrcSize = SrcTy.getSizeInBits();713  const DebugLoc &DL = MI.getDebugLoc();714  const RegisterBank *SrcBank = RBI.getRegBank(SrcReg, *MRI, TRI);715 716  const TargetRegisterClass *SrcRC =717      TRI.getRegClassForSizeOnBank(SrcSize, *SrcBank);718  if (!SrcRC || !RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI))719    return false;720 721  // Note we could have mixed SGPR and VGPR destination banks for an SGPR722  // source, and this relies on the fact that the same subregister indices are723  // used for both.724  ArrayRef<int16_t> SubRegs = TRI.getRegSplitParts(SrcRC, DstSize / 8);725  for (int I = 0, E = NumDst; I != E; ++I) {726    MachineOperand &Dst = MI.getOperand(I);727    BuildMI(*BB, &MI, DL, TII.get(TargetOpcode::COPY), Dst.getReg())728      .addReg(SrcReg, 0, SubRegs[I]);729 730    // Make sure the subregister index is valid for the source register.731    SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubRegs[I]);732    if (!SrcRC || !RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI))733      return false;734 735    const TargetRegisterClass *DstRC =736      TRI.getConstrainedRegClassForOperand(Dst, *MRI);737    if (DstRC && !RBI.constrainGenericRegister(Dst.getReg(), *DstRC, *MRI))738      return false;739  }740 741  MI.eraseFromParent();742  return true;743}744 745bool AMDGPUInstructionSelector::selectG_BUILD_VECTOR(MachineInstr &MI) const {746  assert(MI.getOpcode() == AMDGPU::G_BUILD_VECTOR_TRUNC ||747         MI.getOpcode() == AMDGPU::G_BUILD_VECTOR);748 749  Register Src0 = MI.getOperand(1).getReg();750  Register Src1 = MI.getOperand(2).getReg();751  LLT SrcTy = MRI->getType(Src0);752  const unsigned SrcSize = SrcTy.getSizeInBits();753 754  // BUILD_VECTOR with >=32 bits source is handled by MERGE_VALUE.755  if (MI.getOpcode() == AMDGPU::G_BUILD_VECTOR && SrcSize >= 32) {756    return selectG_MERGE_VALUES(MI);757  }758 759  // Selection logic below is for V2S16 only.760  // For G_BUILD_VECTOR_TRUNC, additionally check that the operands are s32.761  Register Dst = MI.getOperand(0).getReg();762  if (MRI->getType(Dst) != LLT::fixed_vector(2, 16) ||763      (MI.getOpcode() == AMDGPU::G_BUILD_VECTOR_TRUNC &&764       SrcTy != LLT::scalar(32)))765    return selectImpl(MI, *CoverageInfo);766 767  const RegisterBank *DstBank = RBI.getRegBank(Dst, *MRI, TRI);768  if (DstBank->getID() == AMDGPU::AGPRRegBankID)769    return false;770 771  assert(DstBank->getID() == AMDGPU::SGPRRegBankID ||772         DstBank->getID() == AMDGPU::VGPRRegBankID);773  const bool IsVector = DstBank->getID() == AMDGPU::VGPRRegBankID;774 775  const DebugLoc &DL = MI.getDebugLoc();776  MachineBasicBlock *BB = MI.getParent();777 778  // First, before trying TableGen patterns, check if both sources are779  // constants. In those cases, we can trivially compute the final constant780  // and emit a simple move.781  auto ConstSrc1 = getAnyConstantVRegValWithLookThrough(Src1, *MRI, true, true);782  if (ConstSrc1) {783    auto ConstSrc0 =784        getAnyConstantVRegValWithLookThrough(Src0, *MRI, true, true);785    if (ConstSrc0) {786      const int64_t K0 = ConstSrc0->Value.getSExtValue();787      const int64_t K1 = ConstSrc1->Value.getSExtValue();788      uint32_t Lo16 = static_cast<uint32_t>(K0) & 0xffff;789      uint32_t Hi16 = static_cast<uint32_t>(K1) & 0xffff;790      uint32_t Imm = Lo16 | (Hi16 << 16);791 792      // VALU793      if (IsVector) {794        BuildMI(*BB, &MI, DL, TII.get(AMDGPU::V_MOV_B32_e32), Dst).addImm(Imm);795        MI.eraseFromParent();796        return RBI.constrainGenericRegister(Dst, AMDGPU::VGPR_32RegClass, *MRI);797      }798 799      // SALU800      BuildMI(*BB, &MI, DL, TII.get(AMDGPU::S_MOV_B32), Dst).addImm(Imm);801      MI.eraseFromParent();802      return RBI.constrainGenericRegister(Dst, AMDGPU::SReg_32RegClass, *MRI);803    }804  }805 806  // Now try TableGen patterns.807  if (selectImpl(MI, *CoverageInfo))808    return true;809 810  // TODO: This should probably be a combine somewhere811  // (build_vector $src0, undef) -> copy $src0812  MachineInstr *Src1Def = getDefIgnoringCopies(Src1, *MRI);813  if (Src1Def->getOpcode() == AMDGPU::G_IMPLICIT_DEF) {814    MI.setDesc(TII.get(AMDGPU::COPY));815    MI.removeOperand(2);816    const auto &RC =817        IsVector ? AMDGPU::VGPR_32RegClass : AMDGPU::SReg_32RegClass;818    return RBI.constrainGenericRegister(Dst, RC, *MRI) &&819           RBI.constrainGenericRegister(Src0, RC, *MRI);820  }821 822  // TODO: Can be improved?823  if (IsVector) {824    Register TmpReg = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);825    auto MIB = BuildMI(*BB, MI, DL, TII.get(AMDGPU::V_AND_B32_e32), TmpReg)826                   .addImm(0xFFFF)827                   .addReg(Src0);828    if (!constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI))829      return false;830 831    MIB = BuildMI(*BB, MI, DL, TII.get(AMDGPU::V_LSHL_OR_B32_e64), Dst)832              .addReg(Src1)833              .addImm(16)834              .addReg(TmpReg);835    if (!constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI))836      return false;837 838    MI.eraseFromParent();839    return true;840  }841 842  Register ShiftSrc0;843  Register ShiftSrc1;844 845  // With multiple uses of the shift, this will duplicate the shift and846  // increase register pressure.847  //848  // (build_vector (lshr_oneuse $src0, 16), (lshr_oneuse $src1, 16)849  //  => (S_PACK_HH_B32_B16 $src0, $src1)850  // (build_vector (lshr_oneuse SReg_32:$src0, 16), $src1)851  //  => (S_PACK_HL_B32_B16 $src0, $src1)852  // (build_vector $src0, (lshr_oneuse SReg_32:$src1, 16))853  //  => (S_PACK_LH_B32_B16 $src0, $src1)854  // (build_vector $src0, $src1)855  //  => (S_PACK_LL_B32_B16 $src0, $src1)856 857  bool Shift0 = mi_match(858      Src0, *MRI, m_OneUse(m_GLShr(m_Reg(ShiftSrc0), m_SpecificICst(16))));859 860  bool Shift1 = mi_match(861      Src1, *MRI, m_OneUse(m_GLShr(m_Reg(ShiftSrc1), m_SpecificICst(16))));862 863  unsigned Opc = AMDGPU::S_PACK_LL_B32_B16;864  if (Shift0 && Shift1) {865    Opc = AMDGPU::S_PACK_HH_B32_B16;866    MI.getOperand(1).setReg(ShiftSrc0);867    MI.getOperand(2).setReg(ShiftSrc1);868  } else if (Shift1) {869    Opc = AMDGPU::S_PACK_LH_B32_B16;870    MI.getOperand(2).setReg(ShiftSrc1);871  } else if (Shift0) {872    auto ConstSrc1 =873        getAnyConstantVRegValWithLookThrough(Src1, *MRI, true, true);874    if (ConstSrc1 && ConstSrc1->Value == 0) {875      // build_vector_trunc (lshr $src0, 16), 0 -> s_lshr_b32 $src0, 16876      auto MIB = BuildMI(*BB, &MI, DL, TII.get(AMDGPU::S_LSHR_B32), Dst)877                     .addReg(ShiftSrc0)878                     .addImm(16)879                     .setOperandDead(3); // Dead scc880 881      MI.eraseFromParent();882      return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);883    }884    if (STI.hasSPackHL()) {885      Opc = AMDGPU::S_PACK_HL_B32_B16;886      MI.getOperand(1).setReg(ShiftSrc0);887    }888  }889 890  MI.setDesc(TII.get(Opc));891  return constrainSelectedInstRegOperands(MI, TII, TRI, RBI);892}893 894bool AMDGPUInstructionSelector::selectG_IMPLICIT_DEF(MachineInstr &I) const {895  const MachineOperand &MO = I.getOperand(0);896 897  // FIXME: Interface for getConstrainedRegClassForOperand needs work. The898  // regbank check here is to know why getConstrainedRegClassForOperand failed.899  const TargetRegisterClass *RC = TRI.getConstrainedRegClassForOperand(MO, *MRI);900  if ((!RC && !MRI->getRegBankOrNull(MO.getReg())) ||901      (RC && RBI.constrainGenericRegister(MO.getReg(), *RC, *MRI))) {902    I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));903    return true;904  }905 906  return false;907}908 909bool AMDGPUInstructionSelector::selectG_INSERT(MachineInstr &I) const {910  MachineBasicBlock *BB = I.getParent();911 912  Register DstReg = I.getOperand(0).getReg();913  Register Src0Reg = I.getOperand(1).getReg();914  Register Src1Reg = I.getOperand(2).getReg();915  LLT Src1Ty = MRI->getType(Src1Reg);916 917  unsigned DstSize = MRI->getType(DstReg).getSizeInBits();918  unsigned InsSize = Src1Ty.getSizeInBits();919 920  int64_t Offset = I.getOperand(3).getImm();921 922  // FIXME: These cases should have been illegal and unnecessary to check here.923  if (Offset % 32 != 0 || InsSize % 32 != 0)924    return false;925 926  // Currently not handled by getSubRegFromChannel.927  if (InsSize > 128)928    return false;929 930  unsigned SubReg = TRI.getSubRegFromChannel(Offset / 32, InsSize / 32);931  if (SubReg == AMDGPU::NoSubRegister)932    return false;933 934  const RegisterBank *DstBank = RBI.getRegBank(DstReg, *MRI, TRI);935  const TargetRegisterClass *DstRC =936      TRI.getRegClassForSizeOnBank(DstSize, *DstBank);937  if (!DstRC)938    return false;939 940  const RegisterBank *Src0Bank = RBI.getRegBank(Src0Reg, *MRI, TRI);941  const RegisterBank *Src1Bank = RBI.getRegBank(Src1Reg, *MRI, TRI);942  const TargetRegisterClass *Src0RC =943      TRI.getRegClassForSizeOnBank(DstSize, *Src0Bank);944  const TargetRegisterClass *Src1RC =945      TRI.getRegClassForSizeOnBank(InsSize, *Src1Bank);946 947  // Deal with weird cases where the class only partially supports the subreg948  // index.949  Src0RC = TRI.getSubClassWithSubReg(Src0RC, SubReg);950  if (!Src0RC || !Src1RC)951    return false;952 953  if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI) ||954      !RBI.constrainGenericRegister(Src0Reg, *Src0RC, *MRI) ||955      !RBI.constrainGenericRegister(Src1Reg, *Src1RC, *MRI))956    return false;957 958  const DebugLoc &DL = I.getDebugLoc();959  BuildMI(*BB, &I, DL, TII.get(TargetOpcode::INSERT_SUBREG), DstReg)960    .addReg(Src0Reg)961    .addReg(Src1Reg)962    .addImm(SubReg);963 964  I.eraseFromParent();965  return true;966}967 968bool AMDGPUInstructionSelector::selectG_SBFX_UBFX(MachineInstr &MI) const {969  Register DstReg = MI.getOperand(0).getReg();970  Register SrcReg = MI.getOperand(1).getReg();971  Register OffsetReg = MI.getOperand(2).getReg();972  Register WidthReg = MI.getOperand(3).getReg();973 974  assert(RBI.getRegBank(DstReg, *MRI, TRI)->getID() == AMDGPU::VGPRRegBankID &&975         "scalar BFX instructions are expanded in regbankselect");976  assert(MRI->getType(MI.getOperand(0).getReg()).getSizeInBits() == 32 &&977         "64-bit vector BFX instructions are expanded in regbankselect");978 979  const DebugLoc &DL = MI.getDebugLoc();980  MachineBasicBlock *MBB = MI.getParent();981 982  bool IsSigned = MI.getOpcode() == TargetOpcode::G_SBFX;983  unsigned Opc = IsSigned ? AMDGPU::V_BFE_I32_e64 : AMDGPU::V_BFE_U32_e64;984  auto MIB = BuildMI(*MBB, &MI, DL, TII.get(Opc), DstReg)985                 .addReg(SrcReg)986                 .addReg(OffsetReg)987                 .addReg(WidthReg);988  MI.eraseFromParent();989  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);990}991 992bool AMDGPUInstructionSelector::selectInterpP1F16(MachineInstr &MI) const {993  if (STI.getLDSBankCount() != 16)994    return selectImpl(MI, *CoverageInfo);995 996  Register Dst = MI.getOperand(0).getReg();997  Register Src0 = MI.getOperand(2).getReg();998  Register M0Val = MI.getOperand(6).getReg();999  if (!RBI.constrainGenericRegister(M0Val, AMDGPU::SReg_32RegClass, *MRI) ||1000      !RBI.constrainGenericRegister(Dst, AMDGPU::VGPR_32RegClass, *MRI) ||1001      !RBI.constrainGenericRegister(Src0, AMDGPU::VGPR_32RegClass, *MRI))1002    return false;1003 1004  // This requires 2 instructions. It is possible to write a pattern to support1005  // this, but the generated isel emitter doesn't correctly deal with multiple1006  // output instructions using the same physical register input. The copy to m01007  // is incorrectly placed before the second instruction.1008  //1009  // TODO: Match source modifiers.1010 1011  Register InterpMov = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);1012  const DebugLoc &DL = MI.getDebugLoc();1013  MachineBasicBlock *MBB = MI.getParent();1014 1015  BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)1016    .addReg(M0Val);1017  BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::V_INTERP_MOV_F32), InterpMov)1018    .addImm(2)1019    .addImm(MI.getOperand(4).getImm())  // $attr1020    .addImm(MI.getOperand(3).getImm()); // $attrchan1021 1022  BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::V_INTERP_P1LV_F16), Dst)1023    .addImm(0)                          // $src0_modifiers1024    .addReg(Src0)                       // $src01025    .addImm(MI.getOperand(4).getImm())  // $attr1026    .addImm(MI.getOperand(3).getImm())  // $attrchan1027    .addImm(0)                          // $src2_modifiers1028    .addReg(InterpMov)                  // $src2 - 2 f16 values selected by high1029    .addImm(MI.getOperand(5).getImm())  // $high1030    .addImm(0)                          // $clamp1031    .addImm(0);                         // $omod1032 1033  MI.eraseFromParent();1034  return true;1035}1036 1037// Writelane is special in that it can use SGPR and M0 (which would normally1038// count as using the constant bus twice - but in this case it is allowed since1039// the lane selector doesn't count as a use of the constant bus). However, it is1040// still required to abide by the 1 SGPR rule. Fix this up if we might have1041// multiple SGPRs.1042bool AMDGPUInstructionSelector::selectWritelane(MachineInstr &MI) const {1043  // With a constant bus limit of at least 2, there's no issue.1044  if (STI.getConstantBusLimit(AMDGPU::V_WRITELANE_B32) > 1)1045    return selectImpl(MI, *CoverageInfo);1046 1047  MachineBasicBlock *MBB = MI.getParent();1048  const DebugLoc &DL = MI.getDebugLoc();1049  Register VDst = MI.getOperand(0).getReg();1050  Register Val = MI.getOperand(2).getReg();1051  Register LaneSelect = MI.getOperand(3).getReg();1052  Register VDstIn = MI.getOperand(4).getReg();1053 1054  auto MIB = BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::V_WRITELANE_B32), VDst);1055 1056  std::optional<ValueAndVReg> ConstSelect =1057      getIConstantVRegValWithLookThrough(LaneSelect, *MRI);1058  if (ConstSelect) {1059    // The selector has to be an inline immediate, so we can use whatever for1060    // the other operands.1061    MIB.addReg(Val);1062    MIB.addImm(ConstSelect->Value.getSExtValue() &1063               maskTrailingOnes<uint64_t>(STI.getWavefrontSizeLog2()));1064  } else {1065    std::optional<ValueAndVReg> ConstVal =1066        getIConstantVRegValWithLookThrough(Val, *MRI);1067 1068    // If the value written is an inline immediate, we can get away without a1069    // copy to m0.1070    if (ConstVal && AMDGPU::isInlinableLiteral32(ConstVal->Value.getSExtValue(),1071                                                 STI.hasInv2PiInlineImm())) {1072      MIB.addImm(ConstVal->Value.getSExtValue());1073      MIB.addReg(LaneSelect);1074    } else {1075      MIB.addReg(Val);1076 1077      // If the lane selector was originally in a VGPR and copied with1078      // readfirstlane, there's a hazard to read the same SGPR from the1079      // VALU. Constrain to a different SGPR to help avoid needing a nop later.1080      RBI.constrainGenericRegister(LaneSelect, AMDGPU::SReg_32_XM0RegClass, *MRI);1081 1082      BuildMI(*MBB, *MIB, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)1083        .addReg(LaneSelect);1084      MIB.addReg(AMDGPU::M0);1085    }1086  }1087 1088  MIB.addReg(VDstIn);1089 1090  MI.eraseFromParent();1091  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);1092}1093 1094// We need to handle this here because tablegen doesn't support matching1095// instructions with multiple outputs.1096bool AMDGPUInstructionSelector::selectDivScale(MachineInstr &MI) const {1097  Register Dst0 = MI.getOperand(0).getReg();1098  Register Dst1 = MI.getOperand(1).getReg();1099 1100  LLT Ty = MRI->getType(Dst0);1101  unsigned Opc;1102  if (Ty == LLT::scalar(32))1103    Opc = AMDGPU::V_DIV_SCALE_F32_e64;1104  else if (Ty == LLT::scalar(64))1105    Opc = AMDGPU::V_DIV_SCALE_F64_e64;1106  else1107    return false;1108 1109  // TODO: Match source modifiers.1110 1111  const DebugLoc &DL = MI.getDebugLoc();1112  MachineBasicBlock *MBB = MI.getParent();1113 1114  Register Numer = MI.getOperand(3).getReg();1115  Register Denom = MI.getOperand(4).getReg();1116  unsigned ChooseDenom = MI.getOperand(5).getImm();1117 1118  Register Src0 = ChooseDenom != 0 ? Numer : Denom;1119 1120  auto MIB = BuildMI(*MBB, &MI, DL, TII.get(Opc), Dst0)1121    .addDef(Dst1)1122    .addImm(0)     // $src0_modifiers1123    .addUse(Src0)  // $src01124    .addImm(0)     // $src1_modifiers1125    .addUse(Denom) // $src11126    .addImm(0)     // $src2_modifiers1127    .addUse(Numer) // $src21128    .addImm(0)     // $clamp1129    .addImm(0);    // $omod1130 1131  MI.eraseFromParent();1132  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);1133}1134 1135bool AMDGPUInstructionSelector::selectG_INTRINSIC(MachineInstr &I) const {1136  Intrinsic::ID IntrinsicID = cast<GIntrinsic>(I).getIntrinsicID();1137  switch (IntrinsicID) {1138  case Intrinsic::amdgcn_if_break: {1139    MachineBasicBlock *BB = I.getParent();1140 1141    // FIXME: Manually selecting to avoid dealing with the SReg_1 trick1142    // SelectionDAG uses for wave32 vs wave64.1143    BuildMI(*BB, &I, I.getDebugLoc(), TII.get(AMDGPU::SI_IF_BREAK))1144      .add(I.getOperand(0))1145      .add(I.getOperand(2))1146      .add(I.getOperand(3));1147 1148    Register DstReg = I.getOperand(0).getReg();1149    Register Src0Reg = I.getOperand(2).getReg();1150    Register Src1Reg = I.getOperand(3).getReg();1151 1152    I.eraseFromParent();1153 1154    for (Register Reg : { DstReg, Src0Reg, Src1Reg })1155      MRI->setRegClass(Reg, TRI.getWaveMaskRegClass());1156 1157    return true;1158  }1159  case Intrinsic::amdgcn_interp_p1_f16:1160    return selectInterpP1F16(I);1161  case Intrinsic::amdgcn_wqm:1162    return constrainCopyLikeIntrin(I, AMDGPU::WQM);1163  case Intrinsic::amdgcn_softwqm:1164    return constrainCopyLikeIntrin(I, AMDGPU::SOFT_WQM);1165  case Intrinsic::amdgcn_strict_wwm:1166  case Intrinsic::amdgcn_wwm:1167    return constrainCopyLikeIntrin(I, AMDGPU::STRICT_WWM);1168  case Intrinsic::amdgcn_strict_wqm:1169    return constrainCopyLikeIntrin(I, AMDGPU::STRICT_WQM);1170  case Intrinsic::amdgcn_writelane:1171    return selectWritelane(I);1172  case Intrinsic::amdgcn_div_scale:1173    return selectDivScale(I);1174  case Intrinsic::amdgcn_icmp:1175  case Intrinsic::amdgcn_fcmp:1176    if (selectImpl(I, *CoverageInfo))1177      return true;1178    return selectIntrinsicCmp(I);1179  case Intrinsic::amdgcn_ballot:1180    return selectBallot(I);1181  case Intrinsic::amdgcn_reloc_constant:1182    return selectRelocConstant(I);1183  case Intrinsic::amdgcn_groupstaticsize:1184    return selectGroupStaticSize(I);1185  case Intrinsic::returnaddress:1186    return selectReturnAddress(I);1187  case Intrinsic::amdgcn_smfmac_f32_16x16x32_f16:1188  case Intrinsic::amdgcn_smfmac_f32_32x32x16_f16:1189  case Intrinsic::amdgcn_smfmac_f32_16x16x32_bf16:1190  case Intrinsic::amdgcn_smfmac_f32_32x32x16_bf16:1191  case Intrinsic::amdgcn_smfmac_i32_16x16x64_i8:1192  case Intrinsic::amdgcn_smfmac_i32_32x32x32_i8:1193  case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf8_bf8:1194  case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf8_fp8:1195  case Intrinsic::amdgcn_smfmac_f32_16x16x64_fp8_bf8:1196  case Intrinsic::amdgcn_smfmac_f32_16x16x64_fp8_fp8:1197  case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf8_bf8:1198  case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf8_fp8:1199  case Intrinsic::amdgcn_smfmac_f32_32x32x32_fp8_bf8:1200  case Intrinsic::amdgcn_smfmac_f32_32x32x32_fp8_fp8:1201  case Intrinsic::amdgcn_smfmac_f32_16x16x64_f16:1202  case Intrinsic::amdgcn_smfmac_f32_32x32x32_f16:1203  case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf16:1204  case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf16:1205  case Intrinsic::amdgcn_smfmac_i32_16x16x128_i8:1206  case Intrinsic::amdgcn_smfmac_i32_32x32x64_i8:1207  case Intrinsic::amdgcn_smfmac_f32_16x16x128_bf8_bf8:1208  case Intrinsic::amdgcn_smfmac_f32_16x16x128_bf8_fp8:1209  case Intrinsic::amdgcn_smfmac_f32_16x16x128_fp8_bf8:1210  case Intrinsic::amdgcn_smfmac_f32_16x16x128_fp8_fp8:1211  case Intrinsic::amdgcn_smfmac_f32_32x32x64_bf8_bf8:1212  case Intrinsic::amdgcn_smfmac_f32_32x32x64_bf8_fp8:1213  case Intrinsic::amdgcn_smfmac_f32_32x32x64_fp8_bf8:1214  case Intrinsic::amdgcn_smfmac_f32_32x32x64_fp8_fp8:1215    return selectSMFMACIntrin(I);1216  case Intrinsic::amdgcn_permlane16_swap:1217  case Intrinsic::amdgcn_permlane32_swap:1218    return selectPermlaneSwapIntrin(I, IntrinsicID);1219  default:1220    return selectImpl(I, *CoverageInfo);1221  }1222}1223 1224static int getV_CMPOpcode(CmpInst::Predicate P, unsigned Size,1225                          const GCNSubtarget &ST) {1226  if (Size != 16 && Size != 32 && Size != 64)1227    return -1;1228 1229  if (Size == 16 && !ST.has16BitInsts())1230    return -1;1231 1232  const auto Select = [&](unsigned S16Opc, unsigned TrueS16Opc,1233                          unsigned FakeS16Opc, unsigned S32Opc,1234                          unsigned S64Opc) {1235    if (Size == 16)1236      return ST.hasTrue16BitInsts()1237                 ? ST.useRealTrue16Insts() ? TrueS16Opc : FakeS16Opc1238                 : S16Opc;1239    if (Size == 32)1240      return S32Opc;1241    return S64Opc;1242  };1243 1244  switch (P) {1245  default:1246    llvm_unreachable("Unknown condition code!");1247  case CmpInst::ICMP_NE:1248    return Select(AMDGPU::V_CMP_NE_U16_e64, AMDGPU::V_CMP_NE_U16_t16_e64,1249                  AMDGPU::V_CMP_NE_U16_fake16_e64, AMDGPU::V_CMP_NE_U32_e64,1250                  AMDGPU::V_CMP_NE_U64_e64);1251  case CmpInst::ICMP_EQ:1252    return Select(AMDGPU::V_CMP_EQ_U16_e64, AMDGPU::V_CMP_EQ_U16_t16_e64,1253                  AMDGPU::V_CMP_EQ_U16_fake16_e64, AMDGPU::V_CMP_EQ_U32_e64,1254                  AMDGPU::V_CMP_EQ_U64_e64);1255  case CmpInst::ICMP_SGT:1256    return Select(AMDGPU::V_CMP_GT_I16_e64, AMDGPU::V_CMP_GT_I16_t16_e64,1257                  AMDGPU::V_CMP_GT_I16_fake16_e64, AMDGPU::V_CMP_GT_I32_e64,1258                  AMDGPU::V_CMP_GT_I64_e64);1259  case CmpInst::ICMP_SGE:1260    return Select(AMDGPU::V_CMP_GE_I16_e64, AMDGPU::V_CMP_GE_I16_t16_e64,1261                  AMDGPU::V_CMP_GE_I16_fake16_e64, AMDGPU::V_CMP_GE_I32_e64,1262                  AMDGPU::V_CMP_GE_I64_e64);1263  case CmpInst::ICMP_SLT:1264    return Select(AMDGPU::V_CMP_LT_I16_e64, AMDGPU::V_CMP_LT_I16_t16_e64,1265                  AMDGPU::V_CMP_LT_I16_fake16_e64, AMDGPU::V_CMP_LT_I32_e64,1266                  AMDGPU::V_CMP_LT_I64_e64);1267  case CmpInst::ICMP_SLE:1268    return Select(AMDGPU::V_CMP_LE_I16_e64, AMDGPU::V_CMP_LE_I16_t16_e64,1269                  AMDGPU::V_CMP_LE_I16_fake16_e64, AMDGPU::V_CMP_LE_I32_e64,1270                  AMDGPU::V_CMP_LE_I64_e64);1271  case CmpInst::ICMP_UGT:1272    return Select(AMDGPU::V_CMP_GT_U16_e64, AMDGPU::V_CMP_GT_U16_t16_e64,1273                  AMDGPU::V_CMP_GT_U16_fake16_e64, AMDGPU::V_CMP_GT_U32_e64,1274                  AMDGPU::V_CMP_GT_U64_e64);1275  case CmpInst::ICMP_UGE:1276    return Select(AMDGPU::V_CMP_GE_U16_e64, AMDGPU::V_CMP_GE_U16_t16_e64,1277                  AMDGPU::V_CMP_GE_U16_fake16_e64, AMDGPU::V_CMP_GE_U32_e64,1278                  AMDGPU::V_CMP_GE_U64_e64);1279  case CmpInst::ICMP_ULT:1280    return Select(AMDGPU::V_CMP_LT_U16_e64, AMDGPU::V_CMP_LT_U16_t16_e64,1281                  AMDGPU::V_CMP_LT_U16_fake16_e64, AMDGPU::V_CMP_LT_U32_e64,1282                  AMDGPU::V_CMP_LT_U64_e64);1283  case CmpInst::ICMP_ULE:1284    return Select(AMDGPU::V_CMP_LE_U16_e64, AMDGPU::V_CMP_LE_U16_t16_e64,1285                  AMDGPU::V_CMP_LE_U16_fake16_e64, AMDGPU::V_CMP_LE_U32_e64,1286                  AMDGPU::V_CMP_LE_U64_e64);1287 1288  case CmpInst::FCMP_OEQ:1289    return Select(AMDGPU::V_CMP_EQ_F16_e64, AMDGPU::V_CMP_EQ_F16_t16_e64,1290                  AMDGPU::V_CMP_EQ_F16_fake16_e64, AMDGPU::V_CMP_EQ_F32_e64,1291                  AMDGPU::V_CMP_EQ_F64_e64);1292  case CmpInst::FCMP_OGT:1293    return Select(AMDGPU::V_CMP_GT_F16_e64, AMDGPU::V_CMP_GT_F16_t16_e64,1294                  AMDGPU::V_CMP_GT_F16_fake16_e64, AMDGPU::V_CMP_GT_F32_e64,1295                  AMDGPU::V_CMP_GT_F64_e64);1296  case CmpInst::FCMP_OGE:1297    return Select(AMDGPU::V_CMP_GE_F16_e64, AMDGPU::V_CMP_GE_F16_t16_e64,1298                  AMDGPU::V_CMP_GE_F16_fake16_e64, AMDGPU::V_CMP_GE_F32_e64,1299                  AMDGPU::V_CMP_GE_F64_e64);1300  case CmpInst::FCMP_OLT:1301    return Select(AMDGPU::V_CMP_LT_F16_e64, AMDGPU::V_CMP_LT_F16_t16_e64,1302                  AMDGPU::V_CMP_LT_F16_fake16_e64, AMDGPU::V_CMP_LT_F32_e64,1303                  AMDGPU::V_CMP_LT_F64_e64);1304  case CmpInst::FCMP_OLE:1305    return Select(AMDGPU::V_CMP_LE_F16_e64, AMDGPU::V_CMP_LE_F16_t16_e64,1306                  AMDGPU::V_CMP_LE_F16_fake16_e64, AMDGPU::V_CMP_LE_F32_e64,1307                  AMDGPU::V_CMP_LE_F64_e64);1308  case CmpInst::FCMP_ONE:1309    return Select(AMDGPU::V_CMP_NEQ_F16_e64, AMDGPU::V_CMP_NEQ_F16_t16_e64,1310                  AMDGPU::V_CMP_NEQ_F16_fake16_e64, AMDGPU::V_CMP_NEQ_F32_e64,1311                  AMDGPU::V_CMP_NEQ_F64_e64);1312  case CmpInst::FCMP_ORD:1313    return Select(AMDGPU::V_CMP_O_F16_e64, AMDGPU::V_CMP_O_F16_t16_e64,1314                  AMDGPU::V_CMP_O_F16_fake16_e64, AMDGPU::V_CMP_O_F32_e64,1315                  AMDGPU::V_CMP_O_F64_e64);1316  case CmpInst::FCMP_UNO:1317    return Select(AMDGPU::V_CMP_U_F16_e64, AMDGPU::V_CMP_U_F16_t16_e64,1318                  AMDGPU::V_CMP_U_F16_fake16_e64, AMDGPU::V_CMP_U_F32_e64,1319                  AMDGPU::V_CMP_U_F64_e64);1320  case CmpInst::FCMP_UEQ:1321    return Select(AMDGPU::V_CMP_NLG_F16_e64, AMDGPU::V_CMP_NLG_F16_t16_e64,1322                  AMDGPU::V_CMP_NLG_F16_fake16_e64, AMDGPU::V_CMP_NLG_F32_e64,1323                  AMDGPU::V_CMP_NLG_F64_e64);1324  case CmpInst::FCMP_UGT:1325    return Select(AMDGPU::V_CMP_NLE_F16_e64, AMDGPU::V_CMP_NLE_F16_t16_e64,1326                  AMDGPU::V_CMP_NLE_F16_fake16_e64, AMDGPU::V_CMP_NLE_F32_e64,1327                  AMDGPU::V_CMP_NLE_F64_e64);1328  case CmpInst::FCMP_UGE:1329    return Select(AMDGPU::V_CMP_NLT_F16_e64, AMDGPU::V_CMP_NLT_F16_t16_e64,1330                  AMDGPU::V_CMP_NLT_F16_fake16_e64, AMDGPU::V_CMP_NLT_F32_e64,1331                  AMDGPU::V_CMP_NLT_F64_e64);1332  case CmpInst::FCMP_ULT:1333    return Select(AMDGPU::V_CMP_NGE_F16_e64, AMDGPU::V_CMP_NGE_F16_t16_e64,1334                  AMDGPU::V_CMP_NGE_F16_fake16_e64, AMDGPU::V_CMP_NGE_F32_e64,1335                  AMDGPU::V_CMP_NGE_F64_e64);1336  case CmpInst::FCMP_ULE:1337    return Select(AMDGPU::V_CMP_NGT_F16_e64, AMDGPU::V_CMP_NGT_F16_t16_e64,1338                  AMDGPU::V_CMP_NGT_F16_fake16_e64, AMDGPU::V_CMP_NGT_F32_e64,1339                  AMDGPU::V_CMP_NGT_F64_e64);1340  case CmpInst::FCMP_UNE:1341    return Select(AMDGPU::V_CMP_NEQ_F16_e64, AMDGPU::V_CMP_NEQ_F16_t16_e64,1342                  AMDGPU::V_CMP_NEQ_F16_fake16_e64, AMDGPU::V_CMP_NEQ_F32_e64,1343                  AMDGPU::V_CMP_NEQ_F64_e64);1344  case CmpInst::FCMP_TRUE:1345    return Select(AMDGPU::V_CMP_TRU_F16_e64, AMDGPU::V_CMP_TRU_F16_t16_e64,1346                  AMDGPU::V_CMP_TRU_F16_fake16_e64, AMDGPU::V_CMP_TRU_F32_e64,1347                  AMDGPU::V_CMP_TRU_F64_e64);1348  case CmpInst::FCMP_FALSE:1349    return Select(AMDGPU::V_CMP_F_F16_e64, AMDGPU::V_CMP_F_F16_t16_e64,1350                  AMDGPU::V_CMP_F_F16_fake16_e64, AMDGPU::V_CMP_F_F32_e64,1351                  AMDGPU::V_CMP_F_F64_e64);1352  }1353}1354 1355int AMDGPUInstructionSelector::getS_CMPOpcode(CmpInst::Predicate P,1356                                              unsigned Size) const {1357  if (Size == 64) {1358    if (!STI.hasScalarCompareEq64())1359      return -1;1360 1361    switch (P) {1362    case CmpInst::ICMP_NE:1363      return AMDGPU::S_CMP_LG_U64;1364    case CmpInst::ICMP_EQ:1365      return AMDGPU::S_CMP_EQ_U64;1366    default:1367      return -1;1368    }1369  }1370 1371  if (Size == 32) {1372    switch (P) {1373    case CmpInst::ICMP_NE:1374      return AMDGPU::S_CMP_LG_U32;1375    case CmpInst::ICMP_EQ:1376      return AMDGPU::S_CMP_EQ_U32;1377    case CmpInst::ICMP_SGT:1378      return AMDGPU::S_CMP_GT_I32;1379    case CmpInst::ICMP_SGE:1380      return AMDGPU::S_CMP_GE_I32;1381    case CmpInst::ICMP_SLT:1382      return AMDGPU::S_CMP_LT_I32;1383    case CmpInst::ICMP_SLE:1384      return AMDGPU::S_CMP_LE_I32;1385    case CmpInst::ICMP_UGT:1386      return AMDGPU::S_CMP_GT_U32;1387    case CmpInst::ICMP_UGE:1388      return AMDGPU::S_CMP_GE_U32;1389    case CmpInst::ICMP_ULT:1390      return AMDGPU::S_CMP_LT_U32;1391    case CmpInst::ICMP_ULE:1392      return AMDGPU::S_CMP_LE_U32;1393    case CmpInst::FCMP_OEQ:1394      return AMDGPU::S_CMP_EQ_F32;1395    case CmpInst::FCMP_OGT:1396      return AMDGPU::S_CMP_GT_F32;1397    case CmpInst::FCMP_OGE:1398      return AMDGPU::S_CMP_GE_F32;1399    case CmpInst::FCMP_OLT:1400      return AMDGPU::S_CMP_LT_F32;1401    case CmpInst::FCMP_OLE:1402      return AMDGPU::S_CMP_LE_F32;1403    case CmpInst::FCMP_ONE:1404      return AMDGPU::S_CMP_LG_F32;1405    case CmpInst::FCMP_ORD:1406      return AMDGPU::S_CMP_O_F32;1407    case CmpInst::FCMP_UNO:1408      return AMDGPU::S_CMP_U_F32;1409    case CmpInst::FCMP_UEQ:1410      return AMDGPU::S_CMP_NLG_F32;1411    case CmpInst::FCMP_UGT:1412      return AMDGPU::S_CMP_NLE_F32;1413    case CmpInst::FCMP_UGE:1414      return AMDGPU::S_CMP_NLT_F32;1415    case CmpInst::FCMP_ULT:1416      return AMDGPU::S_CMP_NGE_F32;1417    case CmpInst::FCMP_ULE:1418      return AMDGPU::S_CMP_NGT_F32;1419    case CmpInst::FCMP_UNE:1420      return AMDGPU::S_CMP_NEQ_F32;1421    default:1422      llvm_unreachable("Unknown condition code!");1423    }1424  }1425 1426  if (Size == 16) {1427    if (!STI.hasSALUFloatInsts())1428      return -1;1429 1430    switch (P) {1431    case CmpInst::FCMP_OEQ:1432      return AMDGPU::S_CMP_EQ_F16;1433    case CmpInst::FCMP_OGT:1434      return AMDGPU::S_CMP_GT_F16;1435    case CmpInst::FCMP_OGE:1436      return AMDGPU::S_CMP_GE_F16;1437    case CmpInst::FCMP_OLT:1438      return AMDGPU::S_CMP_LT_F16;1439    case CmpInst::FCMP_OLE:1440      return AMDGPU::S_CMP_LE_F16;1441    case CmpInst::FCMP_ONE:1442      return AMDGPU::S_CMP_LG_F16;1443    case CmpInst::FCMP_ORD:1444      return AMDGPU::S_CMP_O_F16;1445    case CmpInst::FCMP_UNO:1446      return AMDGPU::S_CMP_U_F16;1447    case CmpInst::FCMP_UEQ:1448      return AMDGPU::S_CMP_NLG_F16;1449    case CmpInst::FCMP_UGT:1450      return AMDGPU::S_CMP_NLE_F16;1451    case CmpInst::FCMP_UGE:1452      return AMDGPU::S_CMP_NLT_F16;1453    case CmpInst::FCMP_ULT:1454      return AMDGPU::S_CMP_NGE_F16;1455    case CmpInst::FCMP_ULE:1456      return AMDGPU::S_CMP_NGT_F16;1457    case CmpInst::FCMP_UNE:1458      return AMDGPU::S_CMP_NEQ_F16;1459    default:1460      llvm_unreachable("Unknown condition code!");1461    }1462  }1463 1464  return -1;1465}1466 1467bool AMDGPUInstructionSelector::selectG_ICMP_or_FCMP(MachineInstr &I) const {1468 1469  MachineBasicBlock *BB = I.getParent();1470  const DebugLoc &DL = I.getDebugLoc();1471 1472  Register SrcReg = I.getOperand(2).getReg();1473  unsigned Size = RBI.getSizeInBits(SrcReg, *MRI, TRI);1474 1475  auto Pred = (CmpInst::Predicate)I.getOperand(1).getPredicate();1476 1477  Register CCReg = I.getOperand(0).getReg();1478  if (!isVCC(CCReg, *MRI)) {1479    int Opcode = getS_CMPOpcode(Pred, Size);1480    if (Opcode == -1)1481      return false;1482    MachineInstr *ICmp = BuildMI(*BB, &I, DL, TII.get(Opcode))1483            .add(I.getOperand(2))1484            .add(I.getOperand(3));1485    BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), CCReg)1486      .addReg(AMDGPU::SCC);1487    bool Ret =1488        constrainSelectedInstRegOperands(*ICmp, TII, TRI, RBI) &&1489        RBI.constrainGenericRegister(CCReg, AMDGPU::SReg_32RegClass, *MRI);1490    I.eraseFromParent();1491    return Ret;1492  }1493 1494  if (I.getOpcode() == AMDGPU::G_FCMP)1495    return false;1496 1497  int Opcode = getV_CMPOpcode(Pred, Size, *Subtarget);1498  if (Opcode == -1)1499    return false;1500 1501  MachineInstrBuilder ICmp;1502  // t16 instructions1503  if (AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::src0_modifiers)) {1504    ICmp = BuildMI(*BB, &I, DL, TII.get(Opcode), I.getOperand(0).getReg())1505               .addImm(0)1506               .add(I.getOperand(2))1507               .addImm(0)1508               .add(I.getOperand(3))1509               .addImm(0); // op_sel1510  } else {1511    ICmp = BuildMI(*BB, &I, DL, TII.get(Opcode), I.getOperand(0).getReg())1512               .add(I.getOperand(2))1513               .add(I.getOperand(3));1514  }1515 1516  RBI.constrainGenericRegister(ICmp->getOperand(0).getReg(),1517                               *TRI.getBoolRC(), *MRI);1518  bool Ret = constrainSelectedInstRegOperands(*ICmp, TII, TRI, RBI);1519  I.eraseFromParent();1520  return Ret;1521}1522 1523bool AMDGPUInstructionSelector::selectIntrinsicCmp(MachineInstr &I) const {1524  Register Dst = I.getOperand(0).getReg();1525  if (isVCC(Dst, *MRI))1526    return false;1527 1528  LLT DstTy = MRI->getType(Dst);1529  if (DstTy.getSizeInBits() != STI.getWavefrontSize())1530    return false;1531 1532  MachineBasicBlock *BB = I.getParent();1533  const DebugLoc &DL = I.getDebugLoc();1534  Register SrcReg = I.getOperand(2).getReg();1535  unsigned Size = RBI.getSizeInBits(SrcReg, *MRI, TRI);1536 1537  // i1 inputs are not supported in GlobalISel.1538  if (Size == 1)1539    return false;1540 1541  auto Pred = static_cast<CmpInst::Predicate>(I.getOperand(4).getImm());1542  if (!CmpInst::isIntPredicate(Pred) && !CmpInst::isFPPredicate(Pred)) {1543    BuildMI(*BB, &I, DL, TII.get(AMDGPU::IMPLICIT_DEF), Dst);1544    I.eraseFromParent();1545    return RBI.constrainGenericRegister(Dst, *TRI.getBoolRC(), *MRI);1546  }1547 1548  const int Opcode = getV_CMPOpcode(Pred, Size, *Subtarget);1549  if (Opcode == -1)1550    return false;1551 1552  MachineInstrBuilder SelectedMI;1553  MachineOperand &LHS = I.getOperand(2);1554  MachineOperand &RHS = I.getOperand(3);1555  auto [Src0, Src0Mods] = selectVOP3ModsImpl(LHS.getReg());1556  auto [Src1, Src1Mods] = selectVOP3ModsImpl(RHS.getReg());1557  Register Src0Reg =1558      copyToVGPRIfSrcFolded(Src0, Src0Mods, LHS, &I, /*ForceVGPR*/ true);1559  Register Src1Reg =1560      copyToVGPRIfSrcFolded(Src1, Src1Mods, RHS, &I, /*ForceVGPR*/ true);1561  SelectedMI = BuildMI(*BB, &I, DL, TII.get(Opcode), Dst);1562  if (AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::src0_modifiers))1563    SelectedMI.addImm(Src0Mods);1564  SelectedMI.addReg(Src0Reg);1565  if (AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::src1_modifiers))1566    SelectedMI.addImm(Src1Mods);1567  SelectedMI.addReg(Src1Reg);1568  if (AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::clamp))1569    SelectedMI.addImm(0); // clamp1570  if (AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::op_sel))1571    SelectedMI.addImm(0); // op_sel1572 1573  RBI.constrainGenericRegister(Dst, *TRI.getBoolRC(), *MRI);1574  if (!constrainSelectedInstRegOperands(*SelectedMI, TII, TRI, RBI))1575    return false;1576 1577  I.eraseFromParent();1578  return true;1579}1580 1581// Ballot has to zero bits in input lane-mask that are zero in current exec,1582// Done as AND with exec. For inputs that are results of instruction that1583// implicitly use same exec, for example compares in same basic block or SCC to1584// VCC copy, use copy.1585static bool isLaneMaskFromSameBlock(Register Reg, MachineRegisterInfo &MRI,1586                                    MachineBasicBlock *MBB) {1587  MachineInstr *MI = MRI.getVRegDef(Reg);1588  if (MI->getParent() != MBB)1589    return false;1590 1591  // Lane mask generated by SCC to VCC copy.1592  if (MI->getOpcode() == AMDGPU::COPY) {1593    auto DstRB = MRI.getRegBankOrNull(MI->getOperand(0).getReg());1594    auto SrcRB = MRI.getRegBankOrNull(MI->getOperand(1).getReg());1595    if (DstRB && SrcRB && DstRB->getID() == AMDGPU::VCCRegBankID &&1596        SrcRB->getID() == AMDGPU::SGPRRegBankID)1597      return true;1598  }1599 1600  // Lane mask generated using compare with same exec.1601  if (isa<GAnyCmp>(MI))1602    return true;1603 1604  Register LHS, RHS;1605  // Look through AND.1606  if (mi_match(Reg, MRI, m_GAnd(m_Reg(LHS), m_Reg(RHS))))1607    return isLaneMaskFromSameBlock(LHS, MRI, MBB) ||1608           isLaneMaskFromSameBlock(RHS, MRI, MBB);1609 1610  return false;1611}1612 1613bool AMDGPUInstructionSelector::selectBallot(MachineInstr &I) const {1614  MachineBasicBlock *BB = I.getParent();1615  const DebugLoc &DL = I.getDebugLoc();1616  Register DstReg = I.getOperand(0).getReg();1617  Register SrcReg = I.getOperand(2).getReg();1618  const unsigned BallotSize = MRI->getType(DstReg).getSizeInBits();1619  const unsigned WaveSize = STI.getWavefrontSize();1620 1621  // In the common case, the return type matches the wave size.1622  // However we also support emitting i64 ballots in wave32 mode.1623  if (BallotSize != WaveSize && (BallotSize != 64 || WaveSize != 32))1624    return false;1625 1626  std::optional<ValueAndVReg> Arg =1627      getIConstantVRegValWithLookThrough(SrcReg, *MRI);1628 1629  Register Dst = DstReg;1630  // i64 ballot on Wave32: new Dst(i32) for WaveSize ballot.1631  if (BallotSize != WaveSize) {1632    Dst = MRI->createVirtualRegister(TRI.getBoolRC());1633  }1634 1635  if (Arg) {1636    const int64_t Value = Arg->Value.getZExtValue();1637    if (Value == 0) {1638      // Dst = S_MOV 01639      unsigned Opcode = WaveSize == 64 ? AMDGPU::S_MOV_B64 : AMDGPU::S_MOV_B32;1640      BuildMI(*BB, &I, DL, TII.get(Opcode), Dst).addImm(0);1641    } else {1642      // Dst = COPY EXEC1643      assert(Value == 1);1644      BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), Dst).addReg(TRI.getExec());1645    }1646    if (!RBI.constrainGenericRegister(Dst, *TRI.getBoolRC(), *MRI))1647      return false;1648  } else {1649    if (isLaneMaskFromSameBlock(SrcReg, *MRI, BB)) {1650      // Dst = COPY SrcReg1651      BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), Dst).addReg(SrcReg);1652      if (!RBI.constrainGenericRegister(Dst, *TRI.getBoolRC(), *MRI))1653        return false;1654    } else {1655      // Dst = S_AND SrcReg, EXEC1656      unsigned AndOpc = WaveSize == 64 ? AMDGPU::S_AND_B64 : AMDGPU::S_AND_B32;1657      auto And = BuildMI(*BB, &I, DL, TII.get(AndOpc), Dst)1658                     .addReg(SrcReg)1659                     .addReg(TRI.getExec())1660                     .setOperandDead(3); // Dead scc1661      if (!constrainSelectedInstRegOperands(*And, TII, TRI, RBI))1662        return false;1663    }1664  }1665 1666  // i64 ballot on Wave32: zero-extend i32 ballot to i64.1667  if (BallotSize != WaveSize) {1668    Register HiReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);1669    BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_MOV_B32), HiReg).addImm(0);1670    BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)1671        .addReg(Dst)1672        .addImm(AMDGPU::sub0)1673        .addReg(HiReg)1674        .addImm(AMDGPU::sub1);1675  }1676 1677  I.eraseFromParent();1678  return true;1679}1680 1681bool AMDGPUInstructionSelector::selectRelocConstant(MachineInstr &I) const {1682  Register DstReg = I.getOperand(0).getReg();1683  const RegisterBank *DstBank = RBI.getRegBank(DstReg, *MRI, TRI);1684  const TargetRegisterClass *DstRC = TRI.getRegClassForSizeOnBank(32, *DstBank);1685  if (!DstRC || !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))1686    return false;1687 1688  const bool IsVALU = DstBank->getID() == AMDGPU::VGPRRegBankID;1689 1690  Module *M = MF->getFunction().getParent();1691  const MDNode *Metadata = I.getOperand(2).getMetadata();1692  auto SymbolName = cast<MDString>(Metadata->getOperand(0))->getString();1693  auto *RelocSymbol = cast<GlobalVariable>(1694      M->getOrInsertGlobal(SymbolName, Type::getInt32Ty(M->getContext())));1695 1696  MachineBasicBlock *BB = I.getParent();1697  BuildMI(*BB, &I, I.getDebugLoc(),1698          TII.get(IsVALU ? AMDGPU::V_MOV_B32_e32 : AMDGPU::S_MOV_B32), DstReg)1699    .addGlobalAddress(RelocSymbol, 0, SIInstrInfo::MO_ABS32_LO);1700 1701  I.eraseFromParent();1702  return true;1703}1704 1705bool AMDGPUInstructionSelector::selectGroupStaticSize(MachineInstr &I) const {1706  Triple::OSType OS = MF->getTarget().getTargetTriple().getOS();1707 1708  Register DstReg = I.getOperand(0).getReg();1709  const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);1710  unsigned Mov = DstRB->getID() == AMDGPU::SGPRRegBankID ?1711    AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;1712 1713  MachineBasicBlock *MBB = I.getParent();1714  const DebugLoc &DL = I.getDebugLoc();1715 1716  auto MIB = BuildMI(*MBB, &I, DL, TII.get(Mov), DstReg);1717 1718  if (OS == Triple::AMDHSA || OS == Triple::AMDPAL) {1719    const SIMachineFunctionInfo *MFI = MF->getInfo<SIMachineFunctionInfo>();1720    MIB.addImm(MFI->getLDSSize());1721  } else {1722    Module *M = MF->getFunction().getParent();1723    const GlobalValue *GV =1724        Intrinsic::getOrInsertDeclaration(M, Intrinsic::amdgcn_groupstaticsize);1725    MIB.addGlobalAddress(GV, 0, SIInstrInfo::MO_ABS32_LO);1726  }1727 1728  I.eraseFromParent();1729  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);1730}1731 1732bool AMDGPUInstructionSelector::selectReturnAddress(MachineInstr &I) const {1733  MachineBasicBlock *MBB = I.getParent();1734  MachineFunction &MF = *MBB->getParent();1735  const DebugLoc &DL = I.getDebugLoc();1736 1737  MachineOperand &Dst = I.getOperand(0);1738  Register DstReg = Dst.getReg();1739  unsigned Depth = I.getOperand(2).getImm();1740 1741  const TargetRegisterClass *RC1742    = TRI.getConstrainedRegClassForOperand(Dst, *MRI);1743  if (!RC->hasSubClassEq(&AMDGPU::SGPR_64RegClass) ||1744      !RBI.constrainGenericRegister(DstReg, *RC, *MRI))1745    return false;1746 1747  // Check for kernel and shader functions1748  if (Depth != 0 ||1749      MF.getInfo<SIMachineFunctionInfo>()->isEntryFunction()) {1750    BuildMI(*MBB, &I, DL, TII.get(AMDGPU::S_MOV_B64), DstReg)1751      .addImm(0);1752    I.eraseFromParent();1753    return true;1754  }1755 1756  MachineFrameInfo &MFI = MF.getFrameInfo();1757  // There is a call to @llvm.returnaddress in this function1758  MFI.setReturnAddressIsTaken(true);1759 1760  // Get the return address reg and mark it as an implicit live-in1761  Register ReturnAddrReg = TRI.getReturnAddressReg(MF);1762  Register LiveIn = getFunctionLiveInPhysReg(MF, TII, ReturnAddrReg,1763                                             AMDGPU::SReg_64RegClass, DL);1764  BuildMI(*MBB, &I, DL, TII.get(AMDGPU::COPY), DstReg)1765    .addReg(LiveIn);1766  I.eraseFromParent();1767  return true;1768}1769 1770bool AMDGPUInstructionSelector::selectEndCfIntrinsic(MachineInstr &MI) const {1771  // FIXME: Manually selecting to avoid dealing with the SReg_1 trick1772  // SelectionDAG uses for wave32 vs wave64.1773  MachineBasicBlock *BB = MI.getParent();1774  BuildMI(*BB, &MI, MI.getDebugLoc(), TII.get(AMDGPU::SI_END_CF))1775      .add(MI.getOperand(1));1776 1777  Register Reg = MI.getOperand(1).getReg();1778  MI.eraseFromParent();1779 1780  if (!MRI->getRegClassOrNull(Reg))1781    MRI->setRegClass(Reg, TRI.getWaveMaskRegClass());1782  return true;1783}1784 1785bool AMDGPUInstructionSelector::selectDSOrderedIntrinsic(1786  MachineInstr &MI, Intrinsic::ID IntrID) const {1787  MachineBasicBlock *MBB = MI.getParent();1788  MachineFunction *MF = MBB->getParent();1789  const DebugLoc &DL = MI.getDebugLoc();1790 1791  unsigned IndexOperand = MI.getOperand(7).getImm();1792  bool WaveRelease = MI.getOperand(8).getImm() != 0;1793  bool WaveDone = MI.getOperand(9).getImm() != 0;1794 1795  if (WaveDone && !WaveRelease) {1796    // TODO: Move this to IR verifier1797    const Function &Fn = MF->getFunction();1798    Fn.getContext().diagnose(DiagnosticInfoUnsupported(1799        Fn, "ds_ordered_count: wave_done requires wave_release", DL));1800  }1801 1802  unsigned OrderedCountIndex = IndexOperand & 0x3f;1803  IndexOperand &= ~0x3f;1804  unsigned CountDw = 0;1805 1806  if (STI.getGeneration() >= AMDGPUSubtarget::GFX10) {1807    CountDw = (IndexOperand >> 24) & 0xf;1808    IndexOperand &= ~(0xf << 24);1809 1810    if (CountDw < 1 || CountDw > 4) {1811      const Function &Fn = MF->getFunction();1812      Fn.getContext().diagnose(DiagnosticInfoUnsupported(1813          Fn, "ds_ordered_count: dword count must be between 1 and 4", DL));1814      CountDw = 1;1815    }1816  }1817 1818  if (IndexOperand) {1819    const Function &Fn = MF->getFunction();1820    Fn.getContext().diagnose(DiagnosticInfoUnsupported(1821        Fn, "ds_ordered_count: bad index operand", DL));1822  }1823 1824  unsigned Instruction = IntrID == Intrinsic::amdgcn_ds_ordered_add ? 0 : 1;1825  unsigned ShaderType = SIInstrInfo::getDSShaderTypeValue(*MF);1826 1827  unsigned Offset0 = OrderedCountIndex << 2;1828  unsigned Offset1 = WaveRelease | (WaveDone << 1) | (Instruction << 4);1829 1830  if (STI.getGeneration() >= AMDGPUSubtarget::GFX10)1831    Offset1 |= (CountDw - 1) << 6;1832 1833  if (STI.getGeneration() < AMDGPUSubtarget::GFX11)1834    Offset1 |= ShaderType << 2;1835 1836  unsigned Offset = Offset0 | (Offset1 << 8);1837 1838  Register M0Val = MI.getOperand(2).getReg();1839  BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)1840    .addReg(M0Val);1841 1842  Register DstReg = MI.getOperand(0).getReg();1843  Register ValReg = MI.getOperand(3).getReg();1844  MachineInstrBuilder DS =1845    BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::DS_ORDERED_COUNT), DstReg)1846      .addReg(ValReg)1847      .addImm(Offset)1848      .cloneMemRefs(MI);1849 1850  if (!RBI.constrainGenericRegister(M0Val, AMDGPU::SReg_32RegClass, *MRI))1851    return false;1852 1853  bool Ret = constrainSelectedInstRegOperands(*DS, TII, TRI, RBI);1854  MI.eraseFromParent();1855  return Ret;1856}1857 1858static unsigned gwsIntrinToOpcode(unsigned IntrID) {1859  switch (IntrID) {1860  case Intrinsic::amdgcn_ds_gws_init:1861    return AMDGPU::DS_GWS_INIT;1862  case Intrinsic::amdgcn_ds_gws_barrier:1863    return AMDGPU::DS_GWS_BARRIER;1864  case Intrinsic::amdgcn_ds_gws_sema_v:1865    return AMDGPU::DS_GWS_SEMA_V;1866  case Intrinsic::amdgcn_ds_gws_sema_br:1867    return AMDGPU::DS_GWS_SEMA_BR;1868  case Intrinsic::amdgcn_ds_gws_sema_p:1869    return AMDGPU::DS_GWS_SEMA_P;1870  case Intrinsic::amdgcn_ds_gws_sema_release_all:1871    return AMDGPU::DS_GWS_SEMA_RELEASE_ALL;1872  default:1873    llvm_unreachable("not a gws intrinsic");1874  }1875}1876 1877bool AMDGPUInstructionSelector::selectDSGWSIntrinsic(MachineInstr &MI,1878                                                     Intrinsic::ID IID) const {1879  if (!STI.hasGWS() || (IID == Intrinsic::amdgcn_ds_gws_sema_release_all &&1880                        !STI.hasGWSSemaReleaseAll()))1881    return false;1882 1883  // intrinsic ID, vsrc, offset1884  const bool HasVSrc = MI.getNumOperands() == 3;1885  assert(HasVSrc || MI.getNumOperands() == 2);1886 1887  Register BaseOffset = MI.getOperand(HasVSrc ? 2 : 1).getReg();1888  const RegisterBank *OffsetRB = RBI.getRegBank(BaseOffset, *MRI, TRI);1889  if (OffsetRB->getID() != AMDGPU::SGPRRegBankID)1890    return false;1891 1892  MachineInstr *OffsetDef = getDefIgnoringCopies(BaseOffset, *MRI);1893  unsigned ImmOffset;1894 1895  MachineBasicBlock *MBB = MI.getParent();1896  const DebugLoc &DL = MI.getDebugLoc();1897 1898  MachineInstr *Readfirstlane = nullptr;1899 1900  // If we legalized the VGPR input, strip out the readfirstlane to analyze the1901  // incoming offset, in case there's an add of a constant. We'll have to put it1902  // back later.1903  if (OffsetDef->getOpcode() == AMDGPU::V_READFIRSTLANE_B32) {1904    Readfirstlane = OffsetDef;1905    BaseOffset = OffsetDef->getOperand(1).getReg();1906    OffsetDef = getDefIgnoringCopies(BaseOffset, *MRI);1907  }1908 1909  if (OffsetDef->getOpcode() == AMDGPU::G_CONSTANT) {1910    // If we have a constant offset, try to use the 0 in m0 as the base.1911    // TODO: Look into changing the default m0 initialization value. If the1912    // default -1 only set the low 16-bits, we could leave it as-is and add 1 to1913    // the immediate offset.1914 1915    ImmOffset = OffsetDef->getOperand(1).getCImm()->getZExtValue();1916    BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::S_MOV_B32), AMDGPU::M0)1917      .addImm(0);1918  } else {1919    std::tie(BaseOffset, ImmOffset) =1920        AMDGPU::getBaseWithConstantOffset(*MRI, BaseOffset, VT);1921 1922    if (Readfirstlane) {1923      // We have the constant offset now, so put the readfirstlane back on the1924      // variable component.1925      if (!RBI.constrainGenericRegister(BaseOffset, AMDGPU::VGPR_32RegClass, *MRI))1926        return false;1927 1928      Readfirstlane->getOperand(1).setReg(BaseOffset);1929      BaseOffset = Readfirstlane->getOperand(0).getReg();1930    } else {1931      if (!RBI.constrainGenericRegister(BaseOffset,1932                                        AMDGPU::SReg_32RegClass, *MRI))1933        return false;1934    }1935 1936    Register M0Base = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);1937    BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::S_LSHL_B32), M0Base)1938      .addReg(BaseOffset)1939      .addImm(16)1940      .setOperandDead(3); // Dead scc1941 1942    BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)1943      .addReg(M0Base);1944  }1945 1946  // The resource id offset is computed as (<isa opaque base> + M0[21:16] +1947  // offset field) % 64. Some versions of the programming guide omit the m01948  // part, or claim it's from offset 0.1949 1950  unsigned Opc = gwsIntrinToOpcode(IID);1951  const MCInstrDesc &InstrDesc = TII.get(Opc);1952 1953  if (HasVSrc) {1954    Register VSrc = MI.getOperand(1).getReg();1955 1956    int Data0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::data0);1957    const TargetRegisterClass *DataRC = TII.getRegClass(InstrDesc, Data0Idx);1958    const TargetRegisterClass *SubRC =1959        TRI.getSubRegisterClass(DataRC, AMDGPU::sub0);1960 1961    if (!SubRC) {1962      // 32-bit normal case.1963      if (!RBI.constrainGenericRegister(VSrc, *DataRC, *MRI))1964        return false;1965 1966      BuildMI(*MBB, &MI, DL, InstrDesc)1967        .addReg(VSrc)1968        .addImm(ImmOffset)1969        .cloneMemRefs(MI);1970    } else {1971      // Requires even register alignment, so create 64-bit value and pad the1972      // top half with undef.1973      Register DataReg = MRI->createVirtualRegister(DataRC);1974      if (!RBI.constrainGenericRegister(VSrc, *SubRC, *MRI))1975        return false;1976 1977      Register UndefReg = MRI->createVirtualRegister(SubRC);1978      BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::IMPLICIT_DEF), UndefReg);1979      BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::REG_SEQUENCE), DataReg)1980        .addReg(VSrc)1981        .addImm(AMDGPU::sub0)1982        .addReg(UndefReg)1983        .addImm(AMDGPU::sub1);1984 1985      BuildMI(*MBB, &MI, DL, InstrDesc)1986        .addReg(DataReg)1987        .addImm(ImmOffset)1988        .cloneMemRefs(MI);1989    }1990  } else {1991    BuildMI(*MBB, &MI, DL, InstrDesc)1992      .addImm(ImmOffset)1993      .cloneMemRefs(MI);1994  }1995 1996  MI.eraseFromParent();1997  return true;1998}1999 2000bool AMDGPUInstructionSelector::selectDSAppendConsume(MachineInstr &MI,2001                                                      bool IsAppend) const {2002  Register PtrBase = MI.getOperand(2).getReg();2003  LLT PtrTy = MRI->getType(PtrBase);2004  bool IsGDS = PtrTy.getAddressSpace() == AMDGPUAS::REGION_ADDRESS;2005 2006  unsigned Offset;2007  std::tie(PtrBase, Offset) = selectDS1Addr1OffsetImpl(MI.getOperand(2));2008 2009  // TODO: Should this try to look through readfirstlane like GWS?2010  if (!isDSOffsetLegal(PtrBase, Offset)) {2011    PtrBase = MI.getOperand(2).getReg();2012    Offset = 0;2013  }2014 2015  MachineBasicBlock *MBB = MI.getParent();2016  const DebugLoc &DL = MI.getDebugLoc();2017  const unsigned Opc = IsAppend ? AMDGPU::DS_APPEND : AMDGPU::DS_CONSUME;2018 2019  BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)2020    .addReg(PtrBase);2021  if (!RBI.constrainGenericRegister(PtrBase, AMDGPU::SReg_32RegClass, *MRI))2022    return false;2023 2024  auto MIB = BuildMI(*MBB, &MI, DL, TII.get(Opc), MI.getOperand(0).getReg())2025    .addImm(Offset)2026    .addImm(IsGDS ? -1 : 0)2027    .cloneMemRefs(MI);2028  MI.eraseFromParent();2029  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);2030}2031 2032bool AMDGPUInstructionSelector::selectInitWholeWave(MachineInstr &MI) const {2033  MachineFunction *MF = MI.getMF();2034  SIMachineFunctionInfo *MFInfo = MF->getInfo<SIMachineFunctionInfo>();2035 2036  MFInfo->setInitWholeWave();2037  return selectImpl(MI, *CoverageInfo);2038}2039 2040static bool parseTexFail(uint64_t TexFailCtrl, bool &TFE, bool &LWE,2041                         bool &IsTexFail) {2042  if (TexFailCtrl)2043    IsTexFail = true;2044 2045  TFE = TexFailCtrl & 0x1;2046  TexFailCtrl &= ~(uint64_t)0x1;2047  LWE = TexFailCtrl & 0x2;2048  TexFailCtrl &= ~(uint64_t)0x2;2049 2050  return TexFailCtrl == 0;2051}2052 2053bool AMDGPUInstructionSelector::selectImageIntrinsic(2054  MachineInstr &MI, const AMDGPU::ImageDimIntrinsicInfo *Intr) const {2055  MachineBasicBlock *MBB = MI.getParent();2056  const DebugLoc &DL = MI.getDebugLoc();2057  unsigned IntrOpcode = Intr->BaseOpcode;2058 2059  // For image atomic: use no-return opcode if result is unused.2060  if (Intr->AtomicNoRetBaseOpcode != Intr->BaseOpcode) {2061    Register ResultDef = MI.getOperand(0).getReg();2062    if (MRI->use_nodbg_empty(ResultDef))2063      IntrOpcode = Intr->AtomicNoRetBaseOpcode;2064  }2065 2066  const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =2067      AMDGPU::getMIMGBaseOpcodeInfo(IntrOpcode);2068 2069  const AMDGPU::MIMGDimInfo *DimInfo = AMDGPU::getMIMGDimInfo(Intr->Dim);2070  const bool IsGFX10Plus = AMDGPU::isGFX10Plus(STI);2071  const bool IsGFX11Plus = AMDGPU::isGFX11Plus(STI);2072  const bool IsGFX12Plus = AMDGPU::isGFX12Plus(STI);2073 2074  const unsigned ArgOffset = MI.getNumExplicitDefs() + 1;2075 2076  Register VDataIn = AMDGPU::NoRegister;2077  Register VDataOut = AMDGPU::NoRegister;2078  LLT VDataTy;2079  int NumVDataDwords = -1;2080  bool IsD16 = MI.getOpcode() == AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD_D16 ||2081               MI.getOpcode() == AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE_D16;2082 2083  bool Unorm;2084  if (!BaseOpcode->Sampler)2085    Unorm = true;2086  else2087    Unorm = MI.getOperand(ArgOffset + Intr->UnormIndex).getImm() != 0;2088 2089  bool TFE;2090  bool LWE;2091  bool IsTexFail = false;2092  if (!parseTexFail(MI.getOperand(ArgOffset + Intr->TexFailCtrlIndex).getImm(),2093                    TFE, LWE, IsTexFail))2094    return false;2095 2096  const int Flags = MI.getOperand(ArgOffset + Intr->NumArgs).getImm();2097  const bool IsA16 = (Flags & 1) != 0;2098  const bool IsG16 = (Flags & 2) != 0;2099 2100  // A16 implies 16 bit gradients if subtarget doesn't support G162101  if (IsA16 && !STI.hasG16() && !IsG16)2102    return false;2103 2104  unsigned DMask = 0;2105  unsigned DMaskLanes = 0;2106 2107  if (BaseOpcode->Atomic) {2108    if (!BaseOpcode->NoReturn)2109      VDataOut = MI.getOperand(0).getReg();2110    VDataIn = MI.getOperand(2).getReg();2111    LLT Ty = MRI->getType(VDataIn);2112 2113    // Be careful to allow atomic swap on 16-bit element vectors.2114    const bool Is64Bit = BaseOpcode->AtomicX2 ?2115      Ty.getSizeInBits() == 128 :2116      Ty.getSizeInBits() == 64;2117 2118    if (BaseOpcode->AtomicX2) {2119      assert(MI.getOperand(3).getReg() == AMDGPU::NoRegister);2120 2121      DMask = Is64Bit ? 0xf : 0x3;2122      NumVDataDwords = Is64Bit ? 4 : 2;2123    } else {2124      DMask = Is64Bit ? 0x3 : 0x1;2125      NumVDataDwords = Is64Bit ? 2 : 1;2126    }2127  } else {2128    DMask = MI.getOperand(ArgOffset + Intr->DMaskIndex).getImm();2129    DMaskLanes = BaseOpcode->Gather4 ? 4 : llvm::popcount(DMask);2130 2131    if (BaseOpcode->Store) {2132      VDataIn = MI.getOperand(1).getReg();2133      VDataTy = MRI->getType(VDataIn);2134      NumVDataDwords = (VDataTy.getSizeInBits() + 31) / 32;2135    } else if (BaseOpcode->NoReturn) {2136      NumVDataDwords = 0;2137    } else {2138      VDataOut = MI.getOperand(0).getReg();2139      VDataTy = MRI->getType(VDataOut);2140      NumVDataDwords = DMaskLanes;2141 2142      if (IsD16 && !STI.hasUnpackedD16VMem())2143        NumVDataDwords = (DMaskLanes + 1) / 2;2144    }2145  }2146 2147  // Set G16 opcode2148  if (Subtarget->hasG16() && IsG16) {2149    const AMDGPU::MIMGG16MappingInfo *G16MappingInfo =2150        AMDGPU::getMIMGG16MappingInfo(Intr->BaseOpcode);2151    assert(G16MappingInfo);2152    IntrOpcode = G16MappingInfo->G16; // set opcode to variant with _g162153  }2154 2155  // TODO: Check this in verifier.2156  assert((!IsTexFail || DMaskLanes >= 1) && "should have legalized this");2157 2158  unsigned CPol = MI.getOperand(ArgOffset + Intr->CachePolicyIndex).getImm();2159  // Keep GLC only when the atomic's result is actually used.2160  if (BaseOpcode->Atomic && !BaseOpcode->NoReturn)2161    CPol |= AMDGPU::CPol::GLC;2162  if (CPol & ~((IsGFX12Plus ? AMDGPU::CPol::ALL : AMDGPU::CPol::ALL_pregfx12) |2163               AMDGPU::CPol::VOLATILE))2164    return false;2165 2166  int NumVAddrRegs = 0;2167  int NumVAddrDwords = 0;2168  for (unsigned I = Intr->VAddrStart; I < Intr->VAddrEnd; I++) {2169    // Skip the $noregs and 0s inserted during legalization.2170    MachineOperand &AddrOp = MI.getOperand(ArgOffset + I);2171    if (!AddrOp.isReg())2172      continue; // XXX - Break?2173 2174    Register Addr = AddrOp.getReg();2175    if (!Addr)2176      break;2177 2178    ++NumVAddrRegs;2179    NumVAddrDwords += (MRI->getType(Addr).getSizeInBits() + 31) / 32;2180  }2181 2182  // The legalizer preprocessed the intrinsic arguments. If we aren't using2183  // NSA, these should have been packed into a single value in the first2184  // address register2185  const bool UseNSA =2186      NumVAddrRegs != 1 &&2187      (STI.hasPartialNSAEncoding() ? NumVAddrDwords >= NumVAddrRegs2188                                   : NumVAddrDwords == NumVAddrRegs);2189  if (UseNSA && !STI.hasFeature(AMDGPU::FeatureNSAEncoding)) {2190    LLVM_DEBUG(dbgs() << "Trying to use NSA on non-NSA target\n");2191    return false;2192  }2193 2194  if (IsTexFail)2195    ++NumVDataDwords;2196 2197  int Opcode = -1;2198  if (IsGFX12Plus) {2199    Opcode = AMDGPU::getMIMGOpcode(IntrOpcode, AMDGPU::MIMGEncGfx12,2200                                   NumVDataDwords, NumVAddrDwords);2201  } else if (IsGFX11Plus) {2202    Opcode = AMDGPU::getMIMGOpcode(IntrOpcode,2203                                   UseNSA ? AMDGPU::MIMGEncGfx11NSA2204                                          : AMDGPU::MIMGEncGfx11Default,2205                                   NumVDataDwords, NumVAddrDwords);2206  } else if (IsGFX10Plus) {2207    Opcode = AMDGPU::getMIMGOpcode(IntrOpcode,2208                                   UseNSA ? AMDGPU::MIMGEncGfx10NSA2209                                          : AMDGPU::MIMGEncGfx10Default,2210                                   NumVDataDwords, NumVAddrDwords);2211  } else {2212    if (Subtarget->hasGFX90AInsts()) {2213      Opcode = AMDGPU::getMIMGOpcode(IntrOpcode, AMDGPU::MIMGEncGfx90a,2214                                     NumVDataDwords, NumVAddrDwords);2215      if (Opcode == -1) {2216        LLVM_DEBUG(2217            dbgs()2218            << "requested image instruction is not supported on this GPU\n");2219        return false;2220      }2221    }2222    if (Opcode == -1 &&2223        STI.getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS)2224      Opcode = AMDGPU::getMIMGOpcode(IntrOpcode, AMDGPU::MIMGEncGfx8,2225                                     NumVDataDwords, NumVAddrDwords);2226    if (Opcode == -1)2227      Opcode = AMDGPU::getMIMGOpcode(IntrOpcode, AMDGPU::MIMGEncGfx6,2228                                     NumVDataDwords, NumVAddrDwords);2229  }2230  if (Opcode == -1)2231    return false;2232 2233  auto MIB = BuildMI(*MBB, &MI, DL, TII.get(Opcode))2234    .cloneMemRefs(MI);2235 2236  if (VDataOut) {2237    if (BaseOpcode->AtomicX2) {2238      const bool Is64 = MRI->getType(VDataOut).getSizeInBits() == 64;2239 2240      Register TmpReg = MRI->createVirtualRegister(2241        Is64 ? &AMDGPU::VReg_128RegClass : &AMDGPU::VReg_64RegClass);2242      unsigned SubReg = Is64 ? AMDGPU::sub0_sub1 : AMDGPU::sub0;2243 2244      MIB.addDef(TmpReg);2245      if (!MRI->use_empty(VDataOut)) {2246        BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::COPY), VDataOut)2247            .addReg(TmpReg, RegState::Kill, SubReg);2248      }2249 2250    } else {2251      MIB.addDef(VDataOut); // vdata output2252    }2253  }2254 2255  if (VDataIn)2256    MIB.addReg(VDataIn); // vdata input2257 2258  for (int I = 0; I != NumVAddrRegs; ++I) {2259    MachineOperand &SrcOp = MI.getOperand(ArgOffset + Intr->VAddrStart + I);2260    if (SrcOp.isReg()) {2261      assert(SrcOp.getReg() != 0);2262      MIB.addReg(SrcOp.getReg());2263    }2264  }2265 2266  MIB.addReg(MI.getOperand(ArgOffset + Intr->RsrcIndex).getReg());2267  if (BaseOpcode->Sampler)2268    MIB.addReg(MI.getOperand(ArgOffset + Intr->SampIndex).getReg());2269 2270  MIB.addImm(DMask); // dmask2271 2272  if (IsGFX10Plus)2273    MIB.addImm(DimInfo->Encoding);2274  if (AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::unorm))2275    MIB.addImm(Unorm);2276 2277  MIB.addImm(CPol);2278  MIB.addImm(IsA16 &&  // a16 or r1282279             STI.hasFeature(AMDGPU::FeatureR128A16) ? -1 : 0);2280  if (IsGFX10Plus)2281    MIB.addImm(IsA16 ? -1 : 0);2282 2283  if (!Subtarget->hasGFX90AInsts()) {2284    MIB.addImm(TFE); // tfe2285  } else if (TFE) {2286    LLVM_DEBUG(dbgs() << "TFE is not supported on this GPU\n");2287    return false;2288  }2289 2290  if (AMDGPU::hasNamedOperand(Opcode, AMDGPU::OpName::lwe))2291    MIB.addImm(LWE); // lwe2292  if (!IsGFX10Plus)2293    MIB.addImm(DimInfo->DA ? -1 : 0);2294  if (BaseOpcode->HasD16)2295    MIB.addImm(IsD16 ? -1 : 0);2296 2297  MI.eraseFromParent();2298  constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);2299  TII.enforceOperandRCAlignment(*MIB, AMDGPU::OpName::vaddr);2300  return true;2301}2302 2303// We need to handle this here because tablegen doesn't support matching2304// instructions with multiple outputs.2305bool AMDGPUInstructionSelector::selectDSBvhStackIntrinsic(2306    MachineInstr &MI) const {2307  Register Dst0 = MI.getOperand(0).getReg();2308  Register Dst1 = MI.getOperand(1).getReg();2309 2310  const DebugLoc &DL = MI.getDebugLoc();2311  MachineBasicBlock *MBB = MI.getParent();2312 2313  Register Addr = MI.getOperand(3).getReg();2314  Register Data0 = MI.getOperand(4).getReg();2315  Register Data1 = MI.getOperand(5).getReg();2316  unsigned Offset = MI.getOperand(6).getImm();2317 2318  unsigned Opc;2319  switch (cast<GIntrinsic>(MI).getIntrinsicID()) {2320  case Intrinsic::amdgcn_ds_bvh_stack_rtn:2321  case Intrinsic::amdgcn_ds_bvh_stack_push4_pop1_rtn:2322    Opc = AMDGPU::DS_BVH_STACK_RTN_B32;2323    break;2324  case Intrinsic::amdgcn_ds_bvh_stack_push8_pop1_rtn:2325    Opc = AMDGPU::DS_BVH_STACK_PUSH8_POP1_RTN_B32;2326    break;2327  case Intrinsic::amdgcn_ds_bvh_stack_push8_pop2_rtn:2328    Opc = AMDGPU::DS_BVH_STACK_PUSH8_POP2_RTN_B64;2329    break;2330  }2331 2332  auto MIB = BuildMI(*MBB, &MI, DL, TII.get(Opc), Dst0)2333                 .addDef(Dst1)2334                 .addUse(Addr)2335                 .addUse(Data0)2336                 .addUse(Data1)2337                 .addImm(Offset)2338                 .cloneMemRefs(MI);2339 2340  MI.eraseFromParent();2341  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);2342}2343 2344bool AMDGPUInstructionSelector::selectG_INTRINSIC_W_SIDE_EFFECTS(2345    MachineInstr &I) const {2346  Intrinsic::ID IntrinsicID = cast<GIntrinsic>(I).getIntrinsicID();2347  switch (IntrinsicID) {2348  case Intrinsic::amdgcn_end_cf:2349    return selectEndCfIntrinsic(I);2350  case Intrinsic::amdgcn_ds_ordered_add:2351  case Intrinsic::amdgcn_ds_ordered_swap:2352    return selectDSOrderedIntrinsic(I, IntrinsicID);2353  case Intrinsic::amdgcn_ds_gws_init:2354  case Intrinsic::amdgcn_ds_gws_barrier:2355  case Intrinsic::amdgcn_ds_gws_sema_v:2356  case Intrinsic::amdgcn_ds_gws_sema_br:2357  case Intrinsic::amdgcn_ds_gws_sema_p:2358  case Intrinsic::amdgcn_ds_gws_sema_release_all:2359    return selectDSGWSIntrinsic(I, IntrinsicID);2360  case Intrinsic::amdgcn_ds_append:2361    return selectDSAppendConsume(I, true);2362  case Intrinsic::amdgcn_ds_consume:2363    return selectDSAppendConsume(I, false);2364  case Intrinsic::amdgcn_init_whole_wave:2365    return selectInitWholeWave(I);2366  case Intrinsic::amdgcn_raw_buffer_load_lds:2367  case Intrinsic::amdgcn_raw_ptr_buffer_load_lds:2368  case Intrinsic::amdgcn_struct_buffer_load_lds:2369  case Intrinsic::amdgcn_struct_ptr_buffer_load_lds:2370    return selectBufferLoadLds(I);2371  // Until we can store both the address space of the global and the LDS2372  // arguments by having tto MachineMemOperands on an intrinsic, we just trust2373  // that the argument is a global pointer (buffer pointers have been handled by2374  // a LLVM IR-level lowering).2375  case Intrinsic::amdgcn_load_to_lds:2376  case Intrinsic::amdgcn_global_load_lds:2377    return selectGlobalLoadLds(I);2378  case Intrinsic::amdgcn_exp_compr:2379    if (!STI.hasCompressedExport()) {2380      Function &F = I.getMF()->getFunction();2381      F.getContext().diagnose(2382          DiagnosticInfoUnsupported(F, "intrinsic not supported on subtarget",2383                                    I.getDebugLoc(), DS_Error));2384      return false;2385    }2386    break;2387  case Intrinsic::amdgcn_ds_bvh_stack_rtn:2388  case Intrinsic::amdgcn_ds_bvh_stack_push4_pop1_rtn:2389  case Intrinsic::amdgcn_ds_bvh_stack_push8_pop1_rtn:2390  case Intrinsic::amdgcn_ds_bvh_stack_push8_pop2_rtn:2391    return selectDSBvhStackIntrinsic(I);2392  case Intrinsic::amdgcn_s_barrier_init:2393  case Intrinsic::amdgcn_s_barrier_signal_var:2394    return selectNamedBarrierInit(I, IntrinsicID);2395  case Intrinsic::amdgcn_s_barrier_join:2396  case Intrinsic::amdgcn_s_get_named_barrier_state:2397    return selectNamedBarrierInst(I, IntrinsicID);2398  case Intrinsic::amdgcn_s_get_barrier_state:2399    return selectSGetBarrierState(I, IntrinsicID);2400  case Intrinsic::amdgcn_s_barrier_signal_isfirst:2401    return selectSBarrierSignalIsfirst(I, IntrinsicID);2402  }2403  return selectImpl(I, *CoverageInfo);2404}2405 2406bool AMDGPUInstructionSelector::selectG_SELECT(MachineInstr &I) const {2407  if (selectImpl(I, *CoverageInfo))2408    return true;2409 2410  MachineBasicBlock *BB = I.getParent();2411  const DebugLoc &DL = I.getDebugLoc();2412 2413  Register DstReg = I.getOperand(0).getReg();2414  unsigned Size = RBI.getSizeInBits(DstReg, *MRI, TRI);2415  assert(Size <= 32 || Size == 64);2416  const MachineOperand &CCOp = I.getOperand(1);2417  Register CCReg = CCOp.getReg();2418  if (!isVCC(CCReg, *MRI)) {2419    unsigned SelectOpcode = Size == 64 ? AMDGPU::S_CSELECT_B64 :2420                                         AMDGPU::S_CSELECT_B32;2421    MachineInstr *CopySCC = BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), AMDGPU::SCC)2422            .addReg(CCReg);2423 2424    // The generic constrainSelectedInstRegOperands doesn't work for the scc register2425    // bank, because it does not cover the register class that we used to represent2426    // for it.  So we need to manually set the register class here.2427    if (!MRI->getRegClassOrNull(CCReg))2428        MRI->setRegClass(CCReg, TRI.getConstrainedRegClassForOperand(CCOp, *MRI));2429    MachineInstr *Select = BuildMI(*BB, &I, DL, TII.get(SelectOpcode), DstReg)2430            .add(I.getOperand(2))2431            .add(I.getOperand(3));2432 2433    bool Ret = false;2434    Ret |= constrainSelectedInstRegOperands(*Select, TII, TRI, RBI);2435    Ret |= constrainSelectedInstRegOperands(*CopySCC, TII, TRI, RBI);2436    I.eraseFromParent();2437    return Ret;2438  }2439 2440  // Wide VGPR select should have been split in RegBankSelect.2441  if (Size > 32)2442    return false;2443 2444  MachineInstr *Select =2445      BuildMI(*BB, &I, DL, TII.get(AMDGPU::V_CNDMASK_B32_e64), DstReg)2446              .addImm(0)2447              .add(I.getOperand(3))2448              .addImm(0)2449              .add(I.getOperand(2))2450              .add(I.getOperand(1));2451 2452  bool Ret = constrainSelectedInstRegOperands(*Select, TII, TRI, RBI);2453  I.eraseFromParent();2454  return Ret;2455}2456 2457bool AMDGPUInstructionSelector::selectG_TRUNC(MachineInstr &I) const {2458  Register DstReg = I.getOperand(0).getReg();2459  Register SrcReg = I.getOperand(1).getReg();2460  const LLT DstTy = MRI->getType(DstReg);2461  const LLT SrcTy = MRI->getType(SrcReg);2462  const LLT S1 = LLT::scalar(1);2463 2464  const RegisterBank *SrcRB = RBI.getRegBank(SrcReg, *MRI, TRI);2465  const RegisterBank *DstRB;2466  if (DstTy == S1) {2467    // This is a special case. We don't treat s1 for legalization artifacts as2468    // vcc booleans.2469    DstRB = SrcRB;2470  } else {2471    DstRB = RBI.getRegBank(DstReg, *MRI, TRI);2472    if (SrcRB != DstRB)2473      return false;2474  }2475 2476  const bool IsVALU = DstRB->getID() == AMDGPU::VGPRRegBankID;2477 2478  unsigned DstSize = DstTy.getSizeInBits();2479  unsigned SrcSize = SrcTy.getSizeInBits();2480 2481  const TargetRegisterClass *SrcRC =2482      TRI.getRegClassForSizeOnBank(SrcSize, *SrcRB);2483  const TargetRegisterClass *DstRC =2484      TRI.getRegClassForSizeOnBank(DstSize, *DstRB);2485  if (!SrcRC || !DstRC)2486    return false;2487 2488  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI) ||2489      !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI)) {2490    LLVM_DEBUG(dbgs() << "Failed to constrain G_TRUNC\n");2491    return false;2492  }2493 2494  if (DstRC == &AMDGPU::VGPR_16RegClass && SrcSize == 32) {2495    assert(STI.useRealTrue16Insts());2496    const DebugLoc &DL = I.getDebugLoc();2497    MachineBasicBlock *MBB = I.getParent();2498    BuildMI(*MBB, I, DL, TII.get(AMDGPU::COPY), DstReg)2499        .addReg(SrcReg, 0, AMDGPU::lo16);2500    I.eraseFromParent();2501    return true;2502  }2503 2504  if (DstTy == LLT::fixed_vector(2, 16) && SrcTy == LLT::fixed_vector(2, 32)) {2505    MachineBasicBlock *MBB = I.getParent();2506    const DebugLoc &DL = I.getDebugLoc();2507 2508    Register LoReg = MRI->createVirtualRegister(DstRC);2509    Register HiReg = MRI->createVirtualRegister(DstRC);2510    BuildMI(*MBB, I, DL, TII.get(AMDGPU::COPY), LoReg)2511      .addReg(SrcReg, 0, AMDGPU::sub0);2512    BuildMI(*MBB, I, DL, TII.get(AMDGPU::COPY), HiReg)2513      .addReg(SrcReg, 0, AMDGPU::sub1);2514 2515    if (IsVALU && STI.hasSDWA()) {2516      // Write the low 16-bits of the high element into the high 16-bits of the2517      // low element.2518      MachineInstr *MovSDWA =2519        BuildMI(*MBB, I, DL, TII.get(AMDGPU::V_MOV_B32_sdwa), DstReg)2520        .addImm(0)                             // $src0_modifiers2521        .addReg(HiReg)                         // $src02522        .addImm(0)                             // $clamp2523        .addImm(AMDGPU::SDWA::WORD_1)          // $dst_sel2524        .addImm(AMDGPU::SDWA::UNUSED_PRESERVE) // $dst_unused2525        .addImm(AMDGPU::SDWA::WORD_0)          // $src0_sel2526        .addReg(LoReg, RegState::Implicit);2527      MovSDWA->tieOperands(0, MovSDWA->getNumOperands() - 1);2528    } else {2529      Register TmpReg0 = MRI->createVirtualRegister(DstRC);2530      Register TmpReg1 = MRI->createVirtualRegister(DstRC);2531      Register ImmReg = MRI->createVirtualRegister(DstRC);2532      if (IsVALU) {2533        BuildMI(*MBB, I, DL, TII.get(AMDGPU::V_LSHLREV_B32_e64), TmpReg0)2534          .addImm(16)2535          .addReg(HiReg);2536      } else {2537        BuildMI(*MBB, I, DL, TII.get(AMDGPU::S_LSHL_B32), TmpReg0)2538          .addReg(HiReg)2539          .addImm(16)2540          .setOperandDead(3); // Dead scc2541      }2542 2543      unsigned MovOpc = IsVALU ? AMDGPU::V_MOV_B32_e32 : AMDGPU::S_MOV_B32;2544      unsigned AndOpc = IsVALU ? AMDGPU::V_AND_B32_e64 : AMDGPU::S_AND_B32;2545      unsigned OrOpc = IsVALU ? AMDGPU::V_OR_B32_e64 : AMDGPU::S_OR_B32;2546 2547      BuildMI(*MBB, I, DL, TII.get(MovOpc), ImmReg)2548        .addImm(0xffff);2549      auto And = BuildMI(*MBB, I, DL, TII.get(AndOpc), TmpReg1)2550        .addReg(LoReg)2551        .addReg(ImmReg);2552      auto Or = BuildMI(*MBB, I, DL, TII.get(OrOpc), DstReg)2553        .addReg(TmpReg0)2554        .addReg(TmpReg1);2555 2556      if (!IsVALU) {2557        And.setOperandDead(3); // Dead scc2558        Or.setOperandDead(3); // Dead scc2559      }2560    }2561 2562    I.eraseFromParent();2563    return true;2564  }2565 2566  if (!DstTy.isScalar())2567    return false;2568 2569  if (SrcSize > 32) {2570    unsigned SubRegIdx = DstSize < 322571                             ? static_cast<unsigned>(AMDGPU::sub0)2572                             : TRI.getSubRegFromChannel(0, DstSize / 32);2573    if (SubRegIdx == AMDGPU::NoSubRegister)2574      return false;2575 2576    // Deal with weird cases where the class only partially supports the subreg2577    // index.2578    const TargetRegisterClass *SrcWithSubRC2579      = TRI.getSubClassWithSubReg(SrcRC, SubRegIdx);2580    if (!SrcWithSubRC)2581      return false;2582 2583    if (SrcWithSubRC != SrcRC) {2584      if (!RBI.constrainGenericRegister(SrcReg, *SrcWithSubRC, *MRI))2585        return false;2586    }2587 2588    I.getOperand(1).setSubReg(SubRegIdx);2589  }2590 2591  I.setDesc(TII.get(TargetOpcode::COPY));2592  return true;2593}2594 2595/// \returns true if a bitmask for \p Size bits will be an inline immediate.2596static bool shouldUseAndMask(unsigned Size, unsigned &Mask) {2597  Mask = maskTrailingOnes<unsigned>(Size);2598  int SignedMask = static_cast<int>(Mask);2599  return SignedMask >= -16 && SignedMask <= 64;2600}2601 2602// Like RegisterBankInfo::getRegBank, but don't assume vcc for s1.2603const RegisterBank *AMDGPUInstructionSelector::getArtifactRegBank(2604  Register Reg, const MachineRegisterInfo &MRI,2605  const TargetRegisterInfo &TRI) const {2606  const RegClassOrRegBank &RegClassOrBank = MRI.getRegClassOrRegBank(Reg);2607  if (auto *RB = dyn_cast<const RegisterBank *>(RegClassOrBank))2608    return RB;2609 2610  // Ignore the type, since we don't use vcc in artifacts.2611  if (auto *RC = dyn_cast<const TargetRegisterClass *>(RegClassOrBank))2612    return &RBI.getRegBankFromRegClass(*RC, LLT());2613  return nullptr;2614}2615 2616bool AMDGPUInstructionSelector::selectG_SZA_EXT(MachineInstr &I) const {2617  bool InReg = I.getOpcode() == AMDGPU::G_SEXT_INREG;2618  bool Signed = I.getOpcode() == AMDGPU::G_SEXT || InReg;2619  const DebugLoc &DL = I.getDebugLoc();2620  MachineBasicBlock &MBB = *I.getParent();2621  const Register DstReg = I.getOperand(0).getReg();2622  const Register SrcReg = I.getOperand(1).getReg();2623 2624  const LLT DstTy = MRI->getType(DstReg);2625  const LLT SrcTy = MRI->getType(SrcReg);2626  const unsigned SrcSize = I.getOpcode() == AMDGPU::G_SEXT_INREG ?2627    I.getOperand(2).getImm() : SrcTy.getSizeInBits();2628  const unsigned DstSize = DstTy.getSizeInBits();2629  if (!DstTy.isScalar())2630    return false;2631 2632  // Artifact casts should never use vcc.2633  const RegisterBank *SrcBank = getArtifactRegBank(SrcReg, *MRI, TRI);2634 2635  // FIXME: This should probably be illegal and split earlier.2636  if (I.getOpcode() == AMDGPU::G_ANYEXT) {2637    if (DstSize <= 32)2638      return selectCOPY(I);2639 2640    const TargetRegisterClass *SrcRC =2641        TRI.getRegClassForTypeOnBank(SrcTy, *SrcBank);2642    const RegisterBank *DstBank = RBI.getRegBank(DstReg, *MRI, TRI);2643    const TargetRegisterClass *DstRC =2644        TRI.getRegClassForSizeOnBank(DstSize, *DstBank);2645 2646    Register UndefReg = MRI->createVirtualRegister(SrcRC);2647    BuildMI(MBB, I, DL, TII.get(AMDGPU::IMPLICIT_DEF), UndefReg);2648    BuildMI(MBB, I, DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)2649      .addReg(SrcReg)2650      .addImm(AMDGPU::sub0)2651      .addReg(UndefReg)2652      .addImm(AMDGPU::sub1);2653    I.eraseFromParent();2654 2655    return RBI.constrainGenericRegister(DstReg, *DstRC, *MRI) &&2656           RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI);2657  }2658 2659  if (SrcBank->getID() == AMDGPU::VGPRRegBankID && DstSize <= 32) {2660    // 64-bit should have been split up in RegBankSelect2661 2662    // Try to use an and with a mask if it will save code size.2663    unsigned Mask;2664    if (!Signed && shouldUseAndMask(SrcSize, Mask)) {2665      MachineInstr *ExtI =2666      BuildMI(MBB, I, DL, TII.get(AMDGPU::V_AND_B32_e32), DstReg)2667        .addImm(Mask)2668        .addReg(SrcReg);2669      I.eraseFromParent();2670      return constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI);2671    }2672 2673    const unsigned BFE = Signed ? AMDGPU::V_BFE_I32_e64 : AMDGPU::V_BFE_U32_e64;2674    MachineInstr *ExtI =2675      BuildMI(MBB, I, DL, TII.get(BFE), DstReg)2676      .addReg(SrcReg)2677      .addImm(0) // Offset2678      .addImm(SrcSize); // Width2679    I.eraseFromParent();2680    return constrainSelectedInstRegOperands(*ExtI, TII, TRI, RBI);2681  }2682 2683  if (SrcBank->getID() == AMDGPU::SGPRRegBankID && DstSize <= 64) {2684    const TargetRegisterClass &SrcRC = InReg && DstSize > 32 ?2685      AMDGPU::SReg_64RegClass : AMDGPU::SReg_32RegClass;2686    if (!RBI.constrainGenericRegister(SrcReg, SrcRC, *MRI))2687      return false;2688 2689    if (Signed && DstSize == 32 && (SrcSize == 8 || SrcSize == 16)) {2690      const unsigned SextOpc = SrcSize == 8 ?2691        AMDGPU::S_SEXT_I32_I8 : AMDGPU::S_SEXT_I32_I16;2692      BuildMI(MBB, I, DL, TII.get(SextOpc), DstReg)2693        .addReg(SrcReg);2694      I.eraseFromParent();2695      return RBI.constrainGenericRegister(DstReg, AMDGPU::SReg_32RegClass, *MRI);2696    }2697 2698    // Using a single 32-bit SALU to calculate the high half is smaller than2699    // S_BFE with a literal constant operand.2700    if (DstSize > 32 && SrcSize == 32) {2701      Register HiReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);2702      unsigned SubReg = InReg ? AMDGPU::sub0 : AMDGPU::NoSubRegister;2703      if (Signed) {2704        BuildMI(MBB, I, DL, TII.get(AMDGPU::S_ASHR_I32), HiReg)2705          .addReg(SrcReg, 0, SubReg)2706          .addImm(31)2707          .setOperandDead(3); // Dead scc2708      } else {2709        BuildMI(MBB, I, DL, TII.get(AMDGPU::S_MOV_B32), HiReg)2710          .addImm(0);2711      }2712      BuildMI(MBB, I, DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)2713        .addReg(SrcReg, 0, SubReg)2714        .addImm(AMDGPU::sub0)2715        .addReg(HiReg)2716        .addImm(AMDGPU::sub1);2717      I.eraseFromParent();2718      return RBI.constrainGenericRegister(DstReg, AMDGPU::SReg_64RegClass,2719                                          *MRI);2720    }2721 2722    const unsigned BFE64 = Signed ? AMDGPU::S_BFE_I64 : AMDGPU::S_BFE_U64;2723    const unsigned BFE32 = Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32;2724 2725    // Scalar BFE is encoded as S1[5:0] = offset, S1[22:16]= width.2726    if (DstSize > 32 && (SrcSize <= 32 || InReg)) {2727      // We need a 64-bit register source, but the high bits don't matter.2728      Register ExtReg = MRI->createVirtualRegister(&AMDGPU::SReg_64RegClass);2729      Register UndefReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);2730      unsigned SubReg = InReg ? AMDGPU::sub0 : AMDGPU::NoSubRegister;2731 2732      BuildMI(MBB, I, DL, TII.get(AMDGPU::IMPLICIT_DEF), UndefReg);2733      BuildMI(MBB, I, DL, TII.get(AMDGPU::REG_SEQUENCE), ExtReg)2734        .addReg(SrcReg, 0, SubReg)2735        .addImm(AMDGPU::sub0)2736        .addReg(UndefReg)2737        .addImm(AMDGPU::sub1);2738 2739      BuildMI(MBB, I, DL, TII.get(BFE64), DstReg)2740        .addReg(ExtReg)2741        .addImm(SrcSize << 16);2742 2743      I.eraseFromParent();2744      return RBI.constrainGenericRegister(DstReg, AMDGPU::SReg_64RegClass, *MRI);2745    }2746 2747    unsigned Mask;2748    if (!Signed && shouldUseAndMask(SrcSize, Mask)) {2749      BuildMI(MBB, I, DL, TII.get(AMDGPU::S_AND_B32), DstReg)2750        .addReg(SrcReg)2751        .addImm(Mask)2752        .setOperandDead(3); // Dead scc2753    } else {2754      BuildMI(MBB, I, DL, TII.get(BFE32), DstReg)2755        .addReg(SrcReg)2756        .addImm(SrcSize << 16);2757    }2758 2759    I.eraseFromParent();2760    return RBI.constrainGenericRegister(DstReg, AMDGPU::SReg_32RegClass, *MRI);2761  }2762 2763  return false;2764}2765 2766static Register stripCopy(Register Reg, MachineRegisterInfo &MRI) {2767  return getDefSrcRegIgnoringCopies(Reg, MRI)->Reg;2768}2769 2770static Register stripBitCast(Register Reg, MachineRegisterInfo &MRI) {2771  Register BitcastSrc;2772  if (mi_match(Reg, MRI, m_GBitcast(m_Reg(BitcastSrc))))2773    Reg = BitcastSrc;2774  return Reg;2775}2776 2777static bool isExtractHiElt(MachineRegisterInfo &MRI, Register In,2778                           Register &Out) {2779  Register Trunc;2780  if (!mi_match(In, MRI, m_GTrunc(m_Reg(Trunc))))2781    return false;2782 2783  Register LShlSrc;2784  Register Cst;2785  if (mi_match(Trunc, MRI, m_GLShr(m_Reg(LShlSrc), m_Reg(Cst)))) {2786    Cst = stripCopy(Cst, MRI);2787    if (mi_match(Cst, MRI, m_SpecificICst(16))) {2788      Out = stripBitCast(LShlSrc, MRI);2789      return true;2790    }2791  }2792 2793  MachineInstr *Shuffle = MRI.getVRegDef(Trunc);2794  if (Shuffle->getOpcode() != AMDGPU::G_SHUFFLE_VECTOR)2795    return false;2796 2797  assert(MRI.getType(Shuffle->getOperand(0).getReg()) ==2798         LLT::fixed_vector(2, 16));2799 2800  ArrayRef<int> Mask = Shuffle->getOperand(3).getShuffleMask();2801  assert(Mask.size() == 2);2802 2803  if (Mask[0] == 1 && Mask[1] <= 1) {2804    Out = Shuffle->getOperand(0).getReg();2805    return true;2806  }2807 2808  return false;2809}2810 2811bool AMDGPUInstructionSelector::selectG_FPEXT(MachineInstr &I) const {2812  if (!Subtarget->hasSALUFloatInsts())2813    return false;2814 2815  Register Dst = I.getOperand(0).getReg();2816  const RegisterBank *DstRB = RBI.getRegBank(Dst, *MRI, TRI);2817  if (DstRB->getID() != AMDGPU::SGPRRegBankID)2818    return false;2819 2820  Register Src = I.getOperand(1).getReg();2821 2822  if (MRI->getType(Dst) == LLT::scalar(32) &&2823      MRI->getType(Src) == LLT::scalar(16)) {2824    if (isExtractHiElt(*MRI, Src, Src)) {2825      MachineBasicBlock *BB = I.getParent();2826      BuildMI(*BB, &I, I.getDebugLoc(), TII.get(AMDGPU::S_CVT_HI_F32_F16), Dst)2827          .addUse(Src);2828      I.eraseFromParent();2829      return RBI.constrainGenericRegister(Dst, AMDGPU::SReg_32RegClass, *MRI);2830    }2831  }2832 2833  return false;2834}2835 2836bool AMDGPUInstructionSelector::selectG_FNEG(MachineInstr &MI) const {2837  // Only manually handle the f64 SGPR case.2838  //2839  // FIXME: This is a workaround for 2.5 different tablegen problems. Because2840  // the bit ops theoretically have a second result due to the implicit def of2841  // SCC, the GlobalISelEmitter is overly conservative and rejects it. Fixing2842  // that is easy by disabling the check. The result works, but uses a2843  // nonsensical sreg32orlds_and_sreg_1 regclass.2844  //2845  // The DAG emitter is more problematic, and incorrectly adds both S_XOR_B32 to2846  // the variadic REG_SEQUENCE operands.2847 2848  Register Dst = MI.getOperand(0).getReg();2849  const RegisterBank *DstRB = RBI.getRegBank(Dst, *MRI, TRI);2850  if (DstRB->getID() != AMDGPU::SGPRRegBankID ||2851      MRI->getType(Dst) != LLT::scalar(64))2852    return false;2853 2854  Register Src = MI.getOperand(1).getReg();2855  MachineInstr *Fabs = getOpcodeDef(TargetOpcode::G_FABS, Src, *MRI);2856  if (Fabs)2857    Src = Fabs->getOperand(1).getReg();2858 2859  if (!RBI.constrainGenericRegister(Src, AMDGPU::SReg_64RegClass, *MRI) ||2860      !RBI.constrainGenericRegister(Dst, AMDGPU::SReg_64RegClass, *MRI))2861    return false;2862 2863  MachineBasicBlock *BB = MI.getParent();2864  const DebugLoc &DL = MI.getDebugLoc();2865  Register LoReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);2866  Register HiReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);2867  Register ConstReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);2868  Register OpReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);2869 2870  BuildMI(*BB, &MI, DL, TII.get(AMDGPU::COPY), LoReg)2871    .addReg(Src, 0, AMDGPU::sub0);2872  BuildMI(*BB, &MI, DL, TII.get(AMDGPU::COPY), HiReg)2873    .addReg(Src, 0, AMDGPU::sub1);2874  BuildMI(*BB, &MI, DL, TII.get(AMDGPU::S_MOV_B32), ConstReg)2875    .addImm(0x80000000);2876 2877  // Set or toggle sign bit.2878  unsigned Opc = Fabs ? AMDGPU::S_OR_B32 : AMDGPU::S_XOR_B32;2879  BuildMI(*BB, &MI, DL, TII.get(Opc), OpReg)2880    .addReg(HiReg)2881    .addReg(ConstReg)2882    .setOperandDead(3); // Dead scc2883  BuildMI(*BB, &MI, DL, TII.get(AMDGPU::REG_SEQUENCE), Dst)2884    .addReg(LoReg)2885    .addImm(AMDGPU::sub0)2886    .addReg(OpReg)2887    .addImm(AMDGPU::sub1);2888  MI.eraseFromParent();2889  return true;2890}2891 2892// FIXME: This is a workaround for the same tablegen problems as G_FNEG2893bool AMDGPUInstructionSelector::selectG_FABS(MachineInstr &MI) const {2894  Register Dst = MI.getOperand(0).getReg();2895  const RegisterBank *DstRB = RBI.getRegBank(Dst, *MRI, TRI);2896  if (DstRB->getID() != AMDGPU::SGPRRegBankID ||2897      MRI->getType(Dst) != LLT::scalar(64))2898    return false;2899 2900  Register Src = MI.getOperand(1).getReg();2901  MachineBasicBlock *BB = MI.getParent();2902  const DebugLoc &DL = MI.getDebugLoc();2903  Register LoReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);2904  Register HiReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);2905  Register ConstReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);2906  Register OpReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);2907 2908  if (!RBI.constrainGenericRegister(Src, AMDGPU::SReg_64RegClass, *MRI) ||2909      !RBI.constrainGenericRegister(Dst, AMDGPU::SReg_64RegClass, *MRI))2910    return false;2911 2912  BuildMI(*BB, &MI, DL, TII.get(AMDGPU::COPY), LoReg)2913    .addReg(Src, 0, AMDGPU::sub0);2914  BuildMI(*BB, &MI, DL, TII.get(AMDGPU::COPY), HiReg)2915    .addReg(Src, 0, AMDGPU::sub1);2916  BuildMI(*BB, &MI, DL, TII.get(AMDGPU::S_MOV_B32), ConstReg)2917    .addImm(0x7fffffff);2918 2919  // Clear sign bit.2920  // TODO: Should this used S_BITSET0_*?2921  BuildMI(*BB, &MI, DL, TII.get(AMDGPU::S_AND_B32), OpReg)2922    .addReg(HiReg)2923    .addReg(ConstReg)2924    .setOperandDead(3); // Dead scc2925  BuildMI(*BB, &MI, DL, TII.get(AMDGPU::REG_SEQUENCE), Dst)2926    .addReg(LoReg)2927    .addImm(AMDGPU::sub0)2928    .addReg(OpReg)2929    .addImm(AMDGPU::sub1);2930 2931  MI.eraseFromParent();2932  return true;2933}2934 2935static bool isConstant(const MachineInstr &MI) {2936  return MI.getOpcode() == TargetOpcode::G_CONSTANT;2937}2938 2939void AMDGPUInstructionSelector::getAddrModeInfo(const MachineInstr &Load,2940    const MachineRegisterInfo &MRI, SmallVectorImpl<GEPInfo> &AddrInfo) const {2941 2942  unsigned OpNo = Load.getOpcode() == AMDGPU::G_PREFETCH ? 0 : 1;2943  const MachineInstr *PtrMI =2944      MRI.getUniqueVRegDef(Load.getOperand(OpNo).getReg());2945 2946  assert(PtrMI);2947 2948  if (PtrMI->getOpcode() != TargetOpcode::G_PTR_ADD)2949    return;2950 2951  GEPInfo GEPInfo;2952 2953  for (unsigned i = 1; i != 3; ++i) {2954    const MachineOperand &GEPOp = PtrMI->getOperand(i);2955    const MachineInstr *OpDef = MRI.getUniqueVRegDef(GEPOp.getReg());2956    assert(OpDef);2957    if (i == 2 && isConstant(*OpDef)) {2958      // TODO: Could handle constant base + variable offset, but a combine2959      // probably should have commuted it.2960      assert(GEPInfo.Imm == 0);2961      GEPInfo.Imm = OpDef->getOperand(1).getCImm()->getSExtValue();2962      continue;2963    }2964    const RegisterBank *OpBank = RBI.getRegBank(GEPOp.getReg(), MRI, TRI);2965    if (OpBank->getID() == AMDGPU::SGPRRegBankID)2966      GEPInfo.SgprParts.push_back(GEPOp.getReg());2967    else2968      GEPInfo.VgprParts.push_back(GEPOp.getReg());2969  }2970 2971  AddrInfo.push_back(GEPInfo);2972  getAddrModeInfo(*PtrMI, MRI, AddrInfo);2973}2974 2975bool AMDGPUInstructionSelector::isSGPR(Register Reg) const {2976  return RBI.getRegBank(Reg, *MRI, TRI)->getID() == AMDGPU::SGPRRegBankID;2977}2978 2979bool AMDGPUInstructionSelector::isInstrUniform(const MachineInstr &MI) const {2980  if (!MI.hasOneMemOperand())2981    return false;2982 2983  const MachineMemOperand *MMO = *MI.memoperands_begin();2984  const Value *Ptr = MMO->getValue();2985 2986  // UndefValue means this is a load of a kernel input.  These are uniform.2987  // Sometimes LDS instructions have constant pointers.2988  // If Ptr is null, then that means this mem operand contains a2989  // PseudoSourceValue like GOT.2990  if (!Ptr || isa<UndefValue, Argument, Constant, GlobalValue>(Ptr))2991    return true;2992 2993  if (MMO->getAddrSpace() == AMDGPUAS::CONSTANT_ADDRESS_32BIT)2994    return true;2995 2996  if (MI.getOpcode() == AMDGPU::G_PREFETCH)2997    return RBI.getRegBank(MI.getOperand(0).getReg(), *MRI, TRI)->getID() ==2998           AMDGPU::SGPRRegBankID;2999 3000  const Instruction *I = dyn_cast<Instruction>(Ptr);3001  return I && I->getMetadata("amdgpu.uniform");3002}3003 3004bool AMDGPUInstructionSelector::hasVgprParts(ArrayRef<GEPInfo> AddrInfo) const {3005  for (const GEPInfo &GEPInfo : AddrInfo) {3006    if (!GEPInfo.VgprParts.empty())3007      return true;3008  }3009  return false;3010}3011 3012void AMDGPUInstructionSelector::initM0(MachineInstr &I) const {3013  const LLT PtrTy = MRI->getType(I.getOperand(1).getReg());3014  unsigned AS = PtrTy.getAddressSpace();3015  if ((AS == AMDGPUAS::LOCAL_ADDRESS || AS == AMDGPUAS::REGION_ADDRESS) &&3016      STI.ldsRequiresM0Init()) {3017    MachineBasicBlock *BB = I.getParent();3018 3019    // If DS instructions require M0 initialization, insert it before selecting.3020    BuildMI(*BB, &I, I.getDebugLoc(), TII.get(AMDGPU::S_MOV_B32), AMDGPU::M0)3021      .addImm(-1);3022  }3023}3024 3025bool AMDGPUInstructionSelector::selectG_LOAD_STORE_ATOMICRMW(3026  MachineInstr &I) const {3027  initM0(I);3028  return selectImpl(I, *CoverageInfo);3029}3030 3031static bool isVCmpResult(Register Reg, MachineRegisterInfo &MRI) {3032  if (Reg.isPhysical())3033    return false;3034 3035  MachineInstr &MI = *MRI.getUniqueVRegDef(Reg);3036  const unsigned Opcode = MI.getOpcode();3037 3038  if (Opcode == AMDGPU::COPY)3039    return isVCmpResult(MI.getOperand(1).getReg(), MRI);3040 3041  if (Opcode == AMDGPU::G_AND || Opcode == AMDGPU::G_OR ||3042      Opcode == AMDGPU::G_XOR)3043    return isVCmpResult(MI.getOperand(1).getReg(), MRI) &&3044           isVCmpResult(MI.getOperand(2).getReg(), MRI);3045 3046  if (auto *GI = dyn_cast<GIntrinsic>(&MI))3047    return GI->is(Intrinsic::amdgcn_class);3048 3049  return Opcode == AMDGPU::G_ICMP || Opcode == AMDGPU::G_FCMP;3050}3051 3052bool AMDGPUInstructionSelector::selectG_BRCOND(MachineInstr &I) const {3053  MachineBasicBlock *BB = I.getParent();3054  MachineOperand &CondOp = I.getOperand(0);3055  Register CondReg = CondOp.getReg();3056  const DebugLoc &DL = I.getDebugLoc();3057 3058  unsigned BrOpcode;3059  Register CondPhysReg;3060  const TargetRegisterClass *ConstrainRC;3061 3062  // In SelectionDAG, we inspect the IR block for uniformity metadata to decide3063  // whether the branch is uniform when selecting the instruction. In3064  // GlobalISel, we should push that decision into RegBankSelect. Assume for now3065  // RegBankSelect knows what it's doing if the branch condition is scc, even3066  // though it currently does not.3067  if (!isVCC(CondReg, *MRI)) {3068    if (MRI->getType(CondReg) != LLT::scalar(32))3069      return false;3070 3071    CondPhysReg = AMDGPU::SCC;3072    BrOpcode = AMDGPU::S_CBRANCH_SCC1;3073    ConstrainRC = &AMDGPU::SReg_32RegClass;3074  } else {3075    // FIXME: Should scc->vcc copies and with exec?3076 3077    // Unless the value of CondReg is a result of a V_CMP* instruction then we3078    // need to insert an and with exec.3079    if (!isVCmpResult(CondReg, *MRI)) {3080      const bool Is64 = STI.isWave64();3081      const unsigned Opcode = Is64 ? AMDGPU::S_AND_B64 : AMDGPU::S_AND_B32;3082      const Register Exec = Is64 ? AMDGPU::EXEC : AMDGPU::EXEC_LO;3083 3084      Register TmpReg = MRI->createVirtualRegister(TRI.getBoolRC());3085      BuildMI(*BB, &I, DL, TII.get(Opcode), TmpReg)3086          .addReg(CondReg)3087          .addReg(Exec)3088          .setOperandDead(3); // Dead scc3089      CondReg = TmpReg;3090    }3091 3092    CondPhysReg = TRI.getVCC();3093    BrOpcode = AMDGPU::S_CBRANCH_VCCNZ;3094    ConstrainRC = TRI.getBoolRC();3095  }3096 3097  if (!MRI->getRegClassOrNull(CondReg))3098    MRI->setRegClass(CondReg, ConstrainRC);3099 3100  BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), CondPhysReg)3101    .addReg(CondReg);3102  BuildMI(*BB, &I, DL, TII.get(BrOpcode))3103    .addMBB(I.getOperand(1).getMBB());3104 3105  I.eraseFromParent();3106  return true;3107}3108 3109bool AMDGPUInstructionSelector::selectG_GLOBAL_VALUE(3110  MachineInstr &I) const {3111  Register DstReg = I.getOperand(0).getReg();3112  const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);3113  const bool IsVGPR = DstRB->getID() == AMDGPU::VGPRRegBankID;3114  I.setDesc(TII.get(IsVGPR ? AMDGPU::V_MOV_B32_e32 : AMDGPU::S_MOV_B32));3115  if (IsVGPR)3116    I.addOperand(*MF, MachineOperand::CreateReg(AMDGPU::EXEC, false, true));3117 3118  return RBI.constrainGenericRegister(3119    DstReg, IsVGPR ? AMDGPU::VGPR_32RegClass : AMDGPU::SReg_32RegClass, *MRI);3120}3121 3122bool AMDGPUInstructionSelector::selectG_PTRMASK(MachineInstr &I) const {3123  Register DstReg = I.getOperand(0).getReg();3124  Register SrcReg = I.getOperand(1).getReg();3125  Register MaskReg = I.getOperand(2).getReg();3126  LLT Ty = MRI->getType(DstReg);3127  LLT MaskTy = MRI->getType(MaskReg);3128  MachineBasicBlock *BB = I.getParent();3129  const DebugLoc &DL = I.getDebugLoc();3130 3131  const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);3132  const RegisterBank *SrcRB = RBI.getRegBank(SrcReg, *MRI, TRI);3133  const RegisterBank *MaskRB = RBI.getRegBank(MaskReg, *MRI, TRI);3134  const bool IsVGPR = DstRB->getID() == AMDGPU::VGPRRegBankID;3135  if (DstRB != SrcRB) // Should only happen for hand written MIR.3136    return false;3137 3138  // Try to avoid emitting a bit operation when we only need to touch half of3139  // the 64-bit pointer.3140  APInt MaskOnes = VT->getKnownOnes(MaskReg).zext(64);3141  const APInt MaskHi32 = APInt::getHighBitsSet(64, 32);3142  const APInt MaskLo32 = APInt::getLowBitsSet(64, 32);3143 3144  const bool CanCopyLow32 = (MaskOnes & MaskLo32) == MaskLo32;3145  const bool CanCopyHi32 = (MaskOnes & MaskHi32) == MaskHi32;3146 3147  if (!IsVGPR && Ty.getSizeInBits() == 64 &&3148      !CanCopyLow32 && !CanCopyHi32) {3149    auto MIB = BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_AND_B64), DstReg)3150      .addReg(SrcReg)3151      .addReg(MaskReg)3152      .setOperandDead(3); // Dead scc3153    I.eraseFromParent();3154    return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);3155  }3156 3157  unsigned NewOpc = IsVGPR ? AMDGPU::V_AND_B32_e64 : AMDGPU::S_AND_B32;3158  const TargetRegisterClass &RegRC3159    = IsVGPR ? AMDGPU::VGPR_32RegClass : AMDGPU::SReg_32RegClass;3160 3161  const TargetRegisterClass *DstRC = TRI.getRegClassForTypeOnBank(Ty, *DstRB);3162  const TargetRegisterClass *SrcRC = TRI.getRegClassForTypeOnBank(Ty, *SrcRB);3163  const TargetRegisterClass *MaskRC =3164      TRI.getRegClassForTypeOnBank(MaskTy, *MaskRB);3165 3166  if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI) ||3167      !RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI) ||3168      !RBI.constrainGenericRegister(MaskReg, *MaskRC, *MRI))3169    return false;3170 3171  if (Ty.getSizeInBits() == 32) {3172    assert(MaskTy.getSizeInBits() == 32 &&3173           "ptrmask should have been narrowed during legalize");3174 3175    auto NewOp = BuildMI(*BB, &I, DL, TII.get(NewOpc), DstReg)3176      .addReg(SrcReg)3177      .addReg(MaskReg);3178 3179    if (!IsVGPR)3180      NewOp.setOperandDead(3); // Dead scc3181    I.eraseFromParent();3182    return true;3183  }3184 3185  Register HiReg = MRI->createVirtualRegister(&RegRC);3186  Register LoReg = MRI->createVirtualRegister(&RegRC);3187 3188  // Extract the subregisters from the source pointer.3189  BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), LoReg)3190    .addReg(SrcReg, 0, AMDGPU::sub0);3191  BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), HiReg)3192    .addReg(SrcReg, 0, AMDGPU::sub1);3193 3194  Register MaskedLo, MaskedHi;3195 3196  if (CanCopyLow32) {3197    // If all the bits in the low half are 1, we only need a copy for it.3198    MaskedLo = LoReg;3199  } else {3200    // Extract the mask subregister and apply the and.3201    Register MaskLo = MRI->createVirtualRegister(&RegRC);3202    MaskedLo = MRI->createVirtualRegister(&RegRC);3203 3204    BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), MaskLo)3205      .addReg(MaskReg, 0, AMDGPU::sub0);3206    BuildMI(*BB, &I, DL, TII.get(NewOpc), MaskedLo)3207      .addReg(LoReg)3208      .addReg(MaskLo);3209  }3210 3211  if (CanCopyHi32) {3212    // If all the bits in the high half are 1, we only need a copy for it.3213    MaskedHi = HiReg;3214  } else {3215    Register MaskHi = MRI->createVirtualRegister(&RegRC);3216    MaskedHi = MRI->createVirtualRegister(&RegRC);3217 3218    BuildMI(*BB, &I, DL, TII.get(AMDGPU::COPY), MaskHi)3219      .addReg(MaskReg, 0, AMDGPU::sub1);3220    BuildMI(*BB, &I, DL, TII.get(NewOpc), MaskedHi)3221      .addReg(HiReg)3222      .addReg(MaskHi);3223  }3224 3225  BuildMI(*BB, &I, DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)3226    .addReg(MaskedLo)3227    .addImm(AMDGPU::sub0)3228    .addReg(MaskedHi)3229    .addImm(AMDGPU::sub1);3230  I.eraseFromParent();3231  return true;3232}3233 3234/// Return the register to use for the index value, and the subregister to use3235/// for the indirectly accessed register.3236static std::pair<Register, unsigned>3237computeIndirectRegIndex(MachineRegisterInfo &MRI, const SIRegisterInfo &TRI,3238                        const TargetRegisterClass *SuperRC, Register IdxReg,3239                        unsigned EltSize, GISelValueTracking &ValueTracking) {3240  Register IdxBaseReg;3241  int Offset;3242 3243  std::tie(IdxBaseReg, Offset) =3244      AMDGPU::getBaseWithConstantOffset(MRI, IdxReg, &ValueTracking);3245  if (IdxBaseReg == AMDGPU::NoRegister) {3246    // This will happen if the index is a known constant. This should ordinarily3247    // be legalized out, but handle it as a register just in case.3248    assert(Offset == 0);3249    IdxBaseReg = IdxReg;3250  }3251 3252  ArrayRef<int16_t> SubRegs = TRI.getRegSplitParts(SuperRC, EltSize);3253 3254  // Skip out of bounds offsets, or else we would end up using an undefined3255  // register.3256  if (static_cast<unsigned>(Offset) >= SubRegs.size())3257    return std::pair(IdxReg, SubRegs[0]);3258  return std::pair(IdxBaseReg, SubRegs[Offset]);3259}3260 3261bool AMDGPUInstructionSelector::selectG_EXTRACT_VECTOR_ELT(3262  MachineInstr &MI) const {3263  Register DstReg = MI.getOperand(0).getReg();3264  Register SrcReg = MI.getOperand(1).getReg();3265  Register IdxReg = MI.getOperand(2).getReg();3266 3267  LLT DstTy = MRI->getType(DstReg);3268  LLT SrcTy = MRI->getType(SrcReg);3269 3270  const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);3271  const RegisterBank *SrcRB = RBI.getRegBank(SrcReg, *MRI, TRI);3272  const RegisterBank *IdxRB = RBI.getRegBank(IdxReg, *MRI, TRI);3273 3274  // The index must be scalar. If it wasn't RegBankSelect should have moved this3275  // into a waterfall loop.3276  if (IdxRB->getID() != AMDGPU::SGPRRegBankID)3277    return false;3278 3279  const TargetRegisterClass *SrcRC =3280      TRI.getRegClassForTypeOnBank(SrcTy, *SrcRB);3281  const TargetRegisterClass *DstRC =3282      TRI.getRegClassForTypeOnBank(DstTy, *DstRB);3283  if (!SrcRC || !DstRC)3284    return false;3285  if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI) ||3286      !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI) ||3287      !RBI.constrainGenericRegister(IdxReg, AMDGPU::SReg_32RegClass, *MRI))3288    return false;3289 3290  MachineBasicBlock *BB = MI.getParent();3291  const DebugLoc &DL = MI.getDebugLoc();3292  const bool Is64 = DstTy.getSizeInBits() == 64;3293 3294  unsigned SubReg;3295  std::tie(IdxReg, SubReg) = computeIndirectRegIndex(3296      *MRI, TRI, SrcRC, IdxReg, DstTy.getSizeInBits() / 8, *VT);3297 3298  if (SrcRB->getID() == AMDGPU::SGPRRegBankID) {3299    if (DstTy.getSizeInBits() != 32 && !Is64)3300      return false;3301 3302    BuildMI(*BB, &MI, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)3303      .addReg(IdxReg);3304 3305    unsigned Opc = Is64 ? AMDGPU::S_MOVRELS_B64 : AMDGPU::S_MOVRELS_B32;3306    BuildMI(*BB, &MI, DL, TII.get(Opc), DstReg)3307      .addReg(SrcReg, 0, SubReg)3308      .addReg(SrcReg, RegState::Implicit);3309    MI.eraseFromParent();3310    return true;3311  }3312 3313  if (SrcRB->getID() != AMDGPU::VGPRRegBankID || DstTy.getSizeInBits() != 32)3314    return false;3315 3316  if (!STI.useVGPRIndexMode()) {3317    BuildMI(*BB, &MI, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)3318      .addReg(IdxReg);3319    BuildMI(*BB, &MI, DL, TII.get(AMDGPU::V_MOVRELS_B32_e32), DstReg)3320      .addReg(SrcReg, 0, SubReg)3321      .addReg(SrcReg, RegState::Implicit);3322    MI.eraseFromParent();3323    return true;3324  }3325 3326  const MCInstrDesc &GPRIDXDesc =3327      TII.getIndirectGPRIDXPseudo(TRI.getRegSizeInBits(*SrcRC), true);3328  BuildMI(*BB, MI, DL, GPRIDXDesc, DstReg)3329      .addReg(SrcReg)3330      .addReg(IdxReg)3331      .addImm(SubReg);3332 3333  MI.eraseFromParent();3334  return true;3335}3336 3337// TODO: Fold insert_vector_elt (extract_vector_elt) into movrelsd3338bool AMDGPUInstructionSelector::selectG_INSERT_VECTOR_ELT(3339  MachineInstr &MI) const {3340  Register DstReg = MI.getOperand(0).getReg();3341  Register VecReg = MI.getOperand(1).getReg();3342  Register ValReg = MI.getOperand(2).getReg();3343  Register IdxReg = MI.getOperand(3).getReg();3344 3345  LLT VecTy = MRI->getType(DstReg);3346  LLT ValTy = MRI->getType(ValReg);3347  unsigned VecSize = VecTy.getSizeInBits();3348  unsigned ValSize = ValTy.getSizeInBits();3349 3350  const RegisterBank *VecRB = RBI.getRegBank(VecReg, *MRI, TRI);3351  const RegisterBank *ValRB = RBI.getRegBank(ValReg, *MRI, TRI);3352  const RegisterBank *IdxRB = RBI.getRegBank(IdxReg, *MRI, TRI);3353 3354  assert(VecTy.getElementType() == ValTy);3355 3356  // The index must be scalar. If it wasn't RegBankSelect should have moved this3357  // into a waterfall loop.3358  if (IdxRB->getID() != AMDGPU::SGPRRegBankID)3359    return false;3360 3361  const TargetRegisterClass *VecRC =3362      TRI.getRegClassForTypeOnBank(VecTy, *VecRB);3363  const TargetRegisterClass *ValRC =3364      TRI.getRegClassForTypeOnBank(ValTy, *ValRB);3365 3366  if (!RBI.constrainGenericRegister(VecReg, *VecRC, *MRI) ||3367      !RBI.constrainGenericRegister(DstReg, *VecRC, *MRI) ||3368      !RBI.constrainGenericRegister(ValReg, *ValRC, *MRI) ||3369      !RBI.constrainGenericRegister(IdxReg, AMDGPU::SReg_32RegClass, *MRI))3370    return false;3371 3372  if (VecRB->getID() == AMDGPU::VGPRRegBankID && ValSize != 32)3373    return false;3374 3375  unsigned SubReg;3376  std::tie(IdxReg, SubReg) =3377      computeIndirectRegIndex(*MRI, TRI, VecRC, IdxReg, ValSize / 8, *VT);3378 3379  const bool IndexMode = VecRB->getID() == AMDGPU::VGPRRegBankID &&3380                         STI.useVGPRIndexMode();3381 3382  MachineBasicBlock *BB = MI.getParent();3383  const DebugLoc &DL = MI.getDebugLoc();3384 3385  if (!IndexMode) {3386    BuildMI(*BB, &MI, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)3387      .addReg(IdxReg);3388 3389    const MCInstrDesc &RegWriteOp = TII.getIndirectRegWriteMovRelPseudo(3390        VecSize, ValSize, VecRB->getID() == AMDGPU::SGPRRegBankID);3391    BuildMI(*BB, MI, DL, RegWriteOp, DstReg)3392        .addReg(VecReg)3393        .addReg(ValReg)3394        .addImm(SubReg);3395    MI.eraseFromParent();3396    return true;3397  }3398 3399  const MCInstrDesc &GPRIDXDesc =3400      TII.getIndirectGPRIDXPseudo(TRI.getRegSizeInBits(*VecRC), false);3401  BuildMI(*BB, MI, DL, GPRIDXDesc, DstReg)3402      .addReg(VecReg)3403      .addReg(ValReg)3404      .addReg(IdxReg)3405      .addImm(SubReg);3406 3407  MI.eraseFromParent();3408  return true;3409}3410 3411bool AMDGPUInstructionSelector::selectBufferLoadLds(MachineInstr &MI) const {3412  if (!Subtarget->hasVMemToLDSLoad())3413    return false;3414  unsigned Opc;3415  unsigned Size = MI.getOperand(3).getImm();3416 3417  // The struct intrinsic variants add one additional operand over raw.3418  const bool HasVIndex = MI.getNumOperands() == 9;3419  Register VIndex;3420  int OpOffset = 0;3421  if (HasVIndex) {3422    VIndex = MI.getOperand(4).getReg();3423    OpOffset = 1;3424  }3425 3426  Register VOffset = MI.getOperand(4 + OpOffset).getReg();3427  std::optional<ValueAndVReg> MaybeVOffset =3428      getIConstantVRegValWithLookThrough(VOffset, *MRI);3429  const bool HasVOffset = !MaybeVOffset || MaybeVOffset->Value.getZExtValue();3430 3431  switch (Size) {3432  default:3433    return false;3434  case 1:3435    Opc = HasVIndex ? HasVOffset ? AMDGPU::BUFFER_LOAD_UBYTE_LDS_BOTHEN3436                                 : AMDGPU::BUFFER_LOAD_UBYTE_LDS_IDXEN3437                    : HasVOffset ? AMDGPU::BUFFER_LOAD_UBYTE_LDS_OFFEN3438                                 : AMDGPU::BUFFER_LOAD_UBYTE_LDS_OFFSET;3439    break;3440  case 2:3441    Opc = HasVIndex ? HasVOffset ? AMDGPU::BUFFER_LOAD_USHORT_LDS_BOTHEN3442                                 : AMDGPU::BUFFER_LOAD_USHORT_LDS_IDXEN3443                    : HasVOffset ? AMDGPU::BUFFER_LOAD_USHORT_LDS_OFFEN3444                                 : AMDGPU::BUFFER_LOAD_USHORT_LDS_OFFSET;3445    break;3446  case 4:3447    Opc = HasVIndex ? HasVOffset ? AMDGPU::BUFFER_LOAD_DWORD_LDS_BOTHEN3448                                 : AMDGPU::BUFFER_LOAD_DWORD_LDS_IDXEN3449                    : HasVOffset ? AMDGPU::BUFFER_LOAD_DWORD_LDS_OFFEN3450                                 : AMDGPU::BUFFER_LOAD_DWORD_LDS_OFFSET;3451    break;3452  case 12:3453    if (!Subtarget->hasLDSLoadB96_B128())3454      return false;3455 3456    Opc = HasVIndex ? HasVOffset ? AMDGPU::BUFFER_LOAD_DWORDX3_LDS_BOTHEN3457                                 : AMDGPU::BUFFER_LOAD_DWORDX3_LDS_IDXEN3458                    : HasVOffset ? AMDGPU::BUFFER_LOAD_DWORDX3_LDS_OFFEN3459                                 : AMDGPU::BUFFER_LOAD_DWORDX3_LDS_OFFSET;3460    break;3461  case 16:3462    if (!Subtarget->hasLDSLoadB96_B128())3463      return false;3464 3465    Opc = HasVIndex ? HasVOffset ? AMDGPU::BUFFER_LOAD_DWORDX4_LDS_BOTHEN3466                                 : AMDGPU::BUFFER_LOAD_DWORDX4_LDS_IDXEN3467                    : HasVOffset ? AMDGPU::BUFFER_LOAD_DWORDX4_LDS_OFFEN3468                                 : AMDGPU::BUFFER_LOAD_DWORDX4_LDS_OFFSET;3469    break;3470  }3471 3472  MachineBasicBlock *MBB = MI.getParent();3473  const DebugLoc &DL = MI.getDebugLoc();3474  BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)3475    .add(MI.getOperand(2));3476 3477  auto MIB = BuildMI(*MBB, &MI, DL, TII.get(Opc));3478 3479  if (HasVIndex && HasVOffset) {3480    Register IdxReg = MRI->createVirtualRegister(TRI.getVGPR64Class());3481    BuildMI(*MBB, &*MIB, DL, TII.get(AMDGPU::REG_SEQUENCE), IdxReg)3482      .addReg(VIndex)3483      .addImm(AMDGPU::sub0)3484      .addReg(VOffset)3485      .addImm(AMDGPU::sub1);3486 3487    MIB.addReg(IdxReg);3488  } else if (HasVIndex) {3489    MIB.addReg(VIndex);3490  } else if (HasVOffset) {3491    MIB.addReg(VOffset);3492  }3493 3494  MIB.add(MI.getOperand(1));            // rsrc3495  MIB.add(MI.getOperand(5 + OpOffset)); // soffset3496  MIB.add(MI.getOperand(6 + OpOffset)); // imm offset3497  bool IsGFX12Plus = AMDGPU::isGFX12Plus(STI);3498  unsigned Aux = MI.getOperand(7 + OpOffset).getImm();3499  MIB.addImm(Aux & (IsGFX12Plus ? AMDGPU::CPol::ALL3500                                : AMDGPU::CPol::ALL_pregfx12)); // cpol3501  MIB.addImm(3502      Aux & (IsGFX12Plus ? AMDGPU::CPol::SWZ : AMDGPU::CPol::SWZ_pregfx12)3503          ? 13504          : 0); // swz3505 3506  MachineMemOperand *LoadMMO = *MI.memoperands_begin();3507  // Don't set the offset value here because the pointer points to the base of3508  // the buffer.3509  MachinePointerInfo LoadPtrI = LoadMMO->getPointerInfo();3510 3511  MachinePointerInfo StorePtrI = LoadPtrI;3512  LoadPtrI.V = PoisonValue::get(PointerType::get(MF->getFunction().getContext(),3513                                                 AMDGPUAS::BUFFER_RESOURCE));3514  LoadPtrI.AddrSpace = AMDGPUAS::BUFFER_RESOURCE;3515  StorePtrI.AddrSpace = AMDGPUAS::LOCAL_ADDRESS;3516 3517  auto F = LoadMMO->getFlags() &3518           ~(MachineMemOperand::MOStore | MachineMemOperand::MOLoad);3519  LoadMMO = MF->getMachineMemOperand(LoadPtrI, F | MachineMemOperand::MOLoad,3520                                     Size, LoadMMO->getBaseAlign());3521 3522  MachineMemOperand *StoreMMO =3523      MF->getMachineMemOperand(StorePtrI, F | MachineMemOperand::MOStore,3524                               sizeof(int32_t), LoadMMO->getBaseAlign());3525 3526  MIB.setMemRefs({LoadMMO, StoreMMO});3527 3528  MI.eraseFromParent();3529  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);3530}3531 3532/// Match a zero extend from a 32-bit value to 64-bits.3533Register AMDGPUInstructionSelector::matchZeroExtendFromS32(Register Reg) const {3534  Register ZExtSrc;3535  if (mi_match(Reg, *MRI, m_GZExt(m_Reg(ZExtSrc))))3536    return MRI->getType(ZExtSrc) == LLT::scalar(32) ? ZExtSrc : Register();3537 3538  // Match legalized form %zext = G_MERGE_VALUES (s32 %x), (s32 0)3539  const MachineInstr *Def = getDefIgnoringCopies(Reg, *MRI);3540  if (Def->getOpcode() != AMDGPU::G_MERGE_VALUES)3541    return Register();3542 3543  assert(Def->getNumOperands() == 3 &&3544         MRI->getType(Def->getOperand(0).getReg()) == LLT::scalar(64));3545  if (mi_match(Def->getOperand(2).getReg(), *MRI, m_ZeroInt())) {3546    return Def->getOperand(1).getReg();3547  }3548 3549  return Register();3550}3551 3552/// Match a sign extend from a 32-bit value to 64-bits.3553Register AMDGPUInstructionSelector::matchSignExtendFromS32(Register Reg) const {3554  Register SExtSrc;3555  if (mi_match(Reg, *MRI, m_GSExt(m_Reg(SExtSrc))))3556    return MRI->getType(SExtSrc) == LLT::scalar(32) ? SExtSrc : Register();3557 3558  // Match legalized form %sext = G_MERGE_VALUES (s32 %x), G_ASHR((S32 %x, 31))3559  const MachineInstr *Def = getDefIgnoringCopies(Reg, *MRI);3560  if (Def->getOpcode() != AMDGPU::G_MERGE_VALUES)3561    return Register();3562 3563  assert(Def->getNumOperands() == 3 &&3564         MRI->getType(Def->getOperand(0).getReg()) == LLT::scalar(64));3565  if (mi_match(Def->getOperand(2).getReg(), *MRI,3566               m_GAShr(m_SpecificReg(Def->getOperand(1).getReg()),3567                       m_SpecificICst(31))))3568    return Def->getOperand(1).getReg();3569 3570  if (VT->signBitIsZero(Reg))3571    return matchZeroExtendFromS32(Reg);3572 3573  return Register();3574}3575 3576/// Match a zero extend from a 32-bit value to 64-bits, or \p Reg itself if it3577/// is 32-bit.3578Register3579AMDGPUInstructionSelector::matchZeroExtendFromS32OrS32(Register Reg) const {3580  return MRI->getType(Reg) == LLT::scalar(32) ? Reg3581                                              : matchZeroExtendFromS32(Reg);3582}3583 3584/// Match a sign extend from a 32-bit value to 64-bits, or \p Reg itself if it3585/// is 32-bit.3586Register3587AMDGPUInstructionSelector::matchSignExtendFromS32OrS32(Register Reg) const {3588  return MRI->getType(Reg) == LLT::scalar(32) ? Reg3589                                              : matchSignExtendFromS32(Reg);3590}3591 3592Register3593AMDGPUInstructionSelector::matchExtendFromS32OrS32(Register Reg,3594                                                   bool IsSigned) const {3595  if (IsSigned)3596    return matchSignExtendFromS32OrS32(Reg);3597 3598  return matchZeroExtendFromS32OrS32(Reg);3599}3600 3601Register AMDGPUInstructionSelector::matchAnyExtendFromS32(Register Reg) const {3602  Register AnyExtSrc;3603  if (mi_match(Reg, *MRI, m_GAnyExt(m_Reg(AnyExtSrc))))3604    return MRI->getType(AnyExtSrc) == LLT::scalar(32) ? AnyExtSrc : Register();3605 3606  // Match legalized form %zext = G_MERGE_VALUES (s32 %x), (s32 G_IMPLICIT_DEF)3607  const MachineInstr *Def = getDefIgnoringCopies(Reg, *MRI);3608  if (Def->getOpcode() != AMDGPU::G_MERGE_VALUES)3609    return Register();3610 3611  assert(Def->getNumOperands() == 3 &&3612         MRI->getType(Def->getOperand(0).getReg()) == LLT::scalar(64));3613 3614  if (mi_match(Def->getOperand(2).getReg(), *MRI, m_GImplicitDef()))3615    return Def->getOperand(1).getReg();3616 3617  return Register();3618}3619 3620bool AMDGPUInstructionSelector::selectGlobalLoadLds(MachineInstr &MI) const{3621  if (!Subtarget->hasVMemToLDSLoad())3622    return false;3623 3624  unsigned Opc;3625  unsigned Size = MI.getOperand(3).getImm();3626 3627  switch (Size) {3628  default:3629    return false;3630  case 1:3631    Opc = AMDGPU::GLOBAL_LOAD_LDS_UBYTE;3632    break;3633  case 2:3634    Opc = AMDGPU::GLOBAL_LOAD_LDS_USHORT;3635    break;3636  case 4:3637    Opc = AMDGPU::GLOBAL_LOAD_LDS_DWORD;3638    break;3639  case 12:3640    if (!Subtarget->hasLDSLoadB96_B128())3641      return false;3642    Opc = AMDGPU::GLOBAL_LOAD_LDS_DWORDX3;3643    break;3644  case 16:3645    if (!Subtarget->hasLDSLoadB96_B128())3646      return false;3647    Opc = AMDGPU::GLOBAL_LOAD_LDS_DWORDX4;3648    break;3649  }3650 3651  MachineBasicBlock *MBB = MI.getParent();3652  const DebugLoc &DL = MI.getDebugLoc();3653  BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)3654    .add(MI.getOperand(2));3655 3656  Register Addr = MI.getOperand(1).getReg();3657  Register VOffset;3658  // Try to split SAddr and VOffset. Global and LDS pointers share the same3659  // immediate offset, so we cannot use a regular SelectGlobalSAddr().3660  if (!isSGPR(Addr)) {3661    auto AddrDef = getDefSrcRegIgnoringCopies(Addr, *MRI);3662    if (isSGPR(AddrDef->Reg)) {3663      Addr = AddrDef->Reg;3664    } else if (AddrDef->MI->getOpcode() == AMDGPU::G_PTR_ADD) {3665      Register SAddr =3666          getSrcRegIgnoringCopies(AddrDef->MI->getOperand(1).getReg(), *MRI);3667      if (isSGPR(SAddr)) {3668        Register PtrBaseOffset = AddrDef->MI->getOperand(2).getReg();3669        if (Register Off = matchZeroExtendFromS32(PtrBaseOffset)) {3670          Addr = SAddr;3671          VOffset = Off;3672        }3673      }3674    }3675  }3676 3677  if (isSGPR(Addr)) {3678    Opc = AMDGPU::getGlobalSaddrOp(Opc);3679    if (!VOffset) {3680      VOffset = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);3681      BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::V_MOV_B32_e32), VOffset)3682        .addImm(0);3683    }3684  }3685 3686  auto MIB = BuildMI(*MBB, &MI, DL, TII.get(Opc))3687    .addReg(Addr);3688 3689  if (isSGPR(Addr))3690    MIB.addReg(VOffset);3691 3692  MIB.add(MI.getOperand(4)); // offset3693 3694  unsigned Aux = MI.getOperand(5).getImm();3695  MIB.addImm(Aux & ~AMDGPU::CPol::VIRTUAL_BITS); // cpol3696 3697  MachineMemOperand *LoadMMO = *MI.memoperands_begin();3698  MachinePointerInfo LoadPtrI = LoadMMO->getPointerInfo();3699  LoadPtrI.Offset = MI.getOperand(4).getImm();3700  MachinePointerInfo StorePtrI = LoadPtrI;3701  LoadPtrI.V = PoisonValue::get(PointerType::get(MF->getFunction().getContext(),3702                                                 AMDGPUAS::GLOBAL_ADDRESS));3703  LoadPtrI.AddrSpace = AMDGPUAS::GLOBAL_ADDRESS;3704  StorePtrI.AddrSpace = AMDGPUAS::LOCAL_ADDRESS;3705  auto F = LoadMMO->getFlags() &3706           ~(MachineMemOperand::MOStore | MachineMemOperand::MOLoad);3707  LoadMMO = MF->getMachineMemOperand(LoadPtrI, F | MachineMemOperand::MOLoad,3708                                     Size, LoadMMO->getBaseAlign());3709  MachineMemOperand *StoreMMO =3710      MF->getMachineMemOperand(StorePtrI, F | MachineMemOperand::MOStore,3711                               sizeof(int32_t), Align(4));3712 3713  MIB.setMemRefs({LoadMMO, StoreMMO});3714 3715  MI.eraseFromParent();3716  return constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);3717}3718 3719bool AMDGPUInstructionSelector::selectBVHIntersectRayIntrinsic(3720    MachineInstr &MI) const {3721  unsigned OpcodeOpIdx =3722      MI.getOpcode() == AMDGPU::G_AMDGPU_BVH_INTERSECT_RAY ? 1 : 3;3723  MI.setDesc(TII.get(MI.getOperand(OpcodeOpIdx).getImm()));3724  MI.removeOperand(OpcodeOpIdx);3725  MI.addImplicitDefUseOperands(*MI.getMF());3726  return constrainSelectedInstRegOperands(MI, TII, TRI, RBI);3727}3728 3729// FIXME: This should be removed and let the patterns select. We just need the3730// AGPR/VGPR combination versions.3731bool AMDGPUInstructionSelector::selectSMFMACIntrin(MachineInstr &MI) const {3732  unsigned Opc;3733  switch (cast<GIntrinsic>(MI).getIntrinsicID()) {3734  case Intrinsic::amdgcn_smfmac_f32_16x16x32_f16:3735    Opc = AMDGPU::V_SMFMAC_F32_16X16X32_F16_e64;3736    break;3737  case Intrinsic::amdgcn_smfmac_f32_32x32x16_f16:3738    Opc = AMDGPU::V_SMFMAC_F32_32X32X16_F16_e64;3739    break;3740  case Intrinsic::amdgcn_smfmac_f32_16x16x32_bf16:3741    Opc = AMDGPU::V_SMFMAC_F32_16X16X32_BF16_e64;3742    break;3743  case Intrinsic::amdgcn_smfmac_f32_32x32x16_bf16:3744    Opc = AMDGPU::V_SMFMAC_F32_32X32X16_BF16_e64;3745    break;3746  case Intrinsic::amdgcn_smfmac_i32_16x16x64_i8:3747    Opc = AMDGPU::V_SMFMAC_I32_16X16X64_I8_e64;3748    break;3749  case Intrinsic::amdgcn_smfmac_i32_32x32x32_i8:3750    Opc = AMDGPU::V_SMFMAC_I32_32X32X32_I8_e64;3751    break;3752  case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf8_bf8:3753    Opc = AMDGPU::V_SMFMAC_F32_16X16X64_BF8_BF8_e64;3754    break;3755  case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf8_fp8:3756    Opc = AMDGPU::V_SMFMAC_F32_16X16X64_BF8_FP8_e64;3757    break;3758  case Intrinsic::amdgcn_smfmac_f32_16x16x64_fp8_bf8:3759    Opc = AMDGPU::V_SMFMAC_F32_16X16X64_FP8_BF8_e64;3760    break;3761  case Intrinsic::amdgcn_smfmac_f32_16x16x64_fp8_fp8:3762    Opc = AMDGPU::V_SMFMAC_F32_16X16X64_FP8_FP8_e64;3763    break;3764  case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf8_bf8:3765    Opc = AMDGPU::V_SMFMAC_F32_32X32X32_BF8_BF8_e64;3766    break;3767  case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf8_fp8:3768    Opc = AMDGPU::V_SMFMAC_F32_32X32X32_BF8_FP8_e64;3769    break;3770  case Intrinsic::amdgcn_smfmac_f32_32x32x32_fp8_bf8:3771    Opc = AMDGPU::V_SMFMAC_F32_32X32X32_FP8_BF8_e64;3772    break;3773  case Intrinsic::amdgcn_smfmac_f32_32x32x32_fp8_fp8:3774    Opc = AMDGPU::V_SMFMAC_F32_32X32X32_FP8_FP8_e64;3775    break;3776  case Intrinsic::amdgcn_smfmac_f32_16x16x64_f16:3777    Opc = AMDGPU::V_SMFMAC_F32_16X16X64_F16_e64;3778    break;3779  case Intrinsic::amdgcn_smfmac_f32_32x32x32_f16:3780    Opc = AMDGPU::V_SMFMAC_F32_32X32X32_F16_e64;3781    break;3782  case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf16:3783    Opc = AMDGPU::V_SMFMAC_F32_16X16X64_BF16_e64;3784    break;3785  case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf16:3786    Opc = AMDGPU::V_SMFMAC_F32_32X32X32_BF16_e64;3787    break;3788  case Intrinsic::amdgcn_smfmac_i32_16x16x128_i8:3789    Opc = AMDGPU::V_SMFMAC_I32_16X16X128_I8_e64;3790    break;3791  case Intrinsic::amdgcn_smfmac_i32_32x32x64_i8:3792    Opc = AMDGPU::V_SMFMAC_I32_32X32X64_I8_e64;3793    break;3794  case Intrinsic::amdgcn_smfmac_f32_16x16x128_bf8_bf8:3795    Opc = AMDGPU::V_SMFMAC_F32_16X16X128_BF8_BF8_e64;3796    break;3797  case Intrinsic::amdgcn_smfmac_f32_16x16x128_bf8_fp8:3798    Opc = AMDGPU::V_SMFMAC_F32_16X16X128_BF8_FP8_e64;3799    break;3800  case Intrinsic::amdgcn_smfmac_f32_16x16x128_fp8_bf8:3801    Opc = AMDGPU::V_SMFMAC_F32_16X16X128_FP8_BF8_e64;3802    break;3803  case Intrinsic::amdgcn_smfmac_f32_16x16x128_fp8_fp8:3804    Opc = AMDGPU::V_SMFMAC_F32_16X16X128_FP8_FP8_e64;3805    break;3806  case Intrinsic::amdgcn_smfmac_f32_32x32x64_bf8_bf8:3807    Opc = AMDGPU::V_SMFMAC_F32_32X32X64_BF8_BF8_e64;3808    break;3809  case Intrinsic::amdgcn_smfmac_f32_32x32x64_bf8_fp8:3810    Opc = AMDGPU::V_SMFMAC_F32_32X32X64_BF8_FP8_e64;3811    break;3812  case Intrinsic::amdgcn_smfmac_f32_32x32x64_fp8_bf8:3813    Opc = AMDGPU::V_SMFMAC_F32_32X32X64_FP8_BF8_e64;3814    break;3815  case Intrinsic::amdgcn_smfmac_f32_32x32x64_fp8_fp8:3816    Opc = AMDGPU::V_SMFMAC_F32_32X32X64_FP8_FP8_e64;3817    break;3818  default:3819    llvm_unreachable("unhandled smfmac intrinsic");3820  }3821 3822  auto VDst_In = MI.getOperand(4);3823 3824  MI.setDesc(TII.get(Opc));3825  MI.removeOperand(4); // VDst_In3826  MI.removeOperand(1); // Intrinsic ID3827  MI.addOperand(VDst_In); // Readd VDst_In to the end3828  MI.addImplicitDefUseOperands(*MI.getMF());3829  const MCInstrDesc &MCID = MI.getDesc();3830  if (MCID.getOperandConstraint(0, MCOI::EARLY_CLOBBER) != -1) {3831    MI.getOperand(0).setIsEarlyClobber(true);3832  }3833  return true;3834}3835 3836bool AMDGPUInstructionSelector::selectPermlaneSwapIntrin(3837    MachineInstr &MI, Intrinsic::ID IntrID) const {3838  if (IntrID == Intrinsic::amdgcn_permlane16_swap &&3839      !Subtarget->hasPermlane16Swap())3840    return false;3841  if (IntrID == Intrinsic::amdgcn_permlane32_swap &&3842      !Subtarget->hasPermlane32Swap())3843    return false;3844 3845  unsigned Opcode = IntrID == Intrinsic::amdgcn_permlane16_swap3846                        ? AMDGPU::V_PERMLANE16_SWAP_B32_e643847                        : AMDGPU::V_PERMLANE32_SWAP_B32_e64;3848 3849  MI.removeOperand(2);3850  MI.setDesc(TII.get(Opcode));3851  MI.addOperand(*MF, MachineOperand::CreateReg(AMDGPU::EXEC, false, true));3852 3853  MachineOperand &FI = MI.getOperand(4);3854  FI.setImm(FI.getImm() ? AMDGPU::DPP::DPP_FI_1 : AMDGPU::DPP::DPP_FI_0);3855 3856  return constrainSelectedInstRegOperands(MI, TII, TRI, RBI);3857}3858 3859bool AMDGPUInstructionSelector::selectWaveAddress(MachineInstr &MI) const {3860  Register DstReg = MI.getOperand(0).getReg();3861  Register SrcReg = MI.getOperand(1).getReg();3862  const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);3863  const bool IsVALU = DstRB->getID() == AMDGPU::VGPRRegBankID;3864  MachineBasicBlock *MBB = MI.getParent();3865  const DebugLoc &DL = MI.getDebugLoc();3866 3867  if (IsVALU) {3868    BuildMI(*MBB, MI, DL, TII.get(AMDGPU::V_LSHRREV_B32_e64), DstReg)3869      .addImm(Subtarget->getWavefrontSizeLog2())3870      .addReg(SrcReg);3871  } else {3872    BuildMI(*MBB, MI, DL, TII.get(AMDGPU::S_LSHR_B32), DstReg)3873      .addReg(SrcReg)3874      .addImm(Subtarget->getWavefrontSizeLog2())3875      .setOperandDead(3); // Dead scc3876  }3877 3878  const TargetRegisterClass &RC =3879      IsVALU ? AMDGPU::VGPR_32RegClass : AMDGPU::SReg_32RegClass;3880  if (!RBI.constrainGenericRegister(DstReg, RC, *MRI))3881    return false;3882 3883  MI.eraseFromParent();3884  return true;3885}3886 3887// Match BITOP3 operation and return a number of matched instructions plus3888// truth table.3889static std::pair<unsigned, uint8_t> BitOp3_Op(Register R,3890                                              SmallVectorImpl<Register> &Src,3891                                              const MachineRegisterInfo &MRI) {3892  unsigned NumOpcodes = 0;3893  uint8_t LHSBits, RHSBits;3894 3895  auto getOperandBits = [&Src, R, &MRI](Register Op, uint8_t &Bits) -> bool {3896    // Define truth table given Src0, Src1, Src2 bits permutations:3897    //                          0     0     03898    //                          0     0     13899    //                          0     1     03900    //                          0     1     13901    //                          1     0     03902    //                          1     0     13903    //                          1     1     03904    //                          1     1     13905    const uint8_t SrcBits[3] = { 0xf0, 0xcc, 0xaa };3906 3907    if (mi_match(Op, MRI, m_AllOnesInt())) {3908      Bits = 0xff;3909      return true;3910    }3911    if (mi_match(Op, MRI, m_ZeroInt())) {3912      Bits = 0;3913      return true;3914    }3915 3916    for (unsigned I = 0; I < Src.size(); ++I) {3917      // Try to find existing reused operand3918      if (Src[I] == Op) {3919        Bits = SrcBits[I];3920        return true;3921      }3922      // Try to replace parent operator3923      if (Src[I] == R) {3924        Bits = SrcBits[I];3925        Src[I] = Op;3926        return true;3927      }3928    }3929 3930    if (Src.size() == 3) {3931      // No room left for operands. Try one last time, there can be a 'not' of3932      // one of our source operands. In this case we can compute the bits3933      // without growing Src vector.3934      Register LHS;3935      if (mi_match(Op, MRI, m_Not(m_Reg(LHS)))) {3936        LHS = getSrcRegIgnoringCopies(LHS, MRI);3937        for (unsigned I = 0; I < Src.size(); ++I) {3938          if (Src[I] == LHS) {3939            Bits = ~SrcBits[I];3940            return true;3941          }3942        }3943      }3944 3945      return false;3946    }3947 3948    Bits = SrcBits[Src.size()];3949    Src.push_back(Op);3950    return true;3951  };3952 3953  MachineInstr *MI = MRI.getVRegDef(R);3954  switch (MI->getOpcode()) {3955  case TargetOpcode::G_AND:3956  case TargetOpcode::G_OR:3957  case TargetOpcode::G_XOR: {3958    Register LHS = getSrcRegIgnoringCopies(MI->getOperand(1).getReg(), MRI);3959    Register RHS = getSrcRegIgnoringCopies(MI->getOperand(2).getReg(), MRI);3960 3961    SmallVector<Register, 3> Backup(Src.begin(), Src.end());3962    if (!getOperandBits(LHS, LHSBits) ||3963        !getOperandBits(RHS, RHSBits)) {3964      Src = Backup;3965      return std::make_pair(0, 0);3966    }3967 3968    // Recursion is naturally limited by the size of the operand vector.3969    auto Op = BitOp3_Op(LHS, Src, MRI);3970    if (Op.first) {3971      NumOpcodes += Op.first;3972      LHSBits = Op.second;3973    }3974 3975    Op = BitOp3_Op(RHS, Src, MRI);3976    if (Op.first) {3977      NumOpcodes += Op.first;3978      RHSBits = Op.second;3979    }3980    break;3981  }3982  default:3983    return std::make_pair(0, 0);3984  }3985 3986  uint8_t TTbl;3987  switch (MI->getOpcode()) {3988  case TargetOpcode::G_AND:3989    TTbl = LHSBits & RHSBits;3990    break;3991  case TargetOpcode::G_OR:3992    TTbl = LHSBits | RHSBits;3993    break;3994  case TargetOpcode::G_XOR:3995    TTbl = LHSBits ^ RHSBits;3996    break;3997  default:3998    break;3999  }4000 4001  return std::make_pair(NumOpcodes + 1, TTbl);4002}4003 4004bool AMDGPUInstructionSelector::selectBITOP3(MachineInstr &MI) const {4005  if (!Subtarget->hasBitOp3Insts())4006    return false;4007 4008  Register DstReg = MI.getOperand(0).getReg();4009  const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);4010  const bool IsVALU = DstRB->getID() == AMDGPU::VGPRRegBankID;4011  if (!IsVALU)4012    return false;4013 4014  SmallVector<Register, 3> Src;4015  uint8_t TTbl;4016  unsigned NumOpcodes;4017 4018  std::tie(NumOpcodes, TTbl) = BitOp3_Op(DstReg, Src, *MRI);4019 4020  // Src.empty() case can happen if all operands are all zero or all ones.4021  // Normally it shall be optimized out before reaching this.4022  if (NumOpcodes < 2 || Src.empty())4023    return false;4024 4025  const bool IsB32 = MRI->getType(DstReg) == LLT::scalar(32);4026  if (NumOpcodes == 2 && IsB32) {4027    // Avoid using BITOP3 for OR3, XOR3, AND_OR. This is not faster but makes4028    // asm more readable. This cannot be modeled with AddedComplexity because4029    // selector does not know how many operations did we match.4030    if (mi_match(MI, *MRI, m_GXor(m_GXor(m_Reg(), m_Reg()), m_Reg())) ||4031        mi_match(MI, *MRI, m_GOr(m_GOr(m_Reg(), m_Reg()), m_Reg())) ||4032        mi_match(MI, *MRI, m_GOr(m_GAnd(m_Reg(), m_Reg()), m_Reg())))4033      return false;4034  } else if (NumOpcodes < 4) {4035    // For a uniform case threshold should be higher to account for moves4036    // between VGPRs and SGPRs. It needs one operand in a VGPR, rest two can be4037    // in SGPRs and a readtfirstlane after.4038    return false;4039  }4040 4041  unsigned Opc = IsB32 ? AMDGPU::V_BITOP3_B32_e64 : AMDGPU::V_BITOP3_B16_e64;4042  if (!IsB32 && STI.hasTrue16BitInsts())4043    Opc = STI.useRealTrue16Insts() ? AMDGPU::V_BITOP3_B16_gfx1250_t16_e644044                                   : AMDGPU::V_BITOP3_B16_gfx1250_fake16_e64;4045  unsigned CBL = STI.getConstantBusLimit(Opc);4046  MachineBasicBlock *MBB = MI.getParent();4047  const DebugLoc &DL = MI.getDebugLoc();4048 4049  for (unsigned I = 0; I < Src.size(); ++I) {4050    const RegisterBank *RB = RBI.getRegBank(Src[I], *MRI, TRI);4051    if (RB->getID() != AMDGPU::SGPRRegBankID)4052      continue;4053    if (CBL > 0) {4054      --CBL;4055      continue;4056    }4057    Register NewReg =  MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);4058    BuildMI(*MBB, MI, DL, TII.get(AMDGPU::COPY), NewReg)4059        .addReg(Src[I]);4060    Src[I] = NewReg;4061  }4062 4063  // Last operand can be ignored, turning a ternary operation into a binary.4064  // For example: (~a & b & c) | (~a & b & ~c) -> (~a & b). We can replace4065  // 'c' with 'a' here without changing the answer. In some pathological4066  // cases it should be possible to get an operation with a single operand4067  // too if optimizer would not catch it.4068  while (Src.size() < 3)4069    Src.push_back(Src[0]);4070 4071  auto MIB = BuildMI(*MBB, MI, DL, TII.get(Opc), DstReg);4072  if (!IsB32)4073    MIB.addImm(0); // src_mod04074  MIB.addReg(Src[0]);4075  if (!IsB32)4076    MIB.addImm(0); // src_mod14077  MIB.addReg(Src[1]);4078  if (!IsB32)4079    MIB.addImm(0); // src_mod24080  MIB.addReg(Src[2])4081     .addImm(TTbl);4082  if (!IsB32)4083    MIB.addImm(0); // op_sel4084 4085  constrainSelectedInstRegOperands(*MIB, TII, TRI, RBI);4086  MI.eraseFromParent();4087 4088  return true;4089}4090 4091bool AMDGPUInstructionSelector::selectStackRestore(MachineInstr &MI) const {4092  Register SrcReg = MI.getOperand(0).getReg();4093  if (!RBI.constrainGenericRegister(SrcReg, AMDGPU::SReg_32RegClass, *MRI))4094    return false;4095 4096  MachineInstr *DefMI = MRI->getVRegDef(SrcReg);4097  Register SP =4098      Subtarget->getTargetLowering()->getStackPointerRegisterToSaveRestore();4099  Register WaveAddr = getWaveAddress(DefMI);4100  MachineBasicBlock *MBB = MI.getParent();4101  const DebugLoc &DL = MI.getDebugLoc();4102 4103  if (!WaveAddr) {4104    WaveAddr = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);4105    BuildMI(*MBB, MI, DL, TII.get(AMDGPU::S_LSHR_B32), WaveAddr)4106      .addReg(SrcReg)4107      .addImm(Subtarget->getWavefrontSizeLog2())4108      .setOperandDead(3); // Dead scc4109  }4110 4111  BuildMI(*MBB, &MI, DL, TII.get(AMDGPU::COPY), SP)4112    .addReg(WaveAddr);4113 4114  MI.eraseFromParent();4115  return true;4116}4117 4118bool AMDGPUInstructionSelector::select(MachineInstr &I) {4119 4120  if (!I.isPreISelOpcode()) {4121    if (I.isCopy())4122      return selectCOPY(I);4123    return true;4124  }4125 4126  switch (I.getOpcode()) {4127  case TargetOpcode::G_AND:4128  case TargetOpcode::G_OR:4129  case TargetOpcode::G_XOR:4130    if (selectBITOP3(I))4131      return true;4132    if (selectImpl(I, *CoverageInfo))4133      return true;4134    return selectG_AND_OR_XOR(I);4135  case TargetOpcode::G_ADD:4136  case TargetOpcode::G_SUB:4137  case TargetOpcode::G_PTR_ADD:4138    if (selectImpl(I, *CoverageInfo))4139      return true;4140    return selectG_ADD_SUB(I);4141  case TargetOpcode::G_UADDO:4142  case TargetOpcode::G_USUBO:4143  case TargetOpcode::G_UADDE:4144  case TargetOpcode::G_USUBE:4145    return selectG_UADDO_USUBO_UADDE_USUBE(I);4146  case AMDGPU::G_AMDGPU_MAD_U64_U32:4147  case AMDGPU::G_AMDGPU_MAD_I64_I32:4148    return selectG_AMDGPU_MAD_64_32(I);4149  case TargetOpcode::G_INTTOPTR:4150  case TargetOpcode::G_BITCAST:4151  case TargetOpcode::G_PTRTOINT:4152  case TargetOpcode::G_FREEZE:4153    return selectCOPY(I);4154  case TargetOpcode::G_FNEG:4155    if (selectImpl(I, *CoverageInfo))4156      return true;4157    return selectG_FNEG(I);4158  case TargetOpcode::G_FABS:4159    if (selectImpl(I, *CoverageInfo))4160      return true;4161    return selectG_FABS(I);4162  case TargetOpcode::G_EXTRACT:4163    return selectG_EXTRACT(I);4164  case TargetOpcode::G_MERGE_VALUES:4165  case TargetOpcode::G_CONCAT_VECTORS:4166    return selectG_MERGE_VALUES(I);4167  case TargetOpcode::G_UNMERGE_VALUES:4168    return selectG_UNMERGE_VALUES(I);4169  case TargetOpcode::G_BUILD_VECTOR:4170  case TargetOpcode::G_BUILD_VECTOR_TRUNC:4171    return selectG_BUILD_VECTOR(I);4172  case TargetOpcode::G_IMPLICIT_DEF:4173    return selectG_IMPLICIT_DEF(I);4174  case TargetOpcode::G_INSERT:4175    return selectG_INSERT(I);4176  case TargetOpcode::G_INTRINSIC:4177  case TargetOpcode::G_INTRINSIC_CONVERGENT:4178    return selectG_INTRINSIC(I);4179  case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:4180  case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:4181    return selectG_INTRINSIC_W_SIDE_EFFECTS(I);4182  case TargetOpcode::G_ICMP:4183  case TargetOpcode::G_FCMP:4184    if (selectG_ICMP_or_FCMP(I))4185      return true;4186    return selectImpl(I, *CoverageInfo);4187  case TargetOpcode::G_LOAD:4188  case TargetOpcode::G_ZEXTLOAD:4189  case TargetOpcode::G_SEXTLOAD:4190  case TargetOpcode::G_STORE:4191  case TargetOpcode::G_ATOMIC_CMPXCHG:4192  case TargetOpcode::G_ATOMICRMW_XCHG:4193  case TargetOpcode::G_ATOMICRMW_ADD:4194  case TargetOpcode::G_ATOMICRMW_SUB:4195  case TargetOpcode::G_ATOMICRMW_AND:4196  case TargetOpcode::G_ATOMICRMW_OR:4197  case TargetOpcode::G_ATOMICRMW_XOR:4198  case TargetOpcode::G_ATOMICRMW_MIN:4199  case TargetOpcode::G_ATOMICRMW_MAX:4200  case TargetOpcode::G_ATOMICRMW_UMIN:4201  case TargetOpcode::G_ATOMICRMW_UMAX:4202  case TargetOpcode::G_ATOMICRMW_UINC_WRAP:4203  case TargetOpcode::G_ATOMICRMW_UDEC_WRAP:4204  case TargetOpcode::G_ATOMICRMW_FADD:4205  case TargetOpcode::G_ATOMICRMW_FMIN:4206  case TargetOpcode::G_ATOMICRMW_FMAX:4207    return selectG_LOAD_STORE_ATOMICRMW(I);4208  case TargetOpcode::G_SELECT:4209    return selectG_SELECT(I);4210  case TargetOpcode::G_TRUNC:4211    return selectG_TRUNC(I);4212  case TargetOpcode::G_SEXT:4213  case TargetOpcode::G_ZEXT:4214  case TargetOpcode::G_ANYEXT:4215  case TargetOpcode::G_SEXT_INREG:4216    // This is a workaround. For extension from type i1, `selectImpl()` uses4217    // patterns from TD file and generates an illegal VGPR to SGPR COPY as type4218    // i1 can only be hold in a SGPR class.4219    if (MRI->getType(I.getOperand(1).getReg()) != LLT::scalar(1) &&4220        selectImpl(I, *CoverageInfo))4221      return true;4222    return selectG_SZA_EXT(I);4223  case TargetOpcode::G_FPEXT:4224    if (selectG_FPEXT(I))4225      return true;4226    return selectImpl(I, *CoverageInfo);4227  case TargetOpcode::G_BRCOND:4228    return selectG_BRCOND(I);4229  case TargetOpcode::G_GLOBAL_VALUE:4230    return selectG_GLOBAL_VALUE(I);4231  case TargetOpcode::G_PTRMASK:4232    return selectG_PTRMASK(I);4233  case TargetOpcode::G_EXTRACT_VECTOR_ELT:4234    return selectG_EXTRACT_VECTOR_ELT(I);4235  case TargetOpcode::G_INSERT_VECTOR_ELT:4236    return selectG_INSERT_VECTOR_ELT(I);4237  case AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD:4238  case AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD_D16:4239  case AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD_NORET:4240  case AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE:4241  case AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE_D16: {4242    const AMDGPU::ImageDimIntrinsicInfo *Intr =4243        AMDGPU::getImageDimIntrinsicInfo(AMDGPU::getIntrinsicID(I));4244    assert(Intr && "not an image intrinsic with image pseudo");4245    return selectImageIntrinsic(I, Intr);4246  }4247  case AMDGPU::G_AMDGPU_BVH_DUAL_INTERSECT_RAY:4248  case AMDGPU::G_AMDGPU_BVH_INTERSECT_RAY:4249  case AMDGPU::G_AMDGPU_BVH8_INTERSECT_RAY:4250    return selectBVHIntersectRayIntrinsic(I);4251  case AMDGPU::G_SBFX:4252  case AMDGPU::G_UBFX:4253    return selectG_SBFX_UBFX(I);4254  case AMDGPU::G_SI_CALL:4255    I.setDesc(TII.get(AMDGPU::SI_CALL));4256    return true;4257  case AMDGPU::G_AMDGPU_WAVE_ADDRESS:4258    return selectWaveAddress(I);4259  case AMDGPU::G_AMDGPU_WHOLE_WAVE_FUNC_RETURN: {4260    I.setDesc(TII.get(AMDGPU::SI_WHOLE_WAVE_FUNC_RETURN));4261    return true;4262  }4263  case AMDGPU::G_STACKRESTORE:4264    return selectStackRestore(I);4265  case AMDGPU::G_PHI:4266    return selectPHI(I);4267  case AMDGPU::G_AMDGPU_COPY_SCC_VCC:4268    return selectCOPY_SCC_VCC(I);4269  case AMDGPU::G_AMDGPU_COPY_VCC_SCC:4270    return selectCOPY_VCC_SCC(I);4271  case AMDGPU::G_AMDGPU_READANYLANE:4272    return selectReadAnyLane(I);4273  case TargetOpcode::G_CONSTANT:4274  case TargetOpcode::G_FCONSTANT:4275  default:4276    return selectImpl(I, *CoverageInfo);4277  }4278  return false;4279}4280 4281InstructionSelector::ComplexRendererFns4282AMDGPUInstructionSelector::selectVCSRC(MachineOperand &Root) const {4283  return {{4284      [=](MachineInstrBuilder &MIB) { MIB.add(Root); }4285  }};4286 4287}4288 4289std::pair<Register, unsigned> AMDGPUInstructionSelector::selectVOP3ModsImpl(4290    Register Src, bool IsCanonicalizing, bool AllowAbs, bool OpSel) const {4291  unsigned Mods = 0;4292  MachineInstr *MI = getDefIgnoringCopies(Src, *MRI);4293 4294  if (MI->getOpcode() == AMDGPU::G_FNEG) {4295    Src = MI->getOperand(1).getReg();4296    Mods |= SISrcMods::NEG;4297    MI = getDefIgnoringCopies(Src, *MRI);4298  } else if (MI->getOpcode() == AMDGPU::G_FSUB && IsCanonicalizing) {4299    // Fold fsub [+-]0 into fneg. This may not have folded depending on the4300    // denormal mode, but we're implicitly canonicalizing in a source operand.4301    const ConstantFP *LHS =4302        getConstantFPVRegVal(MI->getOperand(1).getReg(), *MRI);4303    if (LHS && LHS->isZero()) {4304      Mods |= SISrcMods::NEG;4305      Src = MI->getOperand(2).getReg();4306    }4307  }4308 4309  if (AllowAbs && MI->getOpcode() == AMDGPU::G_FABS) {4310    Src = MI->getOperand(1).getReg();4311    Mods |= SISrcMods::ABS;4312  }4313 4314  if (OpSel)4315    Mods |= SISrcMods::OP_SEL_0;4316 4317  return std::pair(Src, Mods);4318}4319 4320Register AMDGPUInstructionSelector::copyToVGPRIfSrcFolded(4321    Register Src, unsigned Mods, MachineOperand Root, MachineInstr *InsertPt,4322    bool ForceVGPR) const {4323  if ((Mods != 0 || ForceVGPR) &&4324      RBI.getRegBank(Src, *MRI, TRI)->getID() != AMDGPU::VGPRRegBankID) {4325 4326    // If we looked through copies to find source modifiers on an SGPR operand,4327    // we now have an SGPR register source. To avoid potentially violating the4328    // constant bus restriction, we need to insert a copy to a VGPR.4329    Register VGPRSrc = MRI->cloneVirtualRegister(Root.getReg());4330    BuildMI(*InsertPt->getParent(), InsertPt, InsertPt->getDebugLoc(),4331            TII.get(AMDGPU::COPY), VGPRSrc)4332        .addReg(Src);4333    Src = VGPRSrc;4334  }4335 4336  return Src;4337}4338 4339///4340/// This will select either an SGPR or VGPR operand and will save us from4341/// having to write an extra tablegen pattern.4342InstructionSelector::ComplexRendererFns4343AMDGPUInstructionSelector::selectVSRC0(MachineOperand &Root) const {4344  return {{4345      [=](MachineInstrBuilder &MIB) { MIB.add(Root); }4346  }};4347}4348 4349InstructionSelector::ComplexRendererFns4350AMDGPUInstructionSelector::selectVOP3Mods0(MachineOperand &Root) const {4351  Register Src;4352  unsigned Mods;4353  std::tie(Src, Mods) = selectVOP3ModsImpl(Root.getReg());4354 4355  return {{4356      [=](MachineInstrBuilder &MIB) {4357        MIB.addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));4358      },4359      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); }, // src0_mods4360      [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },    // clamp4361      [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }     // omod4362  }};4363}4364 4365InstructionSelector::ComplexRendererFns4366AMDGPUInstructionSelector::selectVOP3BMods0(MachineOperand &Root) const {4367  Register Src;4368  unsigned Mods;4369  std::tie(Src, Mods) = selectVOP3ModsImpl(Root.getReg(),4370                                           /*IsCanonicalizing=*/true,4371                                           /*AllowAbs=*/false);4372 4373  return {{4374      [=](MachineInstrBuilder &MIB) {4375        MIB.addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));4376      },4377      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); }, // src0_mods4378      [=](MachineInstrBuilder &MIB) { MIB.addImm(0); },    // clamp4379      [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }     // omod4380  }};4381}4382 4383InstructionSelector::ComplexRendererFns4384AMDGPUInstructionSelector::selectVOP3OMods(MachineOperand &Root) const {4385  return {{4386      [=](MachineInstrBuilder &MIB) { MIB.add(Root); },4387      [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }, // clamp4388      [=](MachineInstrBuilder &MIB) { MIB.addImm(0); }  // omod4389  }};4390}4391 4392InstructionSelector::ComplexRendererFns4393AMDGPUInstructionSelector::selectVOP3Mods(MachineOperand &Root) const {4394  Register Src;4395  unsigned Mods;4396  std::tie(Src, Mods) = selectVOP3ModsImpl(Root.getReg());4397 4398  return {{4399      [=](MachineInstrBuilder &MIB) {4400        MIB.addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));4401      },4402      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); } // src_mods4403  }};4404}4405 4406InstructionSelector::ComplexRendererFns4407AMDGPUInstructionSelector::selectVOP3ModsNonCanonicalizing(4408    MachineOperand &Root) const {4409  Register Src;4410  unsigned Mods;4411  std::tie(Src, Mods) =4412      selectVOP3ModsImpl(Root.getReg(), /*IsCanonicalizing=*/false);4413 4414  return {{4415      [=](MachineInstrBuilder &MIB) {4416        MIB.addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));4417      },4418      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); } // src_mods4419  }};4420}4421 4422InstructionSelector::ComplexRendererFns4423AMDGPUInstructionSelector::selectVOP3BMods(MachineOperand &Root) const {4424  Register Src;4425  unsigned Mods;4426  std::tie(Src, Mods) =4427      selectVOP3ModsImpl(Root.getReg(), /*IsCanonicalizing=*/true,4428                         /*AllowAbs=*/false);4429 4430  return {{4431      [=](MachineInstrBuilder &MIB) {4432        MIB.addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));4433      },4434      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); } // src_mods4435  }};4436}4437 4438InstructionSelector::ComplexRendererFns4439AMDGPUInstructionSelector::selectVOP3NoMods(MachineOperand &Root) const {4440  Register Reg = Root.getReg();4441  const MachineInstr *Def = getDefIgnoringCopies(Reg, *MRI);4442  if (Def->getOpcode() == AMDGPU::G_FNEG || Def->getOpcode() == AMDGPU::G_FABS)4443    return {};4444  return {{4445      [=](MachineInstrBuilder &MIB) { MIB.addReg(Reg); },4446  }};4447}4448 4449enum class SrcStatus {4450  IS_SAME,4451  IS_UPPER_HALF,4452  IS_LOWER_HALF,4453  IS_UPPER_HALF_NEG,4454  // This means current op = [op_upper, op_lower] and src = -op_lower.4455  IS_LOWER_HALF_NEG,4456  IS_HI_NEG,4457  // This means current op = [op_upper, op_lower] and src = [op_upper,4458  // -op_lower].4459  IS_LO_NEG,4460  IS_BOTH_NEG,4461  INVALID,4462  NEG_START = IS_UPPER_HALF_NEG,4463  NEG_END = IS_BOTH_NEG,4464  HALF_START = IS_UPPER_HALF,4465  HALF_END = IS_LOWER_HALF_NEG4466};4467/// Test if the MI is truncating to half, such as `%reg0:n = G_TRUNC %reg1:2n`4468static bool isTruncHalf(const MachineInstr *MI,4469                        const MachineRegisterInfo &MRI) {4470  if (MI->getOpcode() != AMDGPU::G_TRUNC)4471    return false;4472 4473  unsigned DstSize = MRI.getType(MI->getOperand(0).getReg()).getSizeInBits();4474  unsigned SrcSize = MRI.getType(MI->getOperand(1).getReg()).getSizeInBits();4475  return DstSize * 2 == SrcSize;4476}4477 4478/// Test if the MI is logic shift right with half bits,4479/// such as `%reg0:2n =G_LSHR %reg1:2n, CONST(n)`4480static bool isLshrHalf(const MachineInstr *MI, const MachineRegisterInfo &MRI) {4481  if (MI->getOpcode() != AMDGPU::G_LSHR)4482    return false;4483 4484  Register ShiftSrc;4485  std::optional<ValueAndVReg> ShiftAmt;4486  if (mi_match(MI->getOperand(0).getReg(), MRI,4487               m_GLShr(m_Reg(ShiftSrc), m_GCst(ShiftAmt)))) {4488    unsigned SrcSize = MRI.getType(MI->getOperand(1).getReg()).getSizeInBits();4489    unsigned Shift = ShiftAmt->Value.getZExtValue();4490    return Shift * 2 == SrcSize;4491  }4492  return false;4493}4494 4495/// Test if the MI is shift left with half bits,4496/// such as `%reg0:2n =G_SHL %reg1:2n, CONST(n)`4497static bool isShlHalf(const MachineInstr *MI, const MachineRegisterInfo &MRI) {4498  if (MI->getOpcode() != AMDGPU::G_SHL)4499    return false;4500 4501  Register ShiftSrc;4502  std::optional<ValueAndVReg> ShiftAmt;4503  if (mi_match(MI->getOperand(0).getReg(), MRI,4504               m_GShl(m_Reg(ShiftSrc), m_GCst(ShiftAmt)))) {4505    unsigned SrcSize = MRI.getType(MI->getOperand(1).getReg()).getSizeInBits();4506    unsigned Shift = ShiftAmt->Value.getZExtValue();4507    return Shift * 2 == SrcSize;4508  }4509  return false;4510}4511 4512/// Test function, if the MI is `%reg0:n, %reg1:n = G_UNMERGE_VALUES %reg2:2n`4513static bool isUnmergeHalf(const MachineInstr *MI,4514                          const MachineRegisterInfo &MRI) {4515  if (MI->getOpcode() != AMDGPU::G_UNMERGE_VALUES)4516    return false;4517  return MI->getNumOperands() == 3 && MI->getOperand(0).isDef() &&4518         MI->getOperand(1).isDef() && !MI->getOperand(2).isDef();4519}4520 4521enum class TypeClass { VECTOR_OF_TWO, SCALAR, NONE_OF_LISTED };4522 4523static TypeClass isVectorOfTwoOrScalar(Register Reg,4524                                       const MachineRegisterInfo &MRI) {4525  LLT OpTy = MRI.getType(Reg);4526  if (OpTy.isScalar())4527    return TypeClass::SCALAR;4528  if (OpTy.isVector() && OpTy.getNumElements() == 2)4529    return TypeClass::VECTOR_OF_TWO;4530  return TypeClass::NONE_OF_LISTED;4531}4532 4533static SrcStatus getNegStatus(Register Reg, SrcStatus S,4534                              const MachineRegisterInfo &MRI) {4535  TypeClass NegType = isVectorOfTwoOrScalar(Reg, MRI);4536  if (NegType != TypeClass::VECTOR_OF_TWO && NegType != TypeClass::SCALAR)4537    return SrcStatus::INVALID;4538 4539  switch (S) {4540  case SrcStatus::IS_SAME:4541    if (NegType == TypeClass::VECTOR_OF_TWO) {4542      // Vector of 2:4543      // [SrcHi, SrcLo]   = [CurrHi, CurrLo]4544      // [CurrHi, CurrLo] = neg [OpHi, OpLo](2 x Type)4545      // [CurrHi, CurrLo] = [-OpHi, -OpLo](2 x Type)4546      // [SrcHi, SrcLo]   = [-OpHi, -OpLo]4547      return SrcStatus::IS_BOTH_NEG;4548    }4549    if (NegType == TypeClass::SCALAR) {4550      // Scalar:4551      // [SrcHi, SrcLo]   = [CurrHi, CurrLo]4552      // [CurrHi, CurrLo] = neg [OpHi, OpLo](Type)4553      // [CurrHi, CurrLo] = [-OpHi, OpLo](Type)4554      // [SrcHi, SrcLo]   = [-OpHi, OpLo]4555      return SrcStatus::IS_HI_NEG;4556    }4557    break;4558  case SrcStatus::IS_HI_NEG:4559    if (NegType == TypeClass::VECTOR_OF_TWO) {4560      // Vector of 2:4561      // [SrcHi, SrcLo]   = [-CurrHi, CurrLo]4562      // [CurrHi, CurrLo] = neg [OpHi, OpLo](2 x Type)4563      // [CurrHi, CurrLo] = [-OpHi, -OpLo](2 x Type)4564      // [SrcHi, SrcLo]   = [-(-OpHi), -OpLo] = [OpHi, -OpLo]4565      return SrcStatus::IS_LO_NEG;4566    }4567    if (NegType == TypeClass::SCALAR) {4568      // Scalar:4569      // [SrcHi, SrcLo]   = [-CurrHi, CurrLo]4570      // [CurrHi, CurrLo] = neg [OpHi, OpLo](Type)4571      // [CurrHi, CurrLo] = [-OpHi, OpLo](Type)4572      // [SrcHi, SrcLo]   = [-(-OpHi), OpLo] = [OpHi, OpLo]4573      return SrcStatus::IS_SAME;4574    }4575    break;4576  case SrcStatus::IS_LO_NEG:4577    if (NegType == TypeClass::VECTOR_OF_TWO) {4578      // Vector of 2:4579      // [SrcHi, SrcLo]   = [CurrHi, -CurrLo]4580      // [CurrHi, CurrLo] = fneg [OpHi, OpLo](2 x Type)4581      // [CurrHi, CurrLo] = [-OpHi, -OpLo](2 x Type)4582      // [SrcHi, SrcLo]   = [-OpHi, -(-OpLo)] = [-OpHi, OpLo]4583      return SrcStatus::IS_HI_NEG;4584    }4585    if (NegType == TypeClass::SCALAR) {4586      // Scalar:4587      // [SrcHi, SrcLo]   = [CurrHi, -CurrLo]4588      // [CurrHi, CurrLo] = fneg [OpHi, OpLo](Type)4589      // [CurrHi, CurrLo] = [-OpHi, OpLo](Type)4590      // [SrcHi, SrcLo]   = [-OpHi, -OpLo]4591      return SrcStatus::IS_BOTH_NEG;4592    }4593    break;4594  case SrcStatus::IS_BOTH_NEG:4595    if (NegType == TypeClass::VECTOR_OF_TWO) {4596      // Vector of 2:4597      // [SrcHi, SrcLo]   = [-CurrHi, -CurrLo]4598      // [CurrHi, CurrLo] = fneg [OpHi, OpLo](2 x Type)4599      // [CurrHi, CurrLo] = [-OpHi, -OpLo](2 x Type)4600      // [SrcHi, SrcLo]   = [OpHi, OpLo]4601      return SrcStatus::IS_SAME;4602    }4603    if (NegType == TypeClass::SCALAR) {4604      // Scalar:4605      // [SrcHi, SrcLo]   = [-CurrHi, -CurrLo]4606      // [CurrHi, CurrLo] = fneg [OpHi, OpLo](Type)4607      // [CurrHi, CurrLo] = [-OpHi, OpLo](Type)4608      // [SrcHi, SrcLo]   = [OpHi, -OpLo]4609      return SrcStatus::IS_LO_NEG;4610    }4611    break;4612  case SrcStatus::IS_UPPER_HALF:4613    // Vector of 2:4614    // Src = CurrUpper4615    // Curr = [CurrUpper, CurrLower]4616    // [CurrUpper, CurrLower] = fneg [OpUpper, OpLower](2 x Type)4617    // [CurrUpper, CurrLower] = [-OpUpper, -OpLower](2 x Type)4618    // Src = -OpUpper4619    //4620    // Scalar:4621    // Src = CurrUpper4622    // Curr = [CurrUpper, CurrLower]4623    // [CurrUpper, CurrLower] = fneg [OpUpper, OpLower](Type)4624    // [CurrUpper, CurrLower] = [-OpUpper, OpLower](Type)4625    // Src = -OpUpper4626    return SrcStatus::IS_UPPER_HALF_NEG;4627  case SrcStatus::IS_LOWER_HALF:4628    if (NegType == TypeClass::VECTOR_OF_TWO) {4629      // Vector of 2:4630      // Src = CurrLower4631      // Curr = [CurrUpper, CurrLower]4632      // [CurrUpper, CurrLower] = fneg [OpUpper, OpLower](2 x Type)4633      // [CurrUpper, CurrLower] = [-OpUpper, -OpLower](2 x Type)4634      // Src = -OpLower4635      return SrcStatus::IS_LOWER_HALF_NEG;4636    }4637    if (NegType == TypeClass::SCALAR) {4638      // Scalar:4639      // Src = CurrLower4640      // Curr = [CurrUpper, CurrLower]4641      // [CurrUpper, CurrLower] = fneg [OpUpper, OpLower](Type)4642      // [CurrUpper, CurrLower] = [-OpUpper, OpLower](Type)4643      // Src = OpLower4644      return SrcStatus::IS_LOWER_HALF;4645    }4646    break;4647  case SrcStatus::IS_UPPER_HALF_NEG:4648    // Vector of 2:4649    // Src = -CurrUpper4650    // Curr = [CurrUpper, CurrLower]4651    // [CurrUpper, CurrLower] = fneg [OpUpper, OpLower](2 x Type)4652    // [CurrUpper, CurrLower] = [-OpUpper, -OpLower](2 x Type)4653    // Src = -(-OpUpper) = OpUpper4654    //4655    // Scalar:4656    // Src = -CurrUpper4657    // Curr = [CurrUpper, CurrLower]4658    // [CurrUpper, CurrLower] = fneg [OpUpper, OpLower](Type)4659    // [CurrUpper, CurrLower] = [-OpUpper, OpLower](Type)4660    // Src = -(-OpUpper) = OpUpper4661    return SrcStatus::IS_UPPER_HALF;4662  case SrcStatus::IS_LOWER_HALF_NEG:4663    if (NegType == TypeClass::VECTOR_OF_TWO) {4664      // Vector of 2:4665      // Src = -CurrLower4666      // Curr = [CurrUpper, CurrLower]4667      // [CurrUpper, CurrLower] = fneg [OpUpper, OpLower](2 x Type)4668      // [CurrUpper, CurrLower] = [-OpUpper, -OpLower](2 x Type)4669      // Src = -(-OpLower) = OpLower4670      return SrcStatus::IS_LOWER_HALF;4671    }4672    if (NegType == TypeClass::SCALAR) {4673      // Scalar:4674      // Src = -CurrLower4675      // Curr = [CurrUpper, CurrLower]4676      // [CurrUpper, CurrLower] = fneg [OpUpper, OpLower](Type)4677      // [CurrUpper, CurrLower] = [-OpUpper, OpLower](Type)4678      // Src = -OpLower4679      return SrcStatus::IS_LOWER_HALF_NEG;4680    }4681    break;4682  default:4683    break;4684  }4685  llvm_unreachable("unexpected SrcStatus & NegType combination");4686}4687 4688static std::optional<std::pair<Register, SrcStatus>>4689calcNextStatus(std::pair<Register, SrcStatus> Curr,4690               const MachineRegisterInfo &MRI) {4691  const MachineInstr *MI = MRI.getVRegDef(Curr.first);4692 4693  unsigned Opc = MI->getOpcode();4694 4695  // Handle general Opc cases.4696  switch (Opc) {4697  case AMDGPU::G_BITCAST:4698    return std::optional<std::pair<Register, SrcStatus>>(4699        {MI->getOperand(1).getReg(), Curr.second});4700  case AMDGPU::COPY:4701    if (MI->getOperand(1).getReg().isPhysical())4702      return std::nullopt;4703    return std::optional<std::pair<Register, SrcStatus>>(4704        {MI->getOperand(1).getReg(), Curr.second});4705  case AMDGPU::G_FNEG: {4706    SrcStatus Stat = getNegStatus(Curr.first, Curr.second, MRI);4707    if (Stat == SrcStatus::INVALID)4708      return std::nullopt;4709    return std::optional<std::pair<Register, SrcStatus>>(4710        {MI->getOperand(1).getReg(), Stat});4711  }4712  default:4713    break;4714  }4715 4716  // Calc next Stat from current Stat.4717  switch (Curr.second) {4718  case SrcStatus::IS_SAME:4719    if (isTruncHalf(MI, MRI))4720      return std::optional<std::pair<Register, SrcStatus>>(4721          {MI->getOperand(1).getReg(), SrcStatus::IS_LOWER_HALF});4722    else if (isUnmergeHalf(MI, MRI)) {4723      if (Curr.first == MI->getOperand(0).getReg())4724        return std::optional<std::pair<Register, SrcStatus>>(4725            {MI->getOperand(2).getReg(), SrcStatus::IS_LOWER_HALF});4726      return std::optional<std::pair<Register, SrcStatus>>(4727          {MI->getOperand(2).getReg(), SrcStatus::IS_UPPER_HALF});4728    }4729    break;4730  case SrcStatus::IS_HI_NEG:4731    if (isTruncHalf(MI, MRI)) {4732      // [SrcHi, SrcLo]   = [-CurrHi, CurrLo]4733      // [CurrHi, CurrLo] = trunc [OpUpper, OpLower] = OpLower4734      //                  = [OpLowerHi, OpLowerLo]4735      // Src = [SrcHi, SrcLo] = [-CurrHi, CurrLo]4736      //     = [-OpLowerHi, OpLowerLo]4737      //     = -OpLower4738      return std::optional<std::pair<Register, SrcStatus>>(4739          {MI->getOperand(1).getReg(), SrcStatus::IS_LOWER_HALF_NEG});4740    }4741    if (isUnmergeHalf(MI, MRI)) {4742      if (Curr.first == MI->getOperand(0).getReg())4743        return std::optional<std::pair<Register, SrcStatus>>(4744            {MI->getOperand(2).getReg(), SrcStatus::IS_LOWER_HALF_NEG});4745      return std::optional<std::pair<Register, SrcStatus>>(4746          {MI->getOperand(2).getReg(), SrcStatus::IS_UPPER_HALF_NEG});4747    }4748    break;4749  case SrcStatus::IS_UPPER_HALF:4750    if (isShlHalf(MI, MRI))4751      return std::optional<std::pair<Register, SrcStatus>>(4752          {MI->getOperand(1).getReg(), SrcStatus::IS_LOWER_HALF});4753    break;4754  case SrcStatus::IS_LOWER_HALF:4755    if (isLshrHalf(MI, MRI))4756      return std::optional<std::pair<Register, SrcStatus>>(4757          {MI->getOperand(1).getReg(), SrcStatus::IS_UPPER_HALF});4758    break;4759  case SrcStatus::IS_UPPER_HALF_NEG:4760    if (isShlHalf(MI, MRI))4761      return std::optional<std::pair<Register, SrcStatus>>(4762          {MI->getOperand(1).getReg(), SrcStatus::IS_LOWER_HALF_NEG});4763    break;4764  case SrcStatus::IS_LOWER_HALF_NEG:4765    if (isLshrHalf(MI, MRI))4766      return std::optional<std::pair<Register, SrcStatus>>(4767          {MI->getOperand(1).getReg(), SrcStatus::IS_UPPER_HALF_NEG});4768    break;4769  default:4770    break;4771  }4772  return std::nullopt;4773}4774 4775/// This is used to control valid status that current MI supports. For example,4776/// non floating point intrinsic such as @llvm.amdgcn.sdot2 does not support NEG4777/// bit on VOP3P.4778/// The class can be further extended to recognize support on SEL, NEG, ABS bit4779/// for different MI on different arch4780class SearchOptions {4781private:4782  bool HasNeg = false;4783  // Assume all complex pattern of VOP3P have opsel.4784  bool HasOpsel = true;4785 4786public:4787  SearchOptions(Register Reg, const MachineRegisterInfo &MRI) {4788    const MachineInstr *MI = MRI.getVRegDef(Reg);4789    unsigned Opc = MI->getOpcode();4790 4791    if (Opc < TargetOpcode::GENERIC_OP_END) {4792      // Keep same for generic op.4793      HasNeg = true;4794    } else if (Opc == TargetOpcode::G_INTRINSIC) {4795      Intrinsic::ID IntrinsicID = cast<GIntrinsic>(*MI).getIntrinsicID();4796      // Only float point intrinsic has neg & neg_hi bits.4797      if (IntrinsicID == Intrinsic::amdgcn_fdot2)4798        HasNeg = true;4799    }4800  }4801  bool checkOptions(SrcStatus Stat) const {4802    if (!HasNeg &&4803        (Stat >= SrcStatus::NEG_START && Stat <= SrcStatus::NEG_END)) {4804      return false;4805    }4806    if (!HasOpsel &&4807        (Stat >= SrcStatus::HALF_START && Stat <= SrcStatus::HALF_END)) {4808      return false;4809    }4810    return true;4811  }4812};4813 4814static SmallVector<std::pair<Register, SrcStatus>>4815getSrcStats(Register Reg, const MachineRegisterInfo &MRI, SearchOptions SO,4816            int MaxDepth = 3) {4817  int Depth = 0;4818  auto Curr = calcNextStatus({Reg, SrcStatus::IS_SAME}, MRI);4819  SmallVector<std::pair<Register, SrcStatus>> Statlist;4820 4821  while (Depth <= MaxDepth && Curr.has_value()) {4822    Depth++;4823    if (SO.checkOptions(Curr.value().second))4824      Statlist.push_back(Curr.value());4825    Curr = calcNextStatus(Curr.value(), MRI);4826  }4827 4828  return Statlist;4829}4830 4831static std::pair<Register, SrcStatus>4832getLastSameOrNeg(Register Reg, const MachineRegisterInfo &MRI, SearchOptions SO,4833                 int MaxDepth = 3) {4834  int Depth = 0;4835  std::pair<Register, SrcStatus> LastSameOrNeg = {Reg, SrcStatus::IS_SAME};4836  auto Curr = calcNextStatus(LastSameOrNeg, MRI);4837 4838  while (Depth <= MaxDepth && Curr.has_value()) {4839    Depth++;4840    SrcStatus Stat = Curr.value().second;4841    if (SO.checkOptions(Stat)) {4842      if (Stat == SrcStatus::IS_SAME || Stat == SrcStatus::IS_HI_NEG ||4843          Stat == SrcStatus::IS_LO_NEG || Stat == SrcStatus::IS_BOTH_NEG)4844        LastSameOrNeg = Curr.value();4845    }4846    Curr = calcNextStatus(Curr.value(), MRI);4847  }4848 4849  return LastSameOrNeg;4850}4851 4852static bool isSameBitWidth(Register Reg1, Register Reg2,4853                           const MachineRegisterInfo &MRI) {4854  unsigned Width1 = MRI.getType(Reg1).getSizeInBits();4855  unsigned Width2 = MRI.getType(Reg2).getSizeInBits();4856  return Width1 == Width2;4857}4858 4859static unsigned updateMods(SrcStatus HiStat, SrcStatus LoStat, unsigned Mods) {4860  // SrcStatus::IS_LOWER_HALF remain 0.4861  if (HiStat == SrcStatus::IS_UPPER_HALF_NEG) {4862    Mods ^= SISrcMods::NEG_HI;4863    Mods |= SISrcMods::OP_SEL_1;4864  } else if (HiStat == SrcStatus::IS_UPPER_HALF)4865    Mods |= SISrcMods::OP_SEL_1;4866  else if (HiStat == SrcStatus::IS_LOWER_HALF_NEG)4867    Mods ^= SISrcMods::NEG_HI;4868  else if (HiStat == SrcStatus::IS_HI_NEG)4869    Mods ^= SISrcMods::NEG_HI;4870 4871  if (LoStat == SrcStatus::IS_UPPER_HALF_NEG) {4872    Mods ^= SISrcMods::NEG;4873    Mods |= SISrcMods::OP_SEL_0;4874  } else if (LoStat == SrcStatus::IS_UPPER_HALF)4875    Mods |= SISrcMods::OP_SEL_0;4876  else if (LoStat == SrcStatus::IS_LOWER_HALF_NEG)4877    Mods |= SISrcMods::NEG;4878  else if (LoStat == SrcStatus::IS_HI_NEG)4879    Mods ^= SISrcMods::NEG;4880 4881  return Mods;4882}4883 4884static bool isValidToPack(SrcStatus HiStat, SrcStatus LoStat, Register NewReg,4885                          Register RootReg, const SIInstrInfo &TII,4886                          const MachineRegisterInfo &MRI) {4887  auto IsHalfState = [](SrcStatus S) {4888    return S == SrcStatus::IS_UPPER_HALF || S == SrcStatus::IS_UPPER_HALF_NEG ||4889           S == SrcStatus::IS_LOWER_HALF || S == SrcStatus::IS_LOWER_HALF_NEG;4890  };4891  return isSameBitWidth(NewReg, RootReg, MRI) && IsHalfState(LoStat) &&4892         IsHalfState(HiStat);4893}4894 4895std::pair<Register, unsigned> AMDGPUInstructionSelector::selectVOP3PModsImpl(4896    Register RootReg, const MachineRegisterInfo &MRI, bool IsDOT) const {4897  unsigned Mods = 0;4898  // No modification if Root type is not form of <2 x Type>.4899  if (isVectorOfTwoOrScalar(RootReg, MRI) != TypeClass::VECTOR_OF_TWO) {4900    Mods |= SISrcMods::OP_SEL_1;4901    return {RootReg, Mods};4902  }4903 4904  SearchOptions SO(RootReg, MRI);4905 4906  std::pair<Register, SrcStatus> Stat = getLastSameOrNeg(RootReg, MRI, SO);4907 4908  if (Stat.second == SrcStatus::IS_BOTH_NEG)4909    Mods ^= (SISrcMods::NEG | SISrcMods::NEG_HI);4910  else if (Stat.second == SrcStatus::IS_HI_NEG)4911    Mods ^= SISrcMods::NEG_HI;4912  else if (Stat.second == SrcStatus::IS_LO_NEG)4913    Mods ^= SISrcMods::NEG;4914 4915  MachineInstr *MI = MRI.getVRegDef(Stat.first);4916 4917  if (MI->getOpcode() != AMDGPU::G_BUILD_VECTOR || MI->getNumOperands() != 3 ||4918      (IsDOT && Subtarget->hasDOTOpSelHazard())) {4919    Mods |= SISrcMods::OP_SEL_1;4920    return {Stat.first, Mods};4921  }4922 4923  SmallVector<std::pair<Register, SrcStatus>> StatlistHi =4924      getSrcStats(MI->getOperand(2).getReg(), MRI, SO);4925 4926  if (StatlistHi.empty()) {4927    Mods |= SISrcMods::OP_SEL_1;4928    return {Stat.first, Mods};4929  }4930 4931  SmallVector<std::pair<Register, SrcStatus>> StatlistLo =4932      getSrcStats(MI->getOperand(1).getReg(), MRI, SO);4933 4934  if (StatlistLo.empty()) {4935    Mods |= SISrcMods::OP_SEL_1;4936    return {Stat.first, Mods};4937  }4938 4939  for (int I = StatlistHi.size() - 1; I >= 0; I--) {4940    for (int J = StatlistLo.size() - 1; J >= 0; J--) {4941      if (StatlistHi[I].first == StatlistLo[J].first &&4942          isValidToPack(StatlistHi[I].second, StatlistLo[J].second,4943                        StatlistHi[I].first, RootReg, TII, MRI))4944        return {StatlistHi[I].first,4945                updateMods(StatlistHi[I].second, StatlistLo[J].second, Mods)};4946    }4947  }4948  // Packed instructions do not have abs modifiers.4949  Mods |= SISrcMods::OP_SEL_1;4950 4951  return {Stat.first, Mods};4952}4953 4954// Removed unused function `getAllKindImm` to eliminate dead code.4955 4956static bool checkRB(Register Reg, unsigned int RBNo,4957                    const AMDGPURegisterBankInfo &RBI,4958                    const MachineRegisterInfo &MRI,4959                    const TargetRegisterInfo &TRI) {4960  const RegisterBank *RB = RBI.getRegBank(Reg, MRI, TRI);4961  return RB->getID() == RBNo;4962}4963 4964// This function is used to get the correct register bank for returned reg.4965// Assume:4966// 1. VOP3P is always legal for VGPR.4967// 2. RootOp's regbank is legal.4968// Thus4969// 1. If RootOp is SGPR, then NewOp can be SGPR or VGPR.4970// 2. If RootOp is VGPR, then NewOp must be VGPR.4971static Register getLegalRegBank(Register NewReg, Register RootReg,4972                                const AMDGPURegisterBankInfo &RBI,4973                                MachineRegisterInfo &MRI,4974                                const TargetRegisterInfo &TRI,4975                                const SIInstrInfo &TII) {4976  // RootOp can only be VGPR or SGPR (some hand written cases such as.4977  // inst-select-ashr.v2s16.mir::ashr_v2s16_vs).4978  if (checkRB(RootReg, AMDGPU::SGPRRegBankID, RBI, MRI, TRI) ||4979      checkRB(NewReg, AMDGPU::VGPRRegBankID, RBI, MRI, TRI))4980    return NewReg;4981 4982  MachineInstr *MI = MRI.getVRegDef(RootReg);4983  if (MI->getOpcode() == AMDGPU::COPY && NewReg == MI->getOperand(1).getReg()) {4984    // RootOp is VGPR, NewOp is not VGPR, but RootOp = COPY NewOp.4985    return RootReg;4986  }4987 4988  MachineBasicBlock *BB = MI->getParent();4989  Register DstReg = MRI.cloneVirtualRegister(RootReg);4990 4991  MachineInstrBuilder MIB =4992      BuildMI(*BB, MI, MI->getDebugLoc(), TII.get(AMDGPU::COPY), DstReg)4993          .addReg(NewReg);4994 4995  // Only accept VGPR.4996  return MIB->getOperand(0).getReg();4997}4998 4999InstructionSelector::ComplexRendererFns5000AMDGPUInstructionSelector::selectVOP3PRetHelper(MachineOperand &Root,5001                                                bool IsDOT) const {5002  MachineRegisterInfo &MRI = Root.getParent()->getMF()->getRegInfo();5003  Register Reg;5004  unsigned Mods;5005  std::tie(Reg, Mods) = selectVOP3PModsImpl(Root.getReg(), MRI, IsDOT);5006 5007  Reg = getLegalRegBank(Reg, Root.getReg(), RBI, MRI, TRI, TII);5008  return {{5009      [=](MachineInstrBuilder &MIB) { MIB.addReg(Reg); },5010      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); } // src_mods5011  }};5012}5013 5014InstructionSelector::ComplexRendererFns5015AMDGPUInstructionSelector::selectVOP3PMods(MachineOperand &Root) const {5016 5017  return selectVOP3PRetHelper(Root);5018}5019 5020InstructionSelector::ComplexRendererFns5021AMDGPUInstructionSelector::selectVOP3PModsDOT(MachineOperand &Root) const {5022 5023  return selectVOP3PRetHelper(Root, true);5024}5025 5026InstructionSelector::ComplexRendererFns5027AMDGPUInstructionSelector::selectWMMAOpSelVOP3PMods(5028    MachineOperand &Root) const {5029  assert((Root.isImm() && (Root.getImm() == -1 || Root.getImm() == 0)) &&5030         "expected i1 value");5031  unsigned Mods = SISrcMods::OP_SEL_1;5032  if (Root.getImm() != 0)5033    Mods |= SISrcMods::OP_SEL_0;5034 5035  return {{5036      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); } // src_mods5037  }};5038}5039 5040static Register buildRegSequence(SmallVectorImpl<Register> &Elts,5041                                 MachineInstr *InsertPt,5042                                 MachineRegisterInfo &MRI) {5043  const TargetRegisterClass *DstRegClass;5044  switch (Elts.size()) {5045  case 8:5046    DstRegClass = &AMDGPU::VReg_256RegClass;5047    break;5048  case 4:5049    DstRegClass = &AMDGPU::VReg_128RegClass;5050    break;5051  case 2:5052    DstRegClass = &AMDGPU::VReg_64RegClass;5053    break;5054  default:5055    llvm_unreachable("unhandled Reg sequence size");5056  }5057 5058  MachineIRBuilder B(*InsertPt);5059  auto MIB = B.buildInstr(AMDGPU::REG_SEQUENCE)5060                 .addDef(MRI.createVirtualRegister(DstRegClass));5061  for (unsigned i = 0; i < Elts.size(); ++i) {5062    MIB.addReg(Elts[i]);5063    MIB.addImm(SIRegisterInfo::getSubRegFromChannel(i));5064  }5065  return MIB->getOperand(0).getReg();5066}5067 5068static void selectWMMAModsNegAbs(unsigned ModOpcode, unsigned &Mods,5069                                 SmallVectorImpl<Register> &Elts, Register &Src,5070                                 MachineInstr *InsertPt,5071                                 MachineRegisterInfo &MRI) {5072  if (ModOpcode == TargetOpcode::G_FNEG) {5073    Mods |= SISrcMods::NEG;5074    // Check if all elements also have abs modifier5075    SmallVector<Register, 8> NegAbsElts;5076    for (auto El : Elts) {5077      Register FabsSrc;5078      if (!mi_match(El, MRI, m_GFabs(m_Reg(FabsSrc))))5079        break;5080      NegAbsElts.push_back(FabsSrc);5081    }5082    if (Elts.size() != NegAbsElts.size()) {5083      // Neg5084      Src = buildRegSequence(Elts, InsertPt, MRI);5085    } else {5086      // Neg and Abs5087      Mods |= SISrcMods::NEG_HI;5088      Src = buildRegSequence(NegAbsElts, InsertPt, MRI);5089    }5090  } else {5091    assert(ModOpcode == TargetOpcode::G_FABS);5092    // Abs5093    Mods |= SISrcMods::NEG_HI;5094    Src = buildRegSequence(Elts, InsertPt, MRI);5095  }5096}5097 5098InstructionSelector::ComplexRendererFns5099AMDGPUInstructionSelector::selectWMMAModsF32NegAbs(MachineOperand &Root) const {5100  Register Src = Root.getReg();5101  unsigned Mods = SISrcMods::OP_SEL_1;5102  SmallVector<Register, 8> EltsF32;5103 5104  if (GBuildVector *BV = dyn_cast<GBuildVector>(MRI->getVRegDef(Src))) {5105    assert(BV->getNumSources() > 0);5106    // Based on first element decide which mod we match, neg or abs5107    MachineInstr *ElF32 = MRI->getVRegDef(BV->getSourceReg(0));5108    unsigned ModOpcode = (ElF32->getOpcode() == AMDGPU::G_FNEG)5109                             ? AMDGPU::G_FNEG5110                             : AMDGPU::G_FABS;5111    for (unsigned i = 0; i < BV->getNumSources(); ++i) {5112      ElF32 = MRI->getVRegDef(BV->getSourceReg(i));5113      if (ElF32->getOpcode() != ModOpcode)5114        break;5115      EltsF32.push_back(ElF32->getOperand(1).getReg());5116    }5117 5118    // All elements had ModOpcode modifier5119    if (BV->getNumSources() == EltsF32.size()) {5120      selectWMMAModsNegAbs(ModOpcode, Mods, EltsF32, Src, Root.getParent(),5121                           *MRI);5122    }5123  }5124 5125  return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Src); },5126           [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); }}};5127}5128 5129InstructionSelector::ComplexRendererFns5130AMDGPUInstructionSelector::selectWMMAModsF16Neg(MachineOperand &Root) const {5131  Register Src = Root.getReg();5132  unsigned Mods = SISrcMods::OP_SEL_1;5133  SmallVector<Register, 8> EltsV2F16;5134 5135  if (GConcatVectors *CV = dyn_cast<GConcatVectors>(MRI->getVRegDef(Src))) {5136    for (unsigned i = 0; i < CV->getNumSources(); ++i) {5137      Register FNegSrc;5138      if (!mi_match(CV->getSourceReg(i), *MRI, m_GFNeg(m_Reg(FNegSrc))))5139        break;5140      EltsV2F16.push_back(FNegSrc);5141    }5142 5143    // All elements had ModOpcode modifier5144    if (CV->getNumSources() == EltsV2F16.size()) {5145      Mods |= SISrcMods::NEG;5146      Mods |= SISrcMods::NEG_HI;5147      Src = buildRegSequence(EltsV2F16, Root.getParent(), *MRI);5148    }5149  }5150 5151  return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Src); },5152           [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); }}};5153}5154 5155InstructionSelector::ComplexRendererFns5156AMDGPUInstructionSelector::selectWMMAModsF16NegAbs(MachineOperand &Root) const {5157  Register Src = Root.getReg();5158  unsigned Mods = SISrcMods::OP_SEL_1;5159  SmallVector<Register, 8> EltsV2F16;5160 5161  if (GConcatVectors *CV = dyn_cast<GConcatVectors>(MRI->getVRegDef(Src))) {5162    assert(CV->getNumSources() > 0);5163    MachineInstr *ElV2F16 = MRI->getVRegDef(CV->getSourceReg(0));5164    // Based on first element decide which mod we match, neg or abs5165    unsigned ModOpcode = (ElV2F16->getOpcode() == AMDGPU::G_FNEG)5166                             ? AMDGPU::G_FNEG5167                             : AMDGPU::G_FABS;5168 5169    for (unsigned i = 0; i < CV->getNumSources(); ++i) {5170      ElV2F16 = MRI->getVRegDef(CV->getSourceReg(i));5171      if (ElV2F16->getOpcode() != ModOpcode)5172        break;5173      EltsV2F16.push_back(ElV2F16->getOperand(1).getReg());5174    }5175 5176    // All elements had ModOpcode modifier5177    if (CV->getNumSources() == EltsV2F16.size()) {5178      MachineIRBuilder B(*Root.getParent());5179      selectWMMAModsNegAbs(ModOpcode, Mods, EltsV2F16, Src, Root.getParent(),5180                           *MRI);5181    }5182  }5183 5184  return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Src); },5185           [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); }}};5186}5187 5188InstructionSelector::ComplexRendererFns5189AMDGPUInstructionSelector::selectWMMAVISrc(MachineOperand &Root) const {5190  std::optional<FPValueAndVReg> FPValReg;5191  if (mi_match(Root.getReg(), *MRI, m_GFCstOrSplat(FPValReg))) {5192    if (TII.isInlineConstant(FPValReg->Value)) {5193      return {{[=](MachineInstrBuilder &MIB) {5194        MIB.addImm(FPValReg->Value.bitcastToAPInt().getSExtValue());5195      }}};5196    }5197    // Non-inlineable splat floats should not fall-through for integer immediate5198    // checks.5199    return {};5200  }5201 5202  APInt ICst;5203  if (mi_match(Root.getReg(), *MRI, m_ICstOrSplat(ICst))) {5204    if (TII.isInlineConstant(ICst)) {5205      return {5206          {[=](MachineInstrBuilder &MIB) { MIB.addImm(ICst.getSExtValue()); }}};5207    }5208  }5209 5210  return {};5211}5212 5213InstructionSelector::ComplexRendererFns5214AMDGPUInstructionSelector::selectSWMMACIndex8(MachineOperand &Root) const {5215  Register Src =5216      getDefIgnoringCopies(Root.getReg(), *MRI)->getOperand(0).getReg();5217  unsigned Key = 0;5218 5219  Register ShiftSrc;5220  std::optional<ValueAndVReg> ShiftAmt;5221  if (mi_match(Src, *MRI, m_GLShr(m_Reg(ShiftSrc), m_GCst(ShiftAmt))) &&5222      MRI->getType(ShiftSrc).getSizeInBits() == 32 &&5223      ShiftAmt->Value.getZExtValue() % 8 == 0) {5224    Key = ShiftAmt->Value.getZExtValue() / 8;5225    Src = ShiftSrc;5226  }5227 5228  return {{5229      [=](MachineInstrBuilder &MIB) { MIB.addReg(Src); },5230      [=](MachineInstrBuilder &MIB) { MIB.addImm(Key); } // index_key5231  }};5232}5233 5234InstructionSelector::ComplexRendererFns5235AMDGPUInstructionSelector::selectSWMMACIndex16(MachineOperand &Root) const {5236 5237  Register Src =5238      getDefIgnoringCopies(Root.getReg(), *MRI)->getOperand(0).getReg();5239  unsigned Key = 0;5240 5241  Register ShiftSrc;5242  std::optional<ValueAndVReg> ShiftAmt;5243  if (mi_match(Src, *MRI, m_GLShr(m_Reg(ShiftSrc), m_GCst(ShiftAmt))) &&5244      MRI->getType(ShiftSrc).getSizeInBits() == 32 &&5245      ShiftAmt->Value.getZExtValue() == 16) {5246    Src = ShiftSrc;5247    Key = 1;5248  }5249 5250  return {{5251      [=](MachineInstrBuilder &MIB) { MIB.addReg(Src); },5252      [=](MachineInstrBuilder &MIB) { MIB.addImm(Key); } // index_key5253  }};5254}5255 5256InstructionSelector::ComplexRendererFns5257AMDGPUInstructionSelector::selectSWMMACIndex32(MachineOperand &Root) const {5258  Register Src =5259      getDefIgnoringCopies(Root.getReg(), *MRI)->getOperand(0).getReg();5260  unsigned Key = 0;5261 5262  Register S32 = matchZeroExtendFromS32(Src);5263  if (!S32)5264    S32 = matchAnyExtendFromS32(Src);5265 5266  if (S32) {5267    const MachineInstr *Def = getDefIgnoringCopies(S32, *MRI);5268    if (Def->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) {5269      assert(Def->getNumOperands() == 3);5270      Register DstReg1 = Def->getOperand(1).getReg();5271      if (mi_match(S32, *MRI,5272                   m_any_of(m_SpecificReg(DstReg1), m_Copy(m_Reg(DstReg1))))) {5273        Src = Def->getOperand(2).getReg();5274        Key = 1;5275      }5276    }5277  }5278 5279  return {{5280      [=](MachineInstrBuilder &MIB) { MIB.addReg(Src); },5281      [=](MachineInstrBuilder &MIB) { MIB.addImm(Key); } // index_key5282  }};5283}5284 5285InstructionSelector::ComplexRendererFns5286AMDGPUInstructionSelector::selectVOP3OpSelMods(MachineOperand &Root) const {5287  Register Src;5288  unsigned Mods;5289  std::tie(Src, Mods) = selectVOP3ModsImpl(Root.getReg());5290 5291  // FIXME: Handle op_sel5292  return {{5293      [=](MachineInstrBuilder &MIB) { MIB.addReg(Src); },5294      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); } // src_mods5295  }};5296}5297 5298// FIXME-TRUE16 remove when fake16 is removed5299InstructionSelector::ComplexRendererFns5300AMDGPUInstructionSelector::selectVINTERPMods(MachineOperand &Root) const {5301  Register Src;5302  unsigned Mods;5303  std::tie(Src, Mods) = selectVOP3ModsImpl(Root.getReg(),5304                                           /*IsCanonicalizing=*/true,5305                                           /*AllowAbs=*/false,5306                                           /*OpSel=*/false);5307 5308  return {{5309      [=](MachineInstrBuilder &MIB) {5310        MIB.addReg(5311            copyToVGPRIfSrcFolded(Src, Mods, Root, MIB, /* ForceVGPR */ true));5312      },5313      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); }, // src0_mods5314  }};5315}5316 5317InstructionSelector::ComplexRendererFns5318AMDGPUInstructionSelector::selectVINTERPModsHi(MachineOperand &Root) const {5319  Register Src;5320  unsigned Mods;5321  std::tie(Src, Mods) = selectVOP3ModsImpl(Root.getReg(),5322                                           /*IsCanonicalizing=*/true,5323                                           /*AllowAbs=*/false,5324                                           /*OpSel=*/true);5325 5326  return {{5327      [=](MachineInstrBuilder &MIB) {5328        MIB.addReg(5329            copyToVGPRIfSrcFolded(Src, Mods, Root, MIB, /* ForceVGPR */ true));5330      },5331      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); }, // src0_mods5332  }};5333}5334 5335// Given \p Offset and load specified by the \p Root operand check if \p Offset5336// is a multiple of the load byte size. If it is update \p Offset to a5337// pre-scaled value and return true.5338bool AMDGPUInstructionSelector::selectScaleOffset(MachineOperand &Root,5339                                                  Register &Offset,5340                                                  bool IsSigned) const {5341  if (!Subtarget->hasScaleOffset())5342    return false;5343 5344  const MachineInstr &MI = *Root.getParent();5345  MachineMemOperand *MMO = *MI.memoperands_begin();5346 5347  if (!MMO->getSize().hasValue())5348    return false;5349 5350  uint64_t Size = MMO->getSize().getValue();5351 5352  Register OffsetReg = matchExtendFromS32OrS32(Offset, IsSigned);5353  if (!OffsetReg)5354    OffsetReg = Offset;5355 5356  if (auto Def = getDefSrcRegIgnoringCopies(OffsetReg, *MRI))5357    OffsetReg = Def->Reg;5358 5359  Register Op0;5360  MachineInstr *Mul;5361  bool ScaleOffset =5362      (isPowerOf2_64(Size) &&5363       mi_match(OffsetReg, *MRI,5364                m_GShl(m_Reg(Op0),5365                       m_any_of(m_SpecificICst(Log2_64(Size)),5366                                m_Copy(m_SpecificICst(Log2_64(Size))))))) ||5367      mi_match(OffsetReg, *MRI,5368               m_GMul(m_Reg(Op0), m_any_of(m_SpecificICst(Size),5369                                           m_Copy(m_SpecificICst(Size))))) ||5370      mi_match(5371          OffsetReg, *MRI,5372          m_BinOp(IsSigned ? AMDGPU::S_MUL_I64_I32_PSEUDO : AMDGPU::S_MUL_U64,5373                  m_Reg(Op0), m_SpecificICst(Size))) ||5374      // Match G_AMDGPU_MAD_U64_U32 offset, c, 05375      (mi_match(OffsetReg, *MRI, m_MInstr(Mul)) &&5376       (Mul->getOpcode() == (IsSigned ? AMDGPU::G_AMDGPU_MAD_I64_I325377                                      : AMDGPU::G_AMDGPU_MAD_U64_U32) ||5378        (IsSigned && Mul->getOpcode() == AMDGPU::G_AMDGPU_MAD_U64_U32 &&5379         VT->signBitIsZero(Mul->getOperand(2).getReg()))) &&5380       mi_match(Mul->getOperand(4).getReg(), *MRI, m_ZeroInt()) &&5381       mi_match(Mul->getOperand(3).getReg(), *MRI,5382                m_GTrunc(m_any_of(m_SpecificICst(Size),5383                                  m_Copy(m_SpecificICst(Size))))) &&5384       mi_match(Mul->getOperand(2).getReg(), *MRI, m_Reg(Op0)));5385 5386  if (ScaleOffset)5387    Offset = Op0;5388 5389  return ScaleOffset;5390}5391 5392bool AMDGPUInstructionSelector::selectSmrdOffset(MachineOperand &Root,5393                                                 Register &Base,5394                                                 Register *SOffset,5395                                                 int64_t *Offset,5396                                                 bool *ScaleOffset) const {5397  MachineInstr *MI = Root.getParent();5398  MachineBasicBlock *MBB = MI->getParent();5399 5400  // FIXME: We should shrink the GEP if the offset is known to be <= 32-bits,5401  // then we can select all ptr + 32-bit offsets.5402  SmallVector<GEPInfo, 4> AddrInfo;5403  getAddrModeInfo(*MI, *MRI, AddrInfo);5404 5405  if (AddrInfo.empty())5406    return false;5407 5408  const GEPInfo &GEPI = AddrInfo[0];5409  std::optional<int64_t> EncodedImm;5410 5411  if (ScaleOffset)5412    *ScaleOffset = false;5413 5414  if (SOffset && Offset) {5415    EncodedImm = AMDGPU::getSMRDEncodedOffset(STI, GEPI.Imm, /*IsBuffer=*/false,5416                                              /*HasSOffset=*/true);5417    if (GEPI.SgprParts.size() == 1 && GEPI.Imm != 0 && EncodedImm &&5418        AddrInfo.size() > 1) {5419      const GEPInfo &GEPI2 = AddrInfo[1];5420      if (GEPI2.SgprParts.size() == 2 && GEPI2.Imm == 0) {5421        Register OffsetReg = GEPI2.SgprParts[1];5422        if (ScaleOffset)5423          *ScaleOffset =5424              selectScaleOffset(Root, OffsetReg, false /* IsSigned */);5425        OffsetReg = matchZeroExtendFromS32OrS32(OffsetReg);5426        if (OffsetReg) {5427          Base = GEPI2.SgprParts[0];5428          *SOffset = OffsetReg;5429          *Offset = *EncodedImm;5430          if (*Offset >= 0 || !AMDGPU::hasSMRDSignedImmOffset(STI))5431            return true;5432 5433          // For unbuffered smem loads, it is illegal for the Immediate Offset5434          // to be negative if the resulting (Offset + (M0 or SOffset or zero)5435          // is negative. Handle the case where the Immediate Offset + SOffset5436          // is negative.5437          auto SKnown = VT->getKnownBits(*SOffset);5438          if (*Offset + SKnown.getMinValue().getSExtValue() < 0)5439            return false;5440 5441          return true;5442        }5443      }5444    }5445    return false;5446  }5447 5448  EncodedImm = AMDGPU::getSMRDEncodedOffset(STI, GEPI.Imm, /*IsBuffer=*/false,5449                                            /*HasSOffset=*/false);5450  if (Offset && GEPI.SgprParts.size() == 1 && EncodedImm) {5451    Base = GEPI.SgprParts[0];5452    *Offset = *EncodedImm;5453    return true;5454  }5455 5456  // SGPR offset is unsigned.5457  if (SOffset && GEPI.SgprParts.size() == 1 && isUInt<32>(GEPI.Imm) &&5458      GEPI.Imm != 0) {5459    // If we make it this far we have a load with an 32-bit immediate offset.5460    // It is OK to select this using a sgpr offset, because we have already5461    // failed trying to select this load into one of the _IMM variants since5462    // the _IMM Patterns are considered before the _SGPR patterns.5463    Base = GEPI.SgprParts[0];5464    *SOffset = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);5465    BuildMI(*MBB, MI, MI->getDebugLoc(), TII.get(AMDGPU::S_MOV_B32), *SOffset)5466        .addImm(GEPI.Imm);5467    return true;5468  }5469 5470  if (SOffset && GEPI.SgprParts.size() && GEPI.Imm == 0) {5471    Register OffsetReg = GEPI.SgprParts[1];5472    if (ScaleOffset)5473      *ScaleOffset = selectScaleOffset(Root, OffsetReg, false /* IsSigned */);5474    OffsetReg = matchZeroExtendFromS32OrS32(OffsetReg);5475    if (OffsetReg) {5476      Base = GEPI.SgprParts[0];5477      *SOffset = OffsetReg;5478      return true;5479    }5480  }5481 5482  return false;5483}5484 5485InstructionSelector::ComplexRendererFns5486AMDGPUInstructionSelector::selectSmrdImm(MachineOperand &Root) const {5487  Register Base;5488  int64_t Offset;5489  if (!selectSmrdOffset(Root, Base, /* SOffset= */ nullptr, &Offset,5490                        /* ScaleOffset */ nullptr))5491    return std::nullopt;5492 5493  return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Base); },5494           [=](MachineInstrBuilder &MIB) { MIB.addImm(Offset); }}};5495}5496 5497InstructionSelector::ComplexRendererFns5498AMDGPUInstructionSelector::selectSmrdImm32(MachineOperand &Root) const {5499  SmallVector<GEPInfo, 4> AddrInfo;5500  getAddrModeInfo(*Root.getParent(), *MRI, AddrInfo);5501 5502  if (AddrInfo.empty() || AddrInfo[0].SgprParts.size() != 1)5503    return std::nullopt;5504 5505  const GEPInfo &GEPInfo = AddrInfo[0];5506  Register PtrReg = GEPInfo.SgprParts[0];5507  std::optional<int64_t> EncodedImm =5508      AMDGPU::getSMRDEncodedLiteralOffset32(STI, GEPInfo.Imm);5509  if (!EncodedImm)5510    return std::nullopt;5511 5512  return {{5513    [=](MachineInstrBuilder &MIB) { MIB.addReg(PtrReg); },5514    [=](MachineInstrBuilder &MIB) { MIB.addImm(*EncodedImm); }5515  }};5516}5517 5518InstructionSelector::ComplexRendererFns5519AMDGPUInstructionSelector::selectSmrdSgpr(MachineOperand &Root) const {5520  Register Base, SOffset;5521  bool ScaleOffset;5522  if (!selectSmrdOffset(Root, Base, &SOffset, /* Offset= */ nullptr,5523                        &ScaleOffset))5524    return std::nullopt;5525 5526  unsigned CPol = ScaleOffset ? AMDGPU::CPol::SCAL : 0;5527  return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Base); },5528           [=](MachineInstrBuilder &MIB) { MIB.addReg(SOffset); },5529           [=](MachineInstrBuilder &MIB) { MIB.addImm(CPol); }}};5530}5531 5532InstructionSelector::ComplexRendererFns5533AMDGPUInstructionSelector::selectSmrdSgprImm(MachineOperand &Root) const {5534  Register Base, SOffset;5535  int64_t Offset;5536  bool ScaleOffset;5537  if (!selectSmrdOffset(Root, Base, &SOffset, &Offset, &ScaleOffset))5538    return std::nullopt;5539 5540  unsigned CPol = ScaleOffset ? AMDGPU::CPol::SCAL : 0;5541  return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(Base); },5542           [=](MachineInstrBuilder &MIB) { MIB.addReg(SOffset); },5543           [=](MachineInstrBuilder &MIB) { MIB.addImm(Offset); },5544           [=](MachineInstrBuilder &MIB) { MIB.addImm(CPol); }}};5545}5546 5547std::pair<Register, int>5548AMDGPUInstructionSelector::selectFlatOffsetImpl(MachineOperand &Root,5549                                                uint64_t FlatVariant) const {5550  MachineInstr *MI = Root.getParent();5551 5552  auto Default = std::pair(Root.getReg(), 0);5553 5554  if (!STI.hasFlatInstOffsets())5555    return Default;5556 5557  Register PtrBase;5558  int64_t ConstOffset;5559  bool IsInBounds;5560  std::tie(PtrBase, ConstOffset, IsInBounds) =5561      getPtrBaseWithConstantOffset(Root.getReg(), *MRI);5562 5563  // Adding the offset to the base address with an immediate in a FLAT5564  // instruction must not change the memory aperture in which the address falls.5565  // Therefore we can only fold offsets from inbounds GEPs into FLAT5566  // instructions.5567  if (ConstOffset == 0 ||5568      (FlatVariant == SIInstrFlags::FlatScratch &&5569       !isFlatScratchBaseLegal(Root.getReg())) ||5570      (FlatVariant == SIInstrFlags::FLAT && !IsInBounds))5571    return Default;5572 5573  unsigned AddrSpace = (*MI->memoperands_begin())->getAddrSpace();5574  if (!TII.isLegalFLATOffset(ConstOffset, AddrSpace, FlatVariant))5575    return Default;5576 5577  return std::pair(PtrBase, ConstOffset);5578}5579 5580InstructionSelector::ComplexRendererFns5581AMDGPUInstructionSelector::selectFlatOffset(MachineOperand &Root) const {5582  auto PtrWithOffset = selectFlatOffsetImpl(Root, SIInstrFlags::FLAT);5583 5584  return {{5585      [=](MachineInstrBuilder &MIB) { MIB.addReg(PtrWithOffset.first); },5586      [=](MachineInstrBuilder &MIB) { MIB.addImm(PtrWithOffset.second); },5587    }};5588}5589 5590InstructionSelector::ComplexRendererFns5591AMDGPUInstructionSelector::selectGlobalOffset(MachineOperand &Root) const {5592  auto PtrWithOffset = selectFlatOffsetImpl(Root, SIInstrFlags::FlatGlobal);5593 5594  return {{5595      [=](MachineInstrBuilder &MIB) { MIB.addReg(PtrWithOffset.first); },5596      [=](MachineInstrBuilder &MIB) { MIB.addImm(PtrWithOffset.second); },5597  }};5598}5599 5600InstructionSelector::ComplexRendererFns5601AMDGPUInstructionSelector::selectScratchOffset(MachineOperand &Root) const {5602  auto PtrWithOffset = selectFlatOffsetImpl(Root, SIInstrFlags::FlatScratch);5603 5604  return {{5605      [=](MachineInstrBuilder &MIB) { MIB.addReg(PtrWithOffset.first); },5606      [=](MachineInstrBuilder &MIB) { MIB.addImm(PtrWithOffset.second); },5607    }};5608}5609 5610// Match (64-bit SGPR base) + (zext vgpr offset) + sext(imm offset)5611InstructionSelector::ComplexRendererFns5612AMDGPUInstructionSelector::selectGlobalSAddr(MachineOperand &Root,5613                                             unsigned CPolBits,5614                                             bool NeedIOffset) const {5615  Register Addr = Root.getReg();5616  Register PtrBase;5617  int64_t ConstOffset;5618  int64_t ImmOffset = 0;5619 5620  // Match the immediate offset first, which canonically is moved as low as5621  // possible.5622  std::tie(PtrBase, ConstOffset, std::ignore) =5623      getPtrBaseWithConstantOffset(Addr, *MRI);5624 5625  if (ConstOffset != 0) {5626    if (NeedIOffset &&5627        TII.isLegalFLATOffset(ConstOffset, AMDGPUAS::GLOBAL_ADDRESS,5628                              SIInstrFlags::FlatGlobal)) {5629      Addr = PtrBase;5630      ImmOffset = ConstOffset;5631    } else {5632      auto PtrBaseDef = getDefSrcRegIgnoringCopies(PtrBase, *MRI);5633      if (isSGPR(PtrBaseDef->Reg)) {5634        if (ConstOffset > 0) {5635          // Offset is too large.5636          //5637          // saddr + large_offset -> saddr +5638          //                         (voffset = large_offset & ~MaxOffset) +5639          //                         (large_offset & MaxOffset);5640          int64_t SplitImmOffset = 0, RemainderOffset = ConstOffset;5641          if (NeedIOffset) {5642            std::tie(SplitImmOffset, RemainderOffset) =5643                TII.splitFlatOffset(ConstOffset, AMDGPUAS::GLOBAL_ADDRESS,5644                                    SIInstrFlags::FlatGlobal);5645          }5646 5647          if (Subtarget->hasSignedGVSOffset() ? isInt<32>(RemainderOffset)5648                                              : isUInt<32>(RemainderOffset)) {5649            MachineInstr *MI = Root.getParent();5650            MachineBasicBlock *MBB = MI->getParent();5651            Register HighBits =5652                MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);5653 5654            BuildMI(*MBB, MI, MI->getDebugLoc(), TII.get(AMDGPU::V_MOV_B32_e32),5655                    HighBits)5656                .addImm(RemainderOffset);5657 5658            if (NeedIOffset)5659              return {{5660                  [=](MachineInstrBuilder &MIB) {5661                    MIB.addReg(PtrBase);5662                  }, // saddr5663                  [=](MachineInstrBuilder &MIB) {5664                    MIB.addReg(HighBits);5665                  }, // voffset5666                  [=](MachineInstrBuilder &MIB) { MIB.addImm(SplitImmOffset); },5667                  [=](MachineInstrBuilder &MIB) { MIB.addImm(CPolBits); },5668              }};5669            return {{5670                [=](MachineInstrBuilder &MIB) { MIB.addReg(PtrBase); }, // saddr5671                [=](MachineInstrBuilder &MIB) {5672                  MIB.addReg(HighBits);5673                }, // voffset5674                [=](MachineInstrBuilder &MIB) { MIB.addImm(CPolBits); },5675            }};5676          }5677        }5678 5679        // We are adding a 64 bit SGPR and a constant. If constant bus limit5680        // is 1 we would need to perform 1 or 2 extra moves for each half of5681        // the constant and it is better to do a scalar add and then issue a5682        // single VALU instruction to materialize zero. Otherwise it is less5683        // instructions to perform VALU adds with immediates or inline literals.5684        unsigned NumLiterals =5685            !TII.isInlineConstant(APInt(32, Lo_32(ConstOffset))) +5686            !TII.isInlineConstant(APInt(32, Hi_32(ConstOffset)));5687        if (STI.getConstantBusLimit(AMDGPU::V_ADD_U32_e64) > NumLiterals)5688          return std::nullopt;5689      }5690    }5691  }5692 5693  // Match the variable offset.5694  auto AddrDef = getDefSrcRegIgnoringCopies(Addr, *MRI);5695  if (AddrDef->MI->getOpcode() == AMDGPU::G_PTR_ADD) {5696    // Look through the SGPR->VGPR copy.5697    Register SAddr =5698        getSrcRegIgnoringCopies(AddrDef->MI->getOperand(1).getReg(), *MRI);5699 5700    if (isSGPR(SAddr)) {5701      Register PtrBaseOffset = AddrDef->MI->getOperand(2).getReg();5702 5703      // It's possible voffset is an SGPR here, but the copy to VGPR will be5704      // inserted later.5705      bool ScaleOffset = selectScaleOffset(Root, PtrBaseOffset,5706                                           Subtarget->hasSignedGVSOffset());5707      if (Register VOffset = matchExtendFromS32OrS32(5708              PtrBaseOffset, Subtarget->hasSignedGVSOffset())) {5709        if (NeedIOffset)5710          return {{[=](MachineInstrBuilder &MIB) { // saddr5711                     MIB.addReg(SAddr);5712                   },5713                   [=](MachineInstrBuilder &MIB) { // voffset5714                     MIB.addReg(VOffset);5715                   },5716                   [=](MachineInstrBuilder &MIB) { // offset5717                     MIB.addImm(ImmOffset);5718                   },5719                   [=](MachineInstrBuilder &MIB) { // cpol5720                     MIB.addImm(CPolBits |5721                                (ScaleOffset ? AMDGPU::CPol::SCAL : 0));5722                   }}};5723        return {{[=](MachineInstrBuilder &MIB) { // saddr5724                   MIB.addReg(SAddr);5725                 },5726                 [=](MachineInstrBuilder &MIB) { // voffset5727                   MIB.addReg(VOffset);5728                 },5729                 [=](MachineInstrBuilder &MIB) { // cpol5730                   MIB.addImm(CPolBits |5731                              (ScaleOffset ? AMDGPU::CPol::SCAL : 0));5732                 }}};5733      }5734    }5735  }5736 5737  // FIXME: We should probably have folded COPY (G_IMPLICIT_DEF) earlier, and5738  // drop this.5739  if (AddrDef->MI->getOpcode() == AMDGPU::G_IMPLICIT_DEF ||5740      AddrDef->MI->getOpcode() == AMDGPU::G_CONSTANT || !isSGPR(AddrDef->Reg))5741    return std::nullopt;5742 5743  // It's cheaper to materialize a single 32-bit zero for vaddr than the two5744  // moves required to copy a 64-bit SGPR to VGPR.5745  MachineInstr *MI = Root.getParent();5746  MachineBasicBlock *MBB = MI->getParent();5747  Register VOffset = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);5748 5749  BuildMI(*MBB, MI, MI->getDebugLoc(), TII.get(AMDGPU::V_MOV_B32_e32), VOffset)5750      .addImm(0);5751 5752  if (NeedIOffset)5753    return {{5754        [=](MachineInstrBuilder &MIB) { MIB.addReg(AddrDef->Reg); }, // saddr5755        [=](MachineInstrBuilder &MIB) { MIB.addReg(VOffset); },      // voffset5756        [=](MachineInstrBuilder &MIB) { MIB.addImm(ImmOffset); },    // offset5757        [=](MachineInstrBuilder &MIB) { MIB.addImm(CPolBits); }      // cpol5758    }};5759  return {{5760      [=](MachineInstrBuilder &MIB) { MIB.addReg(AddrDef->Reg); }, // saddr5761      [=](MachineInstrBuilder &MIB) { MIB.addReg(VOffset); },      // voffset5762      [=](MachineInstrBuilder &MIB) { MIB.addImm(CPolBits); }      // cpol5763  }};5764}5765 5766InstructionSelector::ComplexRendererFns5767AMDGPUInstructionSelector::selectGlobalSAddr(MachineOperand &Root) const {5768  return selectGlobalSAddr(Root, 0);5769}5770 5771InstructionSelector::ComplexRendererFns5772AMDGPUInstructionSelector::selectGlobalSAddrCPol(MachineOperand &Root) const {5773  const MachineInstr &I = *Root.getParent();5774 5775  // We are assuming CPol is always the last operand of the intrinsic.5776  auto PassedCPol =5777      I.getOperand(I.getNumOperands() - 1).getImm() & ~AMDGPU::CPol::SCAL;5778  return selectGlobalSAddr(Root, PassedCPol);5779}5780 5781InstructionSelector::ComplexRendererFns5782AMDGPUInstructionSelector::selectGlobalSAddrCPolM0(MachineOperand &Root) const {5783  const MachineInstr &I = *Root.getParent();5784 5785  // We are assuming CPol is second from last operand of the intrinsic.5786  auto PassedCPol =5787      I.getOperand(I.getNumOperands() - 2).getImm() & ~AMDGPU::CPol::SCAL;5788  return selectGlobalSAddr(Root, PassedCPol);5789}5790 5791InstructionSelector::ComplexRendererFns5792AMDGPUInstructionSelector::selectGlobalSAddrGLC(MachineOperand &Root) const {5793  return selectGlobalSAddr(Root, AMDGPU::CPol::GLC);5794}5795 5796InstructionSelector::ComplexRendererFns5797AMDGPUInstructionSelector::selectGlobalSAddrNoIOffset(5798    MachineOperand &Root) const {5799  const MachineInstr &I = *Root.getParent();5800 5801  // We are assuming CPol is always the last operand of the intrinsic.5802  auto PassedCPol =5803      I.getOperand(I.getNumOperands() - 1).getImm() & ~AMDGPU::CPol::SCAL;5804  return selectGlobalSAddr(Root, PassedCPol, false);5805}5806 5807InstructionSelector::ComplexRendererFns5808AMDGPUInstructionSelector::selectGlobalSAddrNoIOffsetM0(5809    MachineOperand &Root) const {5810  const MachineInstr &I = *Root.getParent();5811 5812  // We are assuming CPol is second from last operand of the intrinsic.5813  auto PassedCPol =5814      I.getOperand(I.getNumOperands() - 2).getImm() & ~AMDGPU::CPol::SCAL;5815  return selectGlobalSAddr(Root, PassedCPol, false);5816}5817 5818InstructionSelector::ComplexRendererFns5819AMDGPUInstructionSelector::selectScratchSAddr(MachineOperand &Root) const {5820  Register Addr = Root.getReg();5821  Register PtrBase;5822  int64_t ConstOffset;5823  int64_t ImmOffset = 0;5824 5825  // Match the immediate offset first, which canonically is moved as low as5826  // possible.5827  std::tie(PtrBase, ConstOffset, std::ignore) =5828      getPtrBaseWithConstantOffset(Addr, *MRI);5829 5830  if (ConstOffset != 0 && isFlatScratchBaseLegal(Addr) &&5831      TII.isLegalFLATOffset(ConstOffset, AMDGPUAS::PRIVATE_ADDRESS,5832                            SIInstrFlags::FlatScratch)) {5833    Addr = PtrBase;5834    ImmOffset = ConstOffset;5835  }5836 5837  auto AddrDef = getDefSrcRegIgnoringCopies(Addr, *MRI);5838  if (AddrDef->MI->getOpcode() == AMDGPU::G_FRAME_INDEX) {5839    int FI = AddrDef->MI->getOperand(1).getIndex();5840    return {{5841        [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(FI); }, // saddr5842        [=](MachineInstrBuilder &MIB) { MIB.addImm(ImmOffset); } // offset5843    }};5844  }5845 5846  Register SAddr = AddrDef->Reg;5847 5848  if (AddrDef->MI->getOpcode() == AMDGPU::G_PTR_ADD) {5849    Register LHS = AddrDef->MI->getOperand(1).getReg();5850    Register RHS = AddrDef->MI->getOperand(2).getReg();5851    auto LHSDef = getDefSrcRegIgnoringCopies(LHS, *MRI);5852    auto RHSDef = getDefSrcRegIgnoringCopies(RHS, *MRI);5853 5854    if (LHSDef->MI->getOpcode() == AMDGPU::G_FRAME_INDEX &&5855        isSGPR(RHSDef->Reg)) {5856      int FI = LHSDef->MI->getOperand(1).getIndex();5857      MachineInstr &I = *Root.getParent();5858      MachineBasicBlock *BB = I.getParent();5859      const DebugLoc &DL = I.getDebugLoc();5860      SAddr = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);5861 5862      BuildMI(*BB, &I, DL, TII.get(AMDGPU::S_ADD_I32), SAddr)5863          .addFrameIndex(FI)5864          .addReg(RHSDef->Reg)5865          .setOperandDead(3); // Dead scc5866    }5867  }5868 5869  if (!isSGPR(SAddr))5870    return std::nullopt;5871 5872  return {{5873      [=](MachineInstrBuilder &MIB) { MIB.addReg(SAddr); }, // saddr5874      [=](MachineInstrBuilder &MIB) { MIB.addImm(ImmOffset); } // offset5875  }};5876}5877 5878// Check whether the flat scratch SVS swizzle bug affects this access.5879bool AMDGPUInstructionSelector::checkFlatScratchSVSSwizzleBug(5880    Register VAddr, Register SAddr, uint64_t ImmOffset) const {5881  if (!Subtarget->hasFlatScratchSVSSwizzleBug())5882    return false;5883 5884  // The bug affects the swizzling of SVS accesses if there is any carry out5885  // from the two low order bits (i.e. from bit 1 into bit 2) when adding5886  // voffset to (soffset + inst_offset).5887  auto VKnown = VT->getKnownBits(VAddr);5888  auto SKnown = KnownBits::add(VT->getKnownBits(SAddr),5889                               KnownBits::makeConstant(APInt(32, ImmOffset)));5890  uint64_t VMax = VKnown.getMaxValue().getZExtValue();5891  uint64_t SMax = SKnown.getMaxValue().getZExtValue();5892  return (VMax & 3) + (SMax & 3) >= 4;5893}5894 5895InstructionSelector::ComplexRendererFns5896AMDGPUInstructionSelector::selectScratchSVAddr(MachineOperand &Root) const {5897  Register Addr = Root.getReg();5898  Register PtrBase;5899  int64_t ConstOffset;5900  int64_t ImmOffset = 0;5901 5902  // Match the immediate offset first, which canonically is moved as low as5903  // possible.5904  std::tie(PtrBase, ConstOffset, std::ignore) =5905      getPtrBaseWithConstantOffset(Addr, *MRI);5906 5907  Register OrigAddr = Addr;5908  if (ConstOffset != 0 &&5909      TII.isLegalFLATOffset(ConstOffset, AMDGPUAS::PRIVATE_ADDRESS,5910                            SIInstrFlags::FlatScratch)) {5911    Addr = PtrBase;5912    ImmOffset = ConstOffset;5913  }5914 5915  auto AddrDef = getDefSrcRegIgnoringCopies(Addr, *MRI);5916  if (AddrDef->MI->getOpcode() != AMDGPU::G_PTR_ADD)5917    return std::nullopt;5918 5919  Register RHS = AddrDef->MI->getOperand(2).getReg();5920  if (RBI.getRegBank(RHS, *MRI, TRI)->getID() != AMDGPU::VGPRRegBankID)5921    return std::nullopt;5922 5923  Register LHS = AddrDef->MI->getOperand(1).getReg();5924  auto LHSDef = getDefSrcRegIgnoringCopies(LHS, *MRI);5925 5926  if (OrigAddr != Addr) {5927    if (!isFlatScratchBaseLegalSVImm(OrigAddr))5928      return std::nullopt;5929  } else {5930    if (!isFlatScratchBaseLegalSV(OrigAddr))5931      return std::nullopt;5932  }5933 5934  if (checkFlatScratchSVSSwizzleBug(RHS, LHS, ImmOffset))5935    return std::nullopt;5936 5937  unsigned CPol = selectScaleOffset(Root, RHS, true /* IsSigned */)5938                      ? AMDGPU::CPol::SCAL5939                      : 0;5940 5941  if (LHSDef->MI->getOpcode() == AMDGPU::G_FRAME_INDEX) {5942    int FI = LHSDef->MI->getOperand(1).getIndex();5943    return {{5944        [=](MachineInstrBuilder &MIB) { MIB.addReg(RHS); },       // vaddr5945        [=](MachineInstrBuilder &MIB) { MIB.addFrameIndex(FI); }, // saddr5946        [=](MachineInstrBuilder &MIB) { MIB.addImm(ImmOffset); }, // offset5947        [=](MachineInstrBuilder &MIB) { MIB.addImm(CPol); }       // cpol5948    }};5949  }5950 5951  if (!isSGPR(LHS))5952    if (auto Def = getDefSrcRegIgnoringCopies(LHS, *MRI))5953      LHS = Def->Reg;5954 5955  if (!isSGPR(LHS))5956    return std::nullopt;5957 5958  return {{5959      [=](MachineInstrBuilder &MIB) { MIB.addReg(RHS); },       // vaddr5960      [=](MachineInstrBuilder &MIB) { MIB.addReg(LHS); },       // saddr5961      [=](MachineInstrBuilder &MIB) { MIB.addImm(ImmOffset); }, // offset5962      [=](MachineInstrBuilder &MIB) { MIB.addImm(CPol); }       // cpol5963  }};5964}5965 5966InstructionSelector::ComplexRendererFns5967AMDGPUInstructionSelector::selectMUBUFScratchOffen(MachineOperand &Root) const {5968  MachineInstr *MI = Root.getParent();5969  MachineBasicBlock *MBB = MI->getParent();5970  MachineFunction *MF = MBB->getParent();5971  const SIMachineFunctionInfo *Info = MF->getInfo<SIMachineFunctionInfo>();5972 5973  int64_t Offset = 0;5974  if (mi_match(Root.getReg(), *MRI, m_ICst(Offset)) &&5975      Offset != TM.getNullPointerValue(AMDGPUAS::PRIVATE_ADDRESS)) {5976    Register HighBits = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);5977 5978    // TODO: Should this be inside the render function? The iterator seems to5979    // move.5980    const uint32_t MaxOffset = SIInstrInfo::getMaxMUBUFImmOffset(*Subtarget);5981    BuildMI(*MBB, MI, MI->getDebugLoc(), TII.get(AMDGPU::V_MOV_B32_e32),5982            HighBits)5983        .addImm(Offset & ~MaxOffset);5984 5985    return {{[=](MachineInstrBuilder &MIB) { // rsrc5986               MIB.addReg(Info->getScratchRSrcReg());5987             },5988             [=](MachineInstrBuilder &MIB) { // vaddr5989               MIB.addReg(HighBits);5990             },5991             [=](MachineInstrBuilder &MIB) { // soffset5992               // Use constant zero for soffset and rely on eliminateFrameIndex5993               // to choose the appropriate frame register if need be.5994               MIB.addImm(0);5995             },5996             [=](MachineInstrBuilder &MIB) { // offset5997               MIB.addImm(Offset & MaxOffset);5998             }}};5999  }6000 6001  assert(Offset == 0 || Offset == -1);6002 6003  // Try to fold a frame index directly into the MUBUF vaddr field, and any6004  // offsets.6005  std::optional<int> FI;6006  Register VAddr = Root.getReg();6007 6008  const MachineInstr *RootDef = MRI->getVRegDef(Root.getReg());6009  Register PtrBase;6010  int64_t ConstOffset;6011  std::tie(PtrBase, ConstOffset, std::ignore) =6012      getPtrBaseWithConstantOffset(VAddr, *MRI);6013  if (ConstOffset != 0) {6014    if (TII.isLegalMUBUFImmOffset(ConstOffset) &&6015        (!STI.privateMemoryResourceIsRangeChecked() ||6016         VT->signBitIsZero(PtrBase))) {6017      const MachineInstr *PtrBaseDef = MRI->getVRegDef(PtrBase);6018      if (PtrBaseDef->getOpcode() == AMDGPU::G_FRAME_INDEX)6019        FI = PtrBaseDef->getOperand(1).getIndex();6020      else6021        VAddr = PtrBase;6022      Offset = ConstOffset;6023    }6024  } else if (RootDef->getOpcode() == AMDGPU::G_FRAME_INDEX) {6025    FI = RootDef->getOperand(1).getIndex();6026  }6027 6028  return {{[=](MachineInstrBuilder &MIB) { // rsrc6029             MIB.addReg(Info->getScratchRSrcReg());6030           },6031           [=](MachineInstrBuilder &MIB) { // vaddr6032             if (FI)6033               MIB.addFrameIndex(*FI);6034             else6035               MIB.addReg(VAddr);6036           },6037           [=](MachineInstrBuilder &MIB) { // soffset6038             // Use constant zero for soffset and rely on eliminateFrameIndex6039             // to choose the appropriate frame register if need be.6040             MIB.addImm(0);6041           },6042           [=](MachineInstrBuilder &MIB) { // offset6043             MIB.addImm(Offset);6044           }}};6045}6046 6047bool AMDGPUInstructionSelector::isDSOffsetLegal(Register Base,6048                                                int64_t Offset) const {6049  if (!isUInt<16>(Offset))6050    return false;6051 6052  if (STI.hasUsableDSOffset() || STI.unsafeDSOffsetFoldingEnabled())6053    return true;6054 6055  // On Southern Islands instruction with a negative base value and an offset6056  // don't seem to work.6057  return VT->signBitIsZero(Base);6058}6059 6060bool AMDGPUInstructionSelector::isDSOffset2Legal(Register Base, int64_t Offset0,6061                                                 int64_t Offset1,6062                                                 unsigned Size) const {6063  if (Offset0 % Size != 0 || Offset1 % Size != 0)6064    return false;6065  if (!isUInt<8>(Offset0 / Size) || !isUInt<8>(Offset1 / Size))6066    return false;6067 6068  if (STI.hasUsableDSOffset() || STI.unsafeDSOffsetFoldingEnabled())6069    return true;6070 6071  // On Southern Islands instruction with a negative base value and an offset6072  // don't seem to work.6073  return VT->signBitIsZero(Base);6074}6075 6076// Return whether the operation has NoUnsignedWrap property.6077static bool isNoUnsignedWrap(MachineInstr *Addr) {6078  return Addr->getOpcode() == TargetOpcode::G_OR ||6079         (Addr->getOpcode() == TargetOpcode::G_PTR_ADD &&6080          Addr->getFlag(MachineInstr::NoUWrap));6081}6082 6083// Check that the base address of flat scratch load/store in the form of `base +6084// offset` is legal to be put in SGPR/VGPR (i.e. unsigned per hardware6085// requirement). We always treat the first operand as the base address here.6086bool AMDGPUInstructionSelector::isFlatScratchBaseLegal(Register Addr) const {6087  MachineInstr *AddrMI = getDefIgnoringCopies(Addr, *MRI);6088 6089  if (isNoUnsignedWrap(AddrMI))6090    return true;6091 6092  // Starting with GFX12, VADDR and SADDR fields in VSCRATCH can use negative6093  // values.6094  if (STI.hasSignedScratchOffsets())6095    return true;6096 6097  Register LHS = AddrMI->getOperand(1).getReg();6098  Register RHS = AddrMI->getOperand(2).getReg();6099 6100  if (AddrMI->getOpcode() == TargetOpcode::G_PTR_ADD) {6101    std::optional<ValueAndVReg> RhsValReg =6102        getIConstantVRegValWithLookThrough(RHS, *MRI);6103    // If the immediate offset is negative and within certain range, the base6104    // address cannot also be negative. If the base is also negative, the sum6105    // would be either negative or much larger than the valid range of scratch6106    // memory a thread can access.6107    if (RhsValReg && RhsValReg->Value.getSExtValue() < 0 &&6108        RhsValReg->Value.getSExtValue() > -0x40000000)6109      return true;6110  }6111 6112  return VT->signBitIsZero(LHS);6113}6114 6115// Check address value in SGPR/VGPR are legal for flat scratch in the form6116// of: SGPR + VGPR.6117bool AMDGPUInstructionSelector::isFlatScratchBaseLegalSV(Register Addr) const {6118  MachineInstr *AddrMI = getDefIgnoringCopies(Addr, *MRI);6119 6120  if (isNoUnsignedWrap(AddrMI))6121    return true;6122 6123  // Starting with GFX12, VADDR and SADDR fields in VSCRATCH can use negative6124  // values.6125  if (STI.hasSignedScratchOffsets())6126    return true;6127 6128  Register LHS = AddrMI->getOperand(1).getReg();6129  Register RHS = AddrMI->getOperand(2).getReg();6130  return VT->signBitIsZero(RHS) && VT->signBitIsZero(LHS);6131}6132 6133// Check address value in SGPR/VGPR are legal for flat scratch in the form6134// of: SGPR + VGPR + Imm.6135bool AMDGPUInstructionSelector::isFlatScratchBaseLegalSVImm(6136    Register Addr) const {6137  // Starting with GFX12, VADDR and SADDR fields in VSCRATCH can use negative6138  // values.6139  if (STI.hasSignedScratchOffsets())6140    return true;6141 6142  MachineInstr *AddrMI = getDefIgnoringCopies(Addr, *MRI);6143  Register Base = AddrMI->getOperand(1).getReg();6144  std::optional<DefinitionAndSourceRegister> BaseDef =6145      getDefSrcRegIgnoringCopies(Base, *MRI);6146  std::optional<ValueAndVReg> RHSOffset =6147      getIConstantVRegValWithLookThrough(AddrMI->getOperand(2).getReg(), *MRI);6148  assert(RHSOffset);6149 6150  // If the immediate offset is negative and within certain range, the base6151  // address cannot also be negative. If the base is also negative, the sum6152  // would be either negative or much larger than the valid range of scratch6153  // memory a thread can access.6154  if (isNoUnsignedWrap(BaseDef->MI) &&6155      (isNoUnsignedWrap(AddrMI) ||6156       (RHSOffset->Value.getSExtValue() < 0 &&6157        RHSOffset->Value.getSExtValue() > -0x40000000)))6158    return true;6159 6160  Register LHS = BaseDef->MI->getOperand(1).getReg();6161  Register RHS = BaseDef->MI->getOperand(2).getReg();6162  return VT->signBitIsZero(RHS) && VT->signBitIsZero(LHS);6163}6164 6165bool AMDGPUInstructionSelector::isUnneededShiftMask(const MachineInstr &MI,6166                                                    unsigned ShAmtBits) const {6167  assert(MI.getOpcode() == TargetOpcode::G_AND);6168 6169  std::optional<APInt> RHS =6170      getIConstantVRegVal(MI.getOperand(2).getReg(), *MRI);6171  if (!RHS)6172    return false;6173 6174  if (RHS->countr_one() >= ShAmtBits)6175    return true;6176 6177  const APInt &LHSKnownZeros = VT->getKnownZeroes(MI.getOperand(1).getReg());6178  return (LHSKnownZeros | *RHS).countr_one() >= ShAmtBits;6179}6180 6181InstructionSelector::ComplexRendererFns6182AMDGPUInstructionSelector::selectMUBUFScratchOffset(6183    MachineOperand &Root) const {6184  Register Reg = Root.getReg();6185  const SIMachineFunctionInfo *Info = MF->getInfo<SIMachineFunctionInfo>();6186 6187  std::optional<DefinitionAndSourceRegister> Def =6188    getDefSrcRegIgnoringCopies(Reg, *MRI);6189  assert(Def && "this shouldn't be an optional result");6190  Reg = Def->Reg;6191 6192  if (Register WaveBase = getWaveAddress(Def->MI)) {6193    return {{6194        [=](MachineInstrBuilder &MIB) { // rsrc6195          MIB.addReg(Info->getScratchRSrcReg());6196        },6197        [=](MachineInstrBuilder &MIB) { // soffset6198          MIB.addReg(WaveBase);6199        },6200        [=](MachineInstrBuilder &MIB) { MIB.addImm(0); } // offset6201    }};6202  }6203 6204  int64_t Offset = 0;6205 6206  // FIXME: Copy check is a hack6207  Register BasePtr;6208  if (mi_match(Reg, *MRI,6209               m_GPtrAdd(m_Reg(BasePtr),6210                         m_any_of(m_ICst(Offset), m_Copy(m_ICst(Offset)))))) {6211    if (!TII.isLegalMUBUFImmOffset(Offset))6212      return {};6213    MachineInstr *BasePtrDef = getDefIgnoringCopies(BasePtr, *MRI);6214    Register WaveBase = getWaveAddress(BasePtrDef);6215    if (!WaveBase)6216      return {};6217 6218    return {{6219        [=](MachineInstrBuilder &MIB) { // rsrc6220          MIB.addReg(Info->getScratchRSrcReg());6221        },6222        [=](MachineInstrBuilder &MIB) { // soffset6223          MIB.addReg(WaveBase);6224        },6225        [=](MachineInstrBuilder &MIB) { MIB.addImm(Offset); } // offset6226    }};6227  }6228 6229  if (!mi_match(Root.getReg(), *MRI, m_ICst(Offset)) ||6230      !TII.isLegalMUBUFImmOffset(Offset))6231    return {};6232 6233  return {{6234      [=](MachineInstrBuilder &MIB) { // rsrc6235        MIB.addReg(Info->getScratchRSrcReg());6236      },6237      [=](MachineInstrBuilder &MIB) { // soffset6238        MIB.addImm(0);6239      },6240      [=](MachineInstrBuilder &MIB) { MIB.addImm(Offset); } // offset6241  }};6242}6243 6244std::pair<Register, unsigned>6245AMDGPUInstructionSelector::selectDS1Addr1OffsetImpl(MachineOperand &Root) const {6246  const MachineInstr *RootDef = MRI->getVRegDef(Root.getReg());6247  int64_t ConstAddr = 0;6248 6249  Register PtrBase;6250  int64_t Offset;6251  std::tie(PtrBase, Offset, std::ignore) =6252      getPtrBaseWithConstantOffset(Root.getReg(), *MRI);6253 6254  if (Offset) {6255    if (isDSOffsetLegal(PtrBase, Offset)) {6256      // (add n0, c0)6257      return std::pair(PtrBase, Offset);6258    }6259  } else if (RootDef->getOpcode() == AMDGPU::G_SUB) {6260    // TODO6261 6262 6263  } else if (mi_match(Root.getReg(), *MRI, m_ICst(ConstAddr))) {6264    // TODO6265 6266  }6267 6268  return std::pair(Root.getReg(), 0);6269}6270 6271InstructionSelector::ComplexRendererFns6272AMDGPUInstructionSelector::selectDS1Addr1Offset(MachineOperand &Root) const {6273  Register Reg;6274  unsigned Offset;6275  std::tie(Reg, Offset) = selectDS1Addr1OffsetImpl(Root);6276  return {{6277      [=](MachineInstrBuilder &MIB) { MIB.addReg(Reg); },6278      [=](MachineInstrBuilder &MIB) { MIB.addImm(Offset); }6279    }};6280}6281 6282InstructionSelector::ComplexRendererFns6283AMDGPUInstructionSelector::selectDS64Bit4ByteAligned(MachineOperand &Root) const {6284  return selectDSReadWrite2(Root, 4);6285}6286 6287InstructionSelector::ComplexRendererFns6288AMDGPUInstructionSelector::selectDS128Bit8ByteAligned(MachineOperand &Root) const {6289  return selectDSReadWrite2(Root, 8);6290}6291 6292InstructionSelector::ComplexRendererFns6293AMDGPUInstructionSelector::selectDSReadWrite2(MachineOperand &Root,6294                                              unsigned Size) const {6295  Register Reg;6296  unsigned Offset;6297  std::tie(Reg, Offset) = selectDSReadWrite2Impl(Root, Size);6298  return {{6299      [=](MachineInstrBuilder &MIB) { MIB.addReg(Reg); },6300      [=](MachineInstrBuilder &MIB) { MIB.addImm(Offset); },6301      [=](MachineInstrBuilder &MIB) { MIB.addImm(Offset+1); }6302    }};6303}6304 6305std::pair<Register, unsigned>6306AMDGPUInstructionSelector::selectDSReadWrite2Impl(MachineOperand &Root,6307                                                  unsigned Size) const {6308  const MachineInstr *RootDef = MRI->getVRegDef(Root.getReg());6309  int64_t ConstAddr = 0;6310 6311  Register PtrBase;6312  int64_t Offset;6313  std::tie(PtrBase, Offset, std::ignore) =6314      getPtrBaseWithConstantOffset(Root.getReg(), *MRI);6315 6316  if (Offset) {6317    int64_t OffsetValue0 = Offset;6318    int64_t OffsetValue1 = Offset + Size;6319    if (isDSOffset2Legal(PtrBase, OffsetValue0, OffsetValue1, Size)) {6320      // (add n0, c0)6321      return std::pair(PtrBase, OffsetValue0 / Size);6322    }6323  } else if (RootDef->getOpcode() == AMDGPU::G_SUB) {6324    // TODO6325 6326  } else if (mi_match(Root.getReg(), *MRI, m_ICst(ConstAddr))) {6327    // TODO6328 6329  }6330 6331  return std::pair(Root.getReg(), 0);6332}6333 6334/// If \p Root is a G_PTR_ADD with a G_CONSTANT on the right hand side, return6335/// the base value with the constant offset, and if the offset computation is6336/// known to be inbounds. There may be intervening copies between \p Root and6337/// the identified constant. Returns \p Root, 0, false if this does not match6338/// the pattern.6339std::tuple<Register, int64_t, bool>6340AMDGPUInstructionSelector::getPtrBaseWithConstantOffset(6341    Register Root, const MachineRegisterInfo &MRI) const {6342  MachineInstr *RootI = getDefIgnoringCopies(Root, MRI);6343  if (RootI->getOpcode() != TargetOpcode::G_PTR_ADD)6344    return {Root, 0, false};6345 6346  MachineOperand &RHS = RootI->getOperand(2);6347  std::optional<ValueAndVReg> MaybeOffset =6348      getIConstantVRegValWithLookThrough(RHS.getReg(), MRI);6349  if (!MaybeOffset)6350    return {Root, 0, false};6351  bool IsInBounds = RootI->getFlag(MachineInstr::MIFlag::InBounds);6352  return {RootI->getOperand(1).getReg(), MaybeOffset->Value.getSExtValue(),6353          IsInBounds};6354}6355 6356static void addZeroImm(MachineInstrBuilder &MIB) {6357  MIB.addImm(0);6358}6359 6360/// Return a resource descriptor for use with an arbitrary 64-bit pointer. If \p6361/// BasePtr is not valid, a null base pointer will be used.6362static Register buildRSRC(MachineIRBuilder &B, MachineRegisterInfo &MRI,6363                          uint32_t FormatLo, uint32_t FormatHi,6364                          Register BasePtr) {6365  Register RSrc2 = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);6366  Register RSrc3 = MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);6367  Register RSrcHi = MRI.createVirtualRegister(&AMDGPU::SReg_64RegClass);6368  Register RSrc = MRI.createVirtualRegister(&AMDGPU::SGPR_128RegClass);6369 6370  B.buildInstr(AMDGPU::S_MOV_B32)6371    .addDef(RSrc2)6372    .addImm(FormatLo);6373  B.buildInstr(AMDGPU::S_MOV_B32)6374    .addDef(RSrc3)6375    .addImm(FormatHi);6376 6377  // Build the half of the subregister with the constants before building the6378  // full 128-bit register. If we are building multiple resource descriptors,6379  // this will allow CSEing of the 2-component register.6380  B.buildInstr(AMDGPU::REG_SEQUENCE)6381    .addDef(RSrcHi)6382    .addReg(RSrc2)6383    .addImm(AMDGPU::sub0)6384    .addReg(RSrc3)6385    .addImm(AMDGPU::sub1);6386 6387  Register RSrcLo = BasePtr;6388  if (!BasePtr) {6389    RSrcLo = MRI.createVirtualRegister(&AMDGPU::SReg_64RegClass);6390    B.buildInstr(AMDGPU::S_MOV_B64)6391      .addDef(RSrcLo)6392      .addImm(0);6393  }6394 6395  B.buildInstr(AMDGPU::REG_SEQUENCE)6396    .addDef(RSrc)6397    .addReg(RSrcLo)6398    .addImm(AMDGPU::sub0_sub1)6399    .addReg(RSrcHi)6400    .addImm(AMDGPU::sub2_sub3);6401 6402  return RSrc;6403}6404 6405static Register buildAddr64RSrc(MachineIRBuilder &B, MachineRegisterInfo &MRI,6406                                const SIInstrInfo &TII, Register BasePtr) {6407  uint64_t DefaultFormat = TII.getDefaultRsrcDataFormat();6408 6409  // FIXME: Why are half the "default" bits ignored based on the addressing6410  // mode?6411  return buildRSRC(B, MRI, 0, Hi_32(DefaultFormat), BasePtr);6412}6413 6414static Register buildOffsetSrc(MachineIRBuilder &B, MachineRegisterInfo &MRI,6415                               const SIInstrInfo &TII, Register BasePtr) {6416  uint64_t DefaultFormat = TII.getDefaultRsrcDataFormat();6417 6418  // FIXME: Why are half the "default" bits ignored based on the addressing6419  // mode?6420  return buildRSRC(B, MRI, -1, Hi_32(DefaultFormat), BasePtr);6421}6422 6423AMDGPUInstructionSelector::MUBUFAddressData6424AMDGPUInstructionSelector::parseMUBUFAddress(Register Src) const {6425  MUBUFAddressData Data;6426  Data.N0 = Src;6427 6428  Register PtrBase;6429  int64_t Offset;6430 6431  std::tie(PtrBase, Offset, std::ignore) =6432      getPtrBaseWithConstantOffset(Src, *MRI);6433  if (isUInt<32>(Offset)) {6434    Data.N0 = PtrBase;6435    Data.Offset = Offset;6436  }6437 6438  if (MachineInstr *InputAdd6439      = getOpcodeDef(TargetOpcode::G_PTR_ADD, Data.N0, *MRI)) {6440    Data.N2 = InputAdd->getOperand(1).getReg();6441    Data.N3 = InputAdd->getOperand(2).getReg();6442 6443    // FIXME: Need to fix extra SGPR->VGPRcopies inserted6444    // FIXME: Don't know this was defined by operand 06445    //6446    // TODO: Remove this when we have copy folding optimizations after6447    // RegBankSelect.6448    Data.N2 = getDefIgnoringCopies(Data.N2, *MRI)->getOperand(0).getReg();6449    Data.N3 = getDefIgnoringCopies(Data.N3, *MRI)->getOperand(0).getReg();6450  }6451 6452  return Data;6453}6454 6455/// Return if the addr64 mubuf mode should be used for the given address.6456bool AMDGPUInstructionSelector::shouldUseAddr64(MUBUFAddressData Addr) const {6457  // (ptr_add N2, N3) -> addr64, or6458  // (ptr_add (ptr_add N2, N3), C1) -> addr646459  if (Addr.N2)6460    return true;6461 6462  const RegisterBank *N0Bank = RBI.getRegBank(Addr.N0, *MRI, TRI);6463  return N0Bank->getID() == AMDGPU::VGPRRegBankID;6464}6465 6466/// Split an immediate offset \p ImmOffset depending on whether it fits in the6467/// immediate field. Modifies \p ImmOffset and sets \p SOffset to the variable6468/// component.6469void AMDGPUInstructionSelector::splitIllegalMUBUFOffset(6470  MachineIRBuilder &B, Register &SOffset, int64_t &ImmOffset) const {6471  if (TII.isLegalMUBUFImmOffset(ImmOffset))6472    return;6473 6474  // Illegal offset, store it in soffset.6475  SOffset = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);6476  B.buildInstr(AMDGPU::S_MOV_B32)6477    .addDef(SOffset)6478    .addImm(ImmOffset);6479  ImmOffset = 0;6480}6481 6482bool AMDGPUInstructionSelector::selectMUBUFAddr64Impl(6483  MachineOperand &Root, Register &VAddr, Register &RSrcReg,6484  Register &SOffset, int64_t &Offset) const {6485  // FIXME: Predicates should stop this from reaching here.6486  // addr64 bit was removed for volcanic islands.6487  if (!STI.hasAddr64() || STI.useFlatForGlobal())6488    return false;6489 6490  MUBUFAddressData AddrData = parseMUBUFAddress(Root.getReg());6491  if (!shouldUseAddr64(AddrData))6492    return false;6493 6494  Register N0 = AddrData.N0;6495  Register N2 = AddrData.N2;6496  Register N3 = AddrData.N3;6497  Offset = AddrData.Offset;6498 6499  // Base pointer for the SRD.6500  Register SRDPtr;6501 6502  if (N2) {6503    if (RBI.getRegBank(N2, *MRI, TRI)->getID() == AMDGPU::VGPRRegBankID) {6504      assert(N3);6505      if (RBI.getRegBank(N3, *MRI, TRI)->getID() == AMDGPU::VGPRRegBankID) {6506        // Both N2 and N3 are divergent. Use N0 (the result of the add) as the6507        // addr64, and construct the default resource from a 0 address.6508        VAddr = N0;6509      } else {6510        SRDPtr = N3;6511        VAddr = N2;6512      }6513    } else {6514      // N2 is not divergent.6515      SRDPtr = N2;6516      VAddr = N3;6517    }6518  } else if (RBI.getRegBank(N0, *MRI, TRI)->getID() == AMDGPU::VGPRRegBankID) {6519    // Use the default null pointer in the resource6520    VAddr = N0;6521  } else {6522    // N0 -> offset, or6523    // (N0 + C1) -> offset6524    SRDPtr = N0;6525  }6526 6527  MachineIRBuilder B(*Root.getParent());6528  RSrcReg = buildAddr64RSrc(B, *MRI, TII, SRDPtr);6529  splitIllegalMUBUFOffset(B, SOffset, Offset);6530  return true;6531}6532 6533bool AMDGPUInstructionSelector::selectMUBUFOffsetImpl(6534  MachineOperand &Root, Register &RSrcReg, Register &SOffset,6535  int64_t &Offset) const {6536 6537  // FIXME: Pattern should not reach here.6538  if (STI.useFlatForGlobal())6539    return false;6540 6541  MUBUFAddressData AddrData = parseMUBUFAddress(Root.getReg());6542  if (shouldUseAddr64(AddrData))6543    return false;6544 6545  // N0 -> offset, or6546  // (N0 + C1) -> offset6547  Register SRDPtr = AddrData.N0;6548  Offset = AddrData.Offset;6549 6550  // TODO: Look through extensions for 32-bit soffset.6551  MachineIRBuilder B(*Root.getParent());6552 6553  RSrcReg = buildOffsetSrc(B, *MRI, TII, SRDPtr);6554  splitIllegalMUBUFOffset(B, SOffset, Offset);6555  return true;6556}6557 6558InstructionSelector::ComplexRendererFns6559AMDGPUInstructionSelector::selectMUBUFAddr64(MachineOperand &Root) const {6560  Register VAddr;6561  Register RSrcReg;6562  Register SOffset;6563  int64_t Offset = 0;6564 6565  if (!selectMUBUFAddr64Impl(Root, VAddr, RSrcReg, SOffset, Offset))6566    return {};6567 6568  // FIXME: Use defaulted operands for trailing 0s and remove from the complex6569  // pattern.6570  return {{6571      [=](MachineInstrBuilder &MIB) {  // rsrc6572        MIB.addReg(RSrcReg);6573      },6574      [=](MachineInstrBuilder &MIB) { // vaddr6575        MIB.addReg(VAddr);6576      },6577      [=](MachineInstrBuilder &MIB) { // soffset6578        if (SOffset)6579          MIB.addReg(SOffset);6580        else if (STI.hasRestrictedSOffset())6581          MIB.addReg(AMDGPU::SGPR_NULL);6582        else6583          MIB.addImm(0);6584      },6585      [=](MachineInstrBuilder &MIB) { // offset6586        MIB.addImm(Offset);6587      },6588      addZeroImm, //  cpol6589      addZeroImm, //  tfe6590      addZeroImm  //  swz6591    }};6592}6593 6594InstructionSelector::ComplexRendererFns6595AMDGPUInstructionSelector::selectMUBUFOffset(MachineOperand &Root) const {6596  Register RSrcReg;6597  Register SOffset;6598  int64_t Offset = 0;6599 6600  if (!selectMUBUFOffsetImpl(Root, RSrcReg, SOffset, Offset))6601    return {};6602 6603  return {{6604      [=](MachineInstrBuilder &MIB) {  // rsrc6605        MIB.addReg(RSrcReg);6606      },6607      [=](MachineInstrBuilder &MIB) { // soffset6608        if (SOffset)6609          MIB.addReg(SOffset);6610        else if (STI.hasRestrictedSOffset())6611          MIB.addReg(AMDGPU::SGPR_NULL);6612        else6613          MIB.addImm(0);6614      },6615      [=](MachineInstrBuilder &MIB) { MIB.addImm(Offset); }, // offset6616      addZeroImm, //  cpol6617      addZeroImm, //  tfe6618      addZeroImm, //  swz6619    }};6620}6621 6622InstructionSelector::ComplexRendererFns6623AMDGPUInstructionSelector::selectBUFSOffset(MachineOperand &Root) const {6624 6625  Register SOffset = Root.getReg();6626 6627  if (STI.hasRestrictedSOffset() && mi_match(SOffset, *MRI, m_ZeroInt()))6628    SOffset = AMDGPU::SGPR_NULL;6629 6630  return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(SOffset); }}};6631}6632 6633/// Get an immediate that must be 32-bits, and treated as zero extended.6634static std::optional<uint64_t>6635getConstantZext32Val(Register Reg, const MachineRegisterInfo &MRI) {6636  // getIConstantVRegVal sexts any values, so see if that matters.6637  std::optional<int64_t> OffsetVal = getIConstantVRegSExtVal(Reg, MRI);6638  if (!OffsetVal || !isInt<32>(*OffsetVal))6639    return std::nullopt;6640  return Lo_32(*OffsetVal);6641}6642 6643InstructionSelector::ComplexRendererFns6644AMDGPUInstructionSelector::selectSMRDBufferImm(MachineOperand &Root) const {6645  std::optional<uint64_t> OffsetVal =6646      Root.isImm() ? Root.getImm() : getConstantZext32Val(Root.getReg(), *MRI);6647  if (!OffsetVal)6648    return {};6649 6650  std::optional<int64_t> EncodedImm =6651      AMDGPU::getSMRDEncodedOffset(STI, *OffsetVal, true);6652  if (!EncodedImm)6653    return {};6654 6655  return {{ [=](MachineInstrBuilder &MIB) { MIB.addImm(*EncodedImm); }  }};6656}6657 6658InstructionSelector::ComplexRendererFns6659AMDGPUInstructionSelector::selectSMRDBufferImm32(MachineOperand &Root) const {6660  assert(STI.getGeneration() == AMDGPUSubtarget::SEA_ISLANDS);6661 6662  std::optional<uint64_t> OffsetVal = getConstantZext32Val(Root.getReg(), *MRI);6663  if (!OffsetVal)6664    return {};6665 6666  std::optional<int64_t> EncodedImm =6667      AMDGPU::getSMRDEncodedLiteralOffset32(STI, *OffsetVal);6668  if (!EncodedImm)6669    return {};6670 6671  return {{ [=](MachineInstrBuilder &MIB) { MIB.addImm(*EncodedImm); }  }};6672}6673 6674InstructionSelector::ComplexRendererFns6675AMDGPUInstructionSelector::selectSMRDBufferSgprImm(MachineOperand &Root) const {6676  // Match the (soffset + offset) pair as a 32-bit register base and6677  // an immediate offset.6678  Register SOffset;6679  unsigned Offset;6680  std::tie(SOffset, Offset) = AMDGPU::getBaseWithConstantOffset(6681      *MRI, Root.getReg(), VT, /*CheckNUW*/ true);6682  if (!SOffset)6683    return std::nullopt;6684 6685  std::optional<int64_t> EncodedOffset =6686      AMDGPU::getSMRDEncodedOffset(STI, Offset, /* IsBuffer */ true);6687  if (!EncodedOffset)6688    return std::nullopt;6689 6690  assert(MRI->getType(SOffset) == LLT::scalar(32));6691  return {{[=](MachineInstrBuilder &MIB) { MIB.addReg(SOffset); },6692           [=](MachineInstrBuilder &MIB) { MIB.addImm(*EncodedOffset); }}};6693}6694 6695std::pair<Register, unsigned>6696AMDGPUInstructionSelector::selectVOP3PMadMixModsImpl(MachineOperand &Root,6697                                                     bool &Matched) const {6698  Matched = false;6699 6700  Register Src;6701  unsigned Mods;6702  std::tie(Src, Mods) = selectVOP3ModsImpl(Root.getReg());6703 6704  if (mi_match(Src, *MRI, m_GFPExt(m_Reg(Src)))) {6705    assert(MRI->getType(Src) == LLT::scalar(16));6706 6707    // Only change Src if src modifier could be gained. In such cases new Src6708    // could be sgpr but this does not violate constant bus restriction for6709    // instruction that is being selected.6710    Src = stripBitCast(Src, *MRI);6711 6712    const auto CheckAbsNeg = [&]() {6713      // Be careful about folding modifiers if we already have an abs. fneg is6714      // applied last, so we don't want to apply an earlier fneg.6715      if ((Mods & SISrcMods::ABS) == 0) {6716        unsigned ModsTmp;6717        std::tie(Src, ModsTmp) = selectVOP3ModsImpl(Src);6718 6719        if ((ModsTmp & SISrcMods::NEG) != 0)6720          Mods ^= SISrcMods::NEG;6721 6722        if ((ModsTmp & SISrcMods::ABS) != 0)6723          Mods |= SISrcMods::ABS;6724      }6725    };6726 6727    CheckAbsNeg();6728 6729    // op_sel/op_sel_hi decide the source type and source.6730    // If the source's op_sel_hi is set, it indicates to do a conversion from6731    // fp16. If the sources's op_sel is set, it picks the high half of the6732    // source register.6733 6734    Mods |= SISrcMods::OP_SEL_1;6735 6736    if (isExtractHiElt(*MRI, Src, Src)) {6737      Mods |= SISrcMods::OP_SEL_0;6738      CheckAbsNeg();6739    }6740 6741    Matched = true;6742  }6743 6744  return {Src, Mods};6745}6746 6747InstructionSelector::ComplexRendererFns6748AMDGPUInstructionSelector::selectVOP3PMadMixModsExt(6749    MachineOperand &Root) const {6750  Register Src;6751  unsigned Mods;6752  bool Matched;6753  std::tie(Src, Mods) = selectVOP3PMadMixModsImpl(Root, Matched);6754  if (!Matched)6755    return {};6756 6757  return {{6758      [=](MachineInstrBuilder &MIB) { MIB.addReg(Src); },6759      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); } // src_mods6760  }};6761}6762 6763InstructionSelector::ComplexRendererFns6764AMDGPUInstructionSelector::selectVOP3PMadMixMods(MachineOperand &Root) const {6765  Register Src;6766  unsigned Mods;6767  bool Matched;6768  std::tie(Src, Mods) = selectVOP3PMadMixModsImpl(Root, Matched);6769 6770  return {{6771      [=](MachineInstrBuilder &MIB) { MIB.addReg(Src); },6772      [=](MachineInstrBuilder &MIB) { MIB.addImm(Mods); } // src_mods6773  }};6774}6775 6776bool AMDGPUInstructionSelector::selectSBarrierSignalIsfirst(6777    MachineInstr &I, Intrinsic::ID IntrID) const {6778  MachineBasicBlock *MBB = I.getParent();6779  const DebugLoc &DL = I.getDebugLoc();6780  Register CCReg = I.getOperand(0).getReg();6781 6782  // Set SCC to true, in case the barrier instruction gets converted to a NOP.6783  BuildMI(*MBB, &I, DL, TII.get(AMDGPU::S_CMP_EQ_U32)).addImm(0).addImm(0);6784 6785  BuildMI(*MBB, &I, DL, TII.get(AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM))6786      .addImm(I.getOperand(2).getImm());6787 6788  BuildMI(*MBB, &I, DL, TII.get(AMDGPU::COPY), CCReg).addReg(AMDGPU::SCC);6789 6790  I.eraseFromParent();6791  return RBI.constrainGenericRegister(CCReg, AMDGPU::SReg_32_XM0_XEXECRegClass,6792                                      *MRI);6793}6794 6795bool AMDGPUInstructionSelector::selectSGetBarrierState(6796    MachineInstr &I, Intrinsic::ID IntrID) const {6797  MachineBasicBlock *MBB = I.getParent();6798  const DebugLoc &DL = I.getDebugLoc();6799  const MachineOperand &BarOp = I.getOperand(2);6800  std::optional<int64_t> BarValImm =6801      getIConstantVRegSExtVal(BarOp.getReg(), *MRI);6802 6803  if (!BarValImm) {6804    auto CopyMIB = BuildMI(*MBB, &I, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)6805                       .addReg(BarOp.getReg());6806    constrainSelectedInstRegOperands(*CopyMIB, TII, TRI, RBI);6807  }6808  MachineInstrBuilder MIB;6809  unsigned Opc = BarValImm ? AMDGPU::S_GET_BARRIER_STATE_IMM6810                           : AMDGPU::S_GET_BARRIER_STATE_M0;6811  MIB = BuildMI(*MBB, &I, DL, TII.get(Opc));6812 6813  auto DstReg = I.getOperand(0).getReg();6814  const TargetRegisterClass *DstRC =6815      TRI.getConstrainedRegClassForOperand(I.getOperand(0), *MRI);6816  if (!DstRC || !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))6817    return false;6818  MIB.addDef(DstReg);6819  if (BarValImm) {6820    MIB.addImm(*BarValImm);6821  }6822  I.eraseFromParent();6823  return true;6824}6825 6826unsigned getNamedBarrierOp(bool HasInlineConst, Intrinsic::ID IntrID) {6827  if (HasInlineConst) {6828    switch (IntrID) {6829    default:6830      llvm_unreachable("not a named barrier op");6831    case Intrinsic::amdgcn_s_barrier_join:6832      return AMDGPU::S_BARRIER_JOIN_IMM;6833    case Intrinsic::amdgcn_s_get_named_barrier_state:6834      return AMDGPU::S_GET_BARRIER_STATE_IMM;6835    };6836  } else {6837    switch (IntrID) {6838    default:6839      llvm_unreachable("not a named barrier op");6840    case Intrinsic::amdgcn_s_barrier_join:6841      return AMDGPU::S_BARRIER_JOIN_M0;6842    case Intrinsic::amdgcn_s_get_named_barrier_state:6843      return AMDGPU::S_GET_BARRIER_STATE_M0;6844    };6845  }6846}6847 6848bool AMDGPUInstructionSelector::selectNamedBarrierInit(6849    MachineInstr &I, Intrinsic::ID IntrID) const {6850  MachineBasicBlock *MBB = I.getParent();6851  const DebugLoc &DL = I.getDebugLoc();6852  const MachineOperand &BarOp = I.getOperand(1);6853  const MachineOperand &CntOp = I.getOperand(2);6854 6855  // BarID = (BarOp >> 4) & 0x3F6856  Register TmpReg0 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);6857  BuildMI(*MBB, &I, DL, TII.get(AMDGPU::S_LSHR_B32), TmpReg0)6858      .add(BarOp)6859      .addImm(4u)6860      .setOperandDead(3); // Dead scc6861 6862  Register TmpReg1 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);6863  BuildMI(*MBB, &I, DL, TII.get(AMDGPU::S_AND_B32), TmpReg1)6864      .addReg(TmpReg0)6865      .addImm(0x3F)6866      .setOperandDead(3); // Dead scc6867 6868  // MO = ((CntOp & 0x3F) << shAmt) | BarID6869  Register TmpReg2 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);6870  BuildMI(*MBB, &I, DL, TII.get(AMDGPU::S_AND_B32), TmpReg2)6871      .add(CntOp)6872      .addImm(0x3F)6873      .setOperandDead(3); // Dead scc6874 6875  Register TmpReg3 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);6876  constexpr unsigned ShAmt = 16;6877  BuildMI(*MBB, &I, DL, TII.get(AMDGPU::S_LSHL_B32), TmpReg3)6878      .addReg(TmpReg2)6879      .addImm(ShAmt)6880      .setOperandDead(3); // Dead scc6881 6882  Register TmpReg4 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);6883  BuildMI(*MBB, &I, DL, TII.get(AMDGPU::S_OR_B32), TmpReg4)6884      .addReg(TmpReg1)6885      .addReg(TmpReg3)6886      .setOperandDead(3); // Dead scc;6887 6888  auto CopyMIB =6889      BuildMI(*MBB, &I, DL, TII.get(AMDGPU::COPY), AMDGPU::M0).addReg(TmpReg4);6890  constrainSelectedInstRegOperands(*CopyMIB, TII, TRI, RBI);6891 6892  unsigned Opc = IntrID == Intrinsic::amdgcn_s_barrier_init6893                     ? AMDGPU::S_BARRIER_INIT_M06894                     : AMDGPU::S_BARRIER_SIGNAL_M0;6895  MachineInstrBuilder MIB;6896  MIB = BuildMI(*MBB, &I, DL, TII.get(Opc));6897 6898  I.eraseFromParent();6899  return true;6900}6901 6902bool AMDGPUInstructionSelector::selectNamedBarrierInst(6903    MachineInstr &I, Intrinsic::ID IntrID) const {6904  MachineBasicBlock *MBB = I.getParent();6905  const DebugLoc &DL = I.getDebugLoc();6906  MachineOperand BarOp = IntrID == Intrinsic::amdgcn_s_get_named_barrier_state6907                             ? I.getOperand(2)6908                             : I.getOperand(1);6909  std::optional<int64_t> BarValImm =6910      getIConstantVRegSExtVal(BarOp.getReg(), *MRI);6911 6912  if (!BarValImm) {6913    // BarID = (BarOp >> 4) & 0x3F6914    Register TmpReg0 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);6915    BuildMI(*MBB, &I, DL, TII.get(AMDGPU::S_LSHR_B32), TmpReg0)6916        .addReg(BarOp.getReg())6917        .addImm(4u)6918        .setOperandDead(3); // Dead scc;6919 6920    Register TmpReg1 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);6921    BuildMI(*MBB, &I, DL, TII.get(AMDGPU::S_AND_B32), TmpReg1)6922        .addReg(TmpReg0)6923        .addImm(0x3F)6924        .setOperandDead(3); // Dead scc;6925 6926    auto CopyMIB = BuildMI(*MBB, &I, DL, TII.get(AMDGPU::COPY), AMDGPU::M0)6927                       .addReg(TmpReg1);6928    constrainSelectedInstRegOperands(*CopyMIB, TII, TRI, RBI);6929  }6930 6931  MachineInstrBuilder MIB;6932  unsigned Opc = getNamedBarrierOp(BarValImm.has_value(), IntrID);6933  MIB = BuildMI(*MBB, &I, DL, TII.get(Opc));6934 6935  if (IntrID == Intrinsic::amdgcn_s_get_named_barrier_state) {6936    auto DstReg = I.getOperand(0).getReg();6937    const TargetRegisterClass *DstRC =6938        TRI.getConstrainedRegClassForOperand(I.getOperand(0), *MRI);6939    if (!DstRC || !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))6940      return false;6941    MIB.addDef(DstReg);6942  }6943 6944  if (BarValImm) {6945    auto BarId = ((*BarValImm) >> 4) & 0x3F;6946    MIB.addImm(BarId);6947  }6948 6949  I.eraseFromParent();6950  return true;6951}6952 6953void AMDGPUInstructionSelector::renderTruncImm32(MachineInstrBuilder &MIB,6954                                                 const MachineInstr &MI,6955                                                 int OpIdx) const {6956  assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&6957         "Expected G_CONSTANT");6958  MIB.addImm(MI.getOperand(1).getCImm()->getSExtValue());6959}6960 6961void AMDGPUInstructionSelector::renderNegateImm(MachineInstrBuilder &MIB,6962                                                const MachineInstr &MI,6963                                                int OpIdx) const {6964  assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&6965         "Expected G_CONSTANT");6966  MIB.addImm(-MI.getOperand(1).getCImm()->getSExtValue());6967}6968 6969void AMDGPUInstructionSelector::renderBitcastFPImm(MachineInstrBuilder &MIB,6970                                                   const MachineInstr &MI,6971                                                   int OpIdx) const {6972  const MachineOperand &Op = MI.getOperand(1);6973  assert(MI.getOpcode() == TargetOpcode::G_FCONSTANT && OpIdx == -1);6974  MIB.addImm(Op.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());6975}6976 6977void AMDGPUInstructionSelector::renderPopcntImm(MachineInstrBuilder &MIB,6978                                                const MachineInstr &MI,6979                                                int OpIdx) const {6980  assert(MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&6981         "Expected G_CONSTANT");6982  MIB.addImm(MI.getOperand(1).getCImm()->getValue().popcount());6983}6984 6985/// This only really exists to satisfy DAG type checking machinery, so is a6986/// no-op here.6987void AMDGPUInstructionSelector::renderTruncTImm(MachineInstrBuilder &MIB,6988                                                const MachineInstr &MI,6989                                                int OpIdx) const {6990  const MachineOperand &Op = MI.getOperand(OpIdx);6991  int64_t Imm;6992  if (Op.isReg() && mi_match(Op.getReg(), *MRI, m_ICst(Imm)))6993    MIB.addImm(Imm);6994  else6995    MIB.addImm(Op.getImm());6996}6997 6998void AMDGPUInstructionSelector::renderZextBoolTImm(MachineInstrBuilder &MIB,6999                                                   const MachineInstr &MI,7000                                                   int OpIdx) const {7001  MIB.addImm(MI.getOperand(OpIdx).getImm() != 0);7002}7003 7004void AMDGPUInstructionSelector::renderOpSelTImm(MachineInstrBuilder &MIB,7005                                                const MachineInstr &MI,7006                                                int OpIdx) const {7007  assert(OpIdx >= 0 && "expected to match an immediate operand");7008  MIB.addImm(MI.getOperand(OpIdx).getImm() ? (int64_t)SISrcMods::OP_SEL_0 : 0);7009}7010 7011void AMDGPUInstructionSelector::renderSrcAndDstSelToOpSelXForm_0_0(7012    MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {7013  assert(OpIdx >= 0 && "expected to match an immediate operand");7014  MIB.addImm(7015      (MI.getOperand(OpIdx).getImm() & 0x1) ? (int64_t)SISrcMods::OP_SEL_0 : 0);7016}7017 7018void AMDGPUInstructionSelector::renderSrcAndDstSelToOpSelXForm_0_1(7019    MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {7020  assert(OpIdx >= 0 && "expected to match an immediate operand");7021  MIB.addImm((MI.getOperand(OpIdx).getImm() & 0x1)7022                 ? (int64_t)(SISrcMods::OP_SEL_0 | SISrcMods::DST_OP_SEL)7023                 : (int64_t)SISrcMods::DST_OP_SEL);7024}7025 7026void AMDGPUInstructionSelector::renderSrcAndDstSelToOpSelXForm_1_0(7027    MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {7028  assert(OpIdx >= 0 && "expected to match an immediate operand");7029  MIB.addImm(7030      (MI.getOperand(OpIdx).getImm() & 0x2) ? (int64_t)SISrcMods::OP_SEL_0 : 0);7031}7032 7033void AMDGPUInstructionSelector::renderSrcAndDstSelToOpSelXForm_1_1(7034    MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {7035  assert(OpIdx >= 0 && "expected to match an immediate operand");7036  MIB.addImm((MI.getOperand(OpIdx).getImm() & 0x2)7037                 ? (int64_t)(SISrcMods::OP_SEL_0)7038                 : 0);7039}7040 7041void AMDGPUInstructionSelector::renderDstSelToOpSelXForm(7042    MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {7043  assert(OpIdx >= 0 && "expected to match an immediate operand");7044  MIB.addImm(MI.getOperand(OpIdx).getImm() ? (int64_t)(SISrcMods::DST_OP_SEL)7045                                           : 0);7046}7047 7048void AMDGPUInstructionSelector::renderSrcSelToOpSelXForm(7049    MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {7050  assert(OpIdx >= 0 && "expected to match an immediate operand");7051  MIB.addImm(MI.getOperand(OpIdx).getImm() ? (int64_t)(SISrcMods::OP_SEL_0)7052                                           : 0);7053}7054 7055void AMDGPUInstructionSelector::renderSrcAndDstSelToOpSelXForm_2_0(7056    MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {7057  assert(OpIdx >= 0 && "expected to match an immediate operand");7058  MIB.addImm(7059      (MI.getOperand(OpIdx).getImm() & 0x1) ? (int64_t)SISrcMods::OP_SEL_0 : 0);7060}7061 7062void AMDGPUInstructionSelector::renderDstSelToOpSel3XFormXForm(7063    MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {7064  assert(OpIdx >= 0 && "expected to match an immediate operand");7065  MIB.addImm((MI.getOperand(OpIdx).getImm() & 0x2)7066                 ? (int64_t)SISrcMods::DST_OP_SEL7067                 : 0);7068}7069 7070void AMDGPUInstructionSelector::renderExtractCPol(MachineInstrBuilder &MIB,7071                                                  const MachineInstr &MI,7072                                                  int OpIdx) const {7073  assert(OpIdx >= 0 && "expected to match an immediate operand");7074  MIB.addImm(MI.getOperand(OpIdx).getImm() &7075             (AMDGPU::isGFX12Plus(STI) ? AMDGPU::CPol::ALL7076                                       : AMDGPU::CPol::ALL_pregfx12));7077}7078 7079void AMDGPUInstructionSelector::renderExtractSWZ(MachineInstrBuilder &MIB,7080                                                 const MachineInstr &MI,7081                                                 int OpIdx) const {7082  assert(OpIdx >= 0 && "expected to match an immediate operand");7083  const bool Swizzle = MI.getOperand(OpIdx).getImm() &7084                       (AMDGPU::isGFX12Plus(STI) ? AMDGPU::CPol::SWZ7085                                                 : AMDGPU::CPol::SWZ_pregfx12);7086  MIB.addImm(Swizzle);7087}7088 7089void AMDGPUInstructionSelector::renderExtractCpolSetGLC(7090    MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {7091  assert(OpIdx >= 0 && "expected to match an immediate operand");7092  const uint32_t Cpol = MI.getOperand(OpIdx).getImm() &7093                        (AMDGPU::isGFX12Plus(STI) ? AMDGPU::CPol::ALL7094                                                  : AMDGPU::CPol::ALL_pregfx12);7095  MIB.addImm(Cpol | AMDGPU::CPol::GLC);7096}7097 7098void AMDGPUInstructionSelector::renderFrameIndex(MachineInstrBuilder &MIB,7099                                                 const MachineInstr &MI,7100                                                 int OpIdx) const {7101  MIB.addFrameIndex(MI.getOperand(1).getIndex());7102}7103 7104void AMDGPUInstructionSelector::renderFPPow2ToExponent(MachineInstrBuilder &MIB,7105                                                       const MachineInstr &MI,7106                                                       int OpIdx) const {7107  const APFloat &APF = MI.getOperand(1).getFPImm()->getValueAPF();7108  int ExpVal = APF.getExactLog2Abs();7109  assert(ExpVal != INT_MIN);7110  MIB.addImm(ExpVal);7111}7112 7113void AMDGPUInstructionSelector::renderRoundMode(MachineInstrBuilder &MIB,7114                                                const MachineInstr &MI,7115                                                int OpIdx) const {7116  // "round.towardzero" -> TowardZero 0        -> FP_ROUND_ROUND_TO_ZERO 37117  // "round.tonearest"  -> NearestTiesToEven 1 -> FP_ROUND_ROUND_TO_NEAREST 07118  // "round.upward"     -> TowardPositive 2    -> FP_ROUND_ROUND_TO_INF 17119  // "round.downward    -> TowardNegative 3    -> FP_ROUND_ROUND_TO_NEGINF 27120  MIB.addImm((MI.getOperand(OpIdx).getImm() + 3) % 4);7121}7122 7123void AMDGPUInstructionSelector::renderVOP3PModsNeg(MachineInstrBuilder &MIB,7124                                                   const MachineInstr &MI,7125                                                   int OpIdx) const {7126  unsigned Mods = SISrcMods::OP_SEL_1;7127  if (MI.getOperand(OpIdx).getImm())7128    Mods ^= SISrcMods::NEG;7129  MIB.addImm((int64_t)Mods);7130}7131 7132void AMDGPUInstructionSelector::renderVOP3PModsNegs(MachineInstrBuilder &MIB,7133                                                    const MachineInstr &MI,7134                                                    int OpIdx) const {7135  unsigned Mods = SISrcMods::OP_SEL_1;7136  if (MI.getOperand(OpIdx).getImm())7137    Mods ^= (SISrcMods::NEG | SISrcMods::NEG_HI);7138  MIB.addImm((int64_t)Mods);7139}7140 7141void AMDGPUInstructionSelector::renderVOP3PModsNegAbs(MachineInstrBuilder &MIB,7142                                                      const MachineInstr &MI,7143                                                      int OpIdx) const {7144  unsigned Val = MI.getOperand(OpIdx).getImm();7145  unsigned Mods = SISrcMods::OP_SEL_1; // default: none7146  if (Val == 1) // neg7147    Mods ^= SISrcMods::NEG;7148  if (Val == 2) // abs7149    Mods ^= SISrcMods::ABS;7150  if (Val == 3) // neg and abs7151    Mods ^= (SISrcMods::NEG | SISrcMods::ABS);7152  MIB.addImm((int64_t)Mods);7153}7154 7155void AMDGPUInstructionSelector::renderPrefetchLoc(MachineInstrBuilder &MIB,7156                                                  const MachineInstr &MI,7157                                                  int OpIdx) const {7158  uint32_t V = MI.getOperand(2).getImm();7159  V = (AMDGPU::CPol::SCOPE_MASK - (V & AMDGPU::CPol::SCOPE_MASK))7160      << AMDGPU::CPol::SCOPE_SHIFT;7161  if (!Subtarget->hasSafeCUPrefetch())7162    V = std::max(V, (uint32_t)AMDGPU::CPol::SCOPE_SE); // CU scope is unsafe7163  MIB.addImm(V);7164}7165 7166/// Convert from 2-bit value to enum values used for op_sel* source modifiers.7167void AMDGPUInstructionSelector::renderScaledMAIIntrinsicOperand(7168    MachineInstrBuilder &MIB, const MachineInstr &MI, int OpIdx) const {7169  unsigned Val = MI.getOperand(OpIdx).getImm();7170  unsigned New = 0;7171  if (Val & 0x1)7172    New |= SISrcMods::OP_SEL_0;7173  if (Val & 0x2)7174    New |= SISrcMods::OP_SEL_1;7175  MIB.addImm(New);7176}7177 7178bool AMDGPUInstructionSelector::isInlineImmediate(const APInt &Imm) const {7179  return TII.isInlineConstant(Imm);7180}7181 7182bool AMDGPUInstructionSelector::isInlineImmediate(const APFloat &Imm) const {7183  return TII.isInlineConstant(Imm);7184}7185