28#include "llvm/IR/IntrinsicsAMDGPU.h"
31#define DEBUG_TYPE "amdgpu-isel"
36#define GET_GLOBALISEL_IMPL
37#define AMDGPUSubtarget GCNSubtarget
38#include "AMDGPUGenGlobalISel.inc"
39#undef GET_GLOBALISEL_IMPL
44 : TII(*STI.getInstrInfo()), TRI(*STI.getRegisterInfo()), RBI(RBI), STI(STI),
46#include
"AMDGPUGenGlobalISel.inc"
49#include
"AMDGPUGenGlobalISel.inc"
61 MRI = &
MF.getRegInfo();
69 return Def->getOpcode() == AMDGPU::G_AMDGPU_WAVE_ADDRESS
70 ? Def->getOperand(1).getReg()
80 auto &RegClassOrBank = MRI.getRegClassOrRegBank(
Reg);
84 const LLT Ty = MRI.getType(
Reg);
93 return RB->
getID() == AMDGPU::VCCRegBankID;
96bool AMDGPUInstructionSelector::constrainCopyLikeIntrin(
MachineInstr &
MI,
97 unsigned NewOpc)
const {
98 MI.setDesc(TII.get(NewOpc));
110 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
112 TRI.getConstrainedRegClassForReg(SrcReg, *MRI);
113 if (!DstRC || DstRC != SrcRC)
116 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI) ||
117 !RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI))
119 const MCInstrDesc &MCID =
MI.getDesc();
121 MI.getOperand(0).setIsEarlyClobber(
true);
126bool AMDGPUInstructionSelector::selectCOPY(
MachineInstr &
I)
const {
129 I.setDesc(TII.get(TargetOpcode::COPY));
131 Register DstReg =
I.getOperand(0).getReg();
132 Register SrcReg =
I.getOperand(1).getReg();
134 if (isVCC(DstReg, *MRI)) {
135 if (SrcReg == AMDGPU::SCC) {
137 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
140 return RBI.constrainGenericRegister(DstReg, *RC, *MRI);
143 if (!isVCC(SrcReg, *MRI)) {
145 if (!RBI.constrainGenericRegister(DstReg, *TRI.getBoolRC(), *MRI))
149 TRI.getConstrainedRegClassForReg(SrcReg, *MRI);
151 std::optional<ValueAndVReg> ConstVal =
155 STI.isWave64() ? AMDGPU::S_MOV_B64 : AMDGPU::S_MOV_B32;
157 .
addImm(ConstVal->Value.getBoolValue() ? -1 : 0);
159 Register MaskedReg = MRI->createVirtualRegister(SrcRC);
166 assert(Subtarget->useRealTrue16Insts());
167 const int64_t NoMods = 0;
168 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::V_AND_B16_t16_e64), MaskedReg)
174 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::V_CMP_NE_U16_t16_e64), DstReg)
181 bool IsSGPR = TRI.isSGPRClass(SrcRC);
182 unsigned AndOpc = IsSGPR ? AMDGPU::S_AND_B32 : AMDGPU::V_AND_B32_e32;
189 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::V_CMP_NE_U32_e64), DstReg)
195 if (!MRI->getRegClassOrNull(SrcReg))
196 MRI->setRegClass(SrcReg, SrcRC);
202 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
203 if (RC && !RBI.constrainGenericRegister(DstReg, *RC, *MRI))
209 for (
const MachineOperand &MO :
I.operands()) {
210 if (MO.getReg().isPhysical())
214 TRI.getConstrainedRegClassForReg(MO.getReg(), *MRI);
217 RBI.constrainGenericRegister(MO.getReg(), *RC, *MRI);
222bool AMDGPUInstructionSelector::selectCOPY_SCC_VCC(
MachineInstr &
I)
const {
225 Register VCCReg =
I.getOperand(1).getReg();
229 if (STI.hasScalarCompareEq64()) {
231 STI.isWave64() ? AMDGPU::S_CMP_LG_U64 : AMDGPU::S_CMP_LG_U32;
234 Register DeadDst = MRI->createVirtualRegister(&AMDGPU::SReg_64RegClass);
235 Cmp =
BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::S_OR_B64), DeadDst)
242 Register DstReg =
I.getOperand(0).getReg();
246 return RBI.constrainGenericRegister(DstReg, AMDGPU::SReg_32RegClass, *MRI);
249bool AMDGPUInstructionSelector::selectCOPY_VCC_SCC(
MachineInstr &
I)
const {
253 Register DstReg =
I.getOperand(0).getReg();
254 Register SrcReg =
I.getOperand(1).getReg();
255 std::optional<ValueAndVReg> Arg =
259 const int64_t
Value = Arg->Value.getZExtValue();
261 unsigned Opcode = STI.isWave64() ? AMDGPU::S_MOV_B64 : AMDGPU::S_MOV_B32;
268 return RBI.constrainGenericRegister(DstReg, *TRI.getBoolRC(), *MRI);
274 unsigned SelectOpcode =
275 STI.isWave64() ? AMDGPU::S_CSELECT_B64 : AMDGPU::S_CSELECT_B32;
285bool AMDGPUInstructionSelector::selectReadAnyLane(
MachineInstr &
I)
const {
286 Register DstReg =
I.getOperand(0).getReg();
287 Register SrcReg =
I.getOperand(1).getReg();
292 auto RFL =
BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::V_READFIRSTLANE_B32), DstReg)
300bool AMDGPUInstructionSelector::selectPHI(
MachineInstr &
I)
const {
301 const Register DefReg =
I.getOperand(0).getReg();
302 const LLT DefTy = MRI->getType(DefReg);
314 MRI->getRegClassOrRegBank(DefReg);
325 DefRC = TRI.getRegClassForTypeOnBank(DefTy, RB);
334 for (
unsigned i = 1; i !=
I.getNumOperands(); i += 2) {
335 const Register SrcReg =
I.getOperand(i).getReg();
337 const RegisterBank *RB = MRI->getRegBankOrNull(SrcReg);
339 const LLT SrcTy = MRI->getType(SrcReg);
341 TRI.getRegClassForTypeOnBank(SrcTy, *RB);
342 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI))
347 I.setDesc(TII.get(TargetOpcode::PHI));
348 return RBI.constrainGenericRegister(DefReg, *DefRC, *MRI);
354 unsigned SubIdx)
const {
358 Register DstReg = MRI->createVirtualRegister(&SubRC);
361 unsigned ComposedSubIdx = TRI.composeSubRegIndices(MO.
getSubReg(), SubIdx);
363 BuildMI(*BB,
MI,
MI->getDebugLoc(), TII.get(AMDGPU::COPY), DstReg)
389 return Is64 ? AMDGPU::S_AND_B64 : AMDGPU::S_AND_B32;
391 return Is64 ? AMDGPU::S_OR_B64 : AMDGPU::S_OR_B32;
393 return Is64 ? AMDGPU::S_XOR_B64 : AMDGPU::S_XOR_B32;
399bool AMDGPUInstructionSelector::selectG_AND_OR_XOR(
MachineInstr &
I)
const {
400 Register DstReg =
I.getOperand(0).getReg();
403 const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
404 if (DstRB->
getID() != AMDGPU::SGPRRegBankID &&
405 DstRB->
getID() != AMDGPU::VCCRegBankID)
408 bool Is64 =
Size > 32 || (DstRB->
getID() == AMDGPU::VCCRegBankID &&
421bool AMDGPUInstructionSelector::selectG_ADD_SUB(
MachineInstr &
I)
const {
424 Register DstReg =
I.getOperand(0).getReg();
426 LLT Ty = MRI->getType(DstReg);
431 const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
432 const bool IsSALU = DstRB->
getID() == AMDGPU::SGPRRegBankID;
433 const bool Sub =
I.getOpcode() == TargetOpcode::G_SUB;
437 const unsigned Opc =
Sub ? AMDGPU::S_SUB_U32 : AMDGPU::S_ADD_U32;
440 .
add(
I.getOperand(1))
441 .
add(
I.getOperand(2))
448 if (STI.hasAddNoCarryInsts()) {
449 const unsigned Opc =
Sub ? AMDGPU::V_SUB_U32_e64 : AMDGPU::V_ADD_U32_e64;
450 I.setDesc(TII.get(
Opc));
457 const unsigned Opc =
Sub ? AMDGPU::V_SUB_CO_U32_e64 : AMDGPU::V_ADD_CO_U32_e64;
459 Register UnusedCarry = MRI->createVirtualRegister(TRI.getWaveMaskRegClass());
463 .
add(
I.getOperand(1))
464 .
add(
I.getOperand(2))
471 assert(!
Sub &&
"illegal sub should not reach here");
474 = IsSALU ? AMDGPU::SReg_64_XEXECRegClass : AMDGPU::VReg_64RegClass;
476 = IsSALU ? AMDGPU::SReg_32RegClass : AMDGPU::VGPR_32RegClass;
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));
483 Register DstLo = MRI->createVirtualRegister(&HalfRC);
484 Register DstHi = MRI->createVirtualRegister(&HalfRC);
487 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::S_ADD_U32), DstLo)
490 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::S_ADDC_U32), DstHi)
496 Register CarryReg = MRI->createVirtualRegister(CarryRC);
497 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::V_ADD_CO_U32_e64), DstLo)
503 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::V_ADDC_U32_e64), DstHi)
513 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)
520 if (!RBI.constrainGenericRegister(DstReg, RC, *MRI))
527bool AMDGPUInstructionSelector::selectG_UADDO_USUBO_UADDE_USUBE(
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;
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));
550 Register Src0Reg =
I.getOperand(2).getReg();
551 Register Src1Reg =
I.getOperand(3).getReg();
554 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::COPY), AMDGPU::SCC)
555 .
addReg(
I.getOperand(4).getReg());
558 unsigned NoCarryOpc = IsAdd ? AMDGPU::S_ADD_U32 : AMDGPU::S_SUB_U32;
559 unsigned CarryOpc = IsAdd ? AMDGPU::S_ADDC_U32 : AMDGPU::S_SUBB_U32;
561 auto CarryInst =
BuildMI(*BB, &
I,
DL, TII.get(HasCarryIn ? CarryOpc : NoCarryOpc), Dst0Reg)
562 .
add(
I.getOperand(2))
563 .
add(
I.getOperand(3));
565 if (MRI->use_nodbg_empty(Dst1Reg)) {
566 CarryInst.setOperandDead(3);
568 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::COPY), Dst1Reg)
570 if (!MRI->getRegClassOrNull(Dst1Reg))
571 MRI->setRegClass(Dst1Reg, &AMDGPU::SReg_32RegClass);
574 if (!RBI.constrainGenericRegister(Dst0Reg, AMDGPU::SReg_32RegClass, *MRI) ||
575 !RBI.constrainGenericRegister(Src0Reg, AMDGPU::SReg_32RegClass, *MRI) ||
576 !RBI.constrainGenericRegister(Src1Reg, AMDGPU::SReg_32RegClass, *MRI))
580 !RBI.constrainGenericRegister(
I.getOperand(4).getReg(),
581 AMDGPU::SReg_32RegClass, *MRI))
588bool AMDGPUInstructionSelector::selectG_AMDGPU_MAD_64_32(
592 const bool IsUnsigned =
I.getOpcode() == AMDGPU::G_AMDGPU_MAD_U64_U32;
593 bool UseNoCarry = Subtarget->hasMadNC64_32Insts() &&
594 MRI->use_nodbg_empty(
I.getOperand(1).getReg());
597 if (Subtarget->hasMADIntraFwdBug())
598 Opc = IsUnsigned ? AMDGPU::V_MAD_U64_U32_gfx11_e64
599 : AMDGPU::V_MAD_I64_I32_gfx11_e64;
601 Opc = IsUnsigned ? AMDGPU::V_MAD_NC_U64_U32_e64
602 : AMDGPU::V_MAD_NC_I64_I32_e64;
604 Opc = IsUnsigned ? AMDGPU::V_MAD_U64_U32_e64 : AMDGPU::V_MAD_I64_I32_e64;
609 I.setDesc(TII.get(
Opc));
611 I.addImplicitDefUseOperands(*
MF);
612 I.getOperand(0).setIsEarlyClobber(
true);
618bool AMDGPUInstructionSelector::selectG_EXTRACT(
MachineInstr &
I)
const {
620 Register DstReg =
I.getOperand(0).getReg();
621 Register SrcReg =
I.getOperand(1).getReg();
622 LLT DstTy = MRI->getType(DstReg);
623 LLT SrcTy = MRI->getType(SrcReg);
628 int64_t
Offset =
I.getOperand(2).getImm();
629 if (
Offset % 32 != 0 || DstSize > 128)
638 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
639 if (!DstRC || !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))
642 const RegisterBank *SrcBank = RBI.getRegBank(SrcReg, *MRI, TRI);
644 TRI.getRegClassForSizeOnBank(SrcSize, *SrcBank);
649 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubReg);
654 *SrcRC,
I.getOperand(1));
656 BuildMI(*BB, &
I,
DL, TII.get(TargetOpcode::COPY), DstReg)
657 .
addReg(SrcReg, {}, SubReg);
663bool AMDGPUInstructionSelector::selectS16MergeToS32(
MachineInstr &
MI)
const {
668 LLT Src0Ty = MRI->getType(Src0);
669 LLT Src1Ty = MRI->getType(Src1);
671 const RegisterBank *DstBank = RBI.getRegBank(Dst, *MRI, TRI);
672 const RegisterBank *Src0Bank = RBI.getRegBank(Src0, *MRI, TRI);
673 const RegisterBank *Src1Bank = RBI.getRegBank(Src1, *MRI, TRI);
674 const bool IsVector = DstBank->
getID() == AMDGPU::VGPRRegBankID;
685 if (Src0Bank->
getID() == AMDGPU::VGPRRegBankID &&
686 Src1Bank->
getID() == AMDGPU::VGPRRegBankID &&
688 BuildMI(*BB,
MI,
DL, TII.get(TargetOpcode::REG_SEQUENCE), Dst)
694 if (!RBI.constrainGenericRegister(Dst, AMDGPU::VGPR_32RegClass, *MRI))
697 MI.eraseFromParent();
702 Register TmpReg = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
703 auto MIB =
BuildMI(*BB,
MI,
DL, TII.get(AMDGPU::V_AND_B32_e32), TmpReg)
708 MIB =
BuildMI(*BB,
MI,
DL, TII.get(AMDGPU::V_LSHL_OR_B32_e64), Dst)
714 MI.eraseFromParent();
737 unsigned Opc = AMDGPU::S_PACK_LL_B32_B16;
738 if (Shift0 && Shift1) {
739 Opc = AMDGPU::S_PACK_HH_B32_B16;
740 MI.getOperand(1).setReg(ShiftSrc0);
741 MI.getOperand(2).setReg(ShiftSrc1);
743 Opc = AMDGPU::S_PACK_LH_B32_B16;
744 MI.getOperand(2).setReg(ShiftSrc1);
748 if (ConstSrc1 && ConstSrc1->Value == 0) {
750 auto MIB =
BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::S_LSHR_B32), Dst)
755 MI.eraseFromParent();
759 if (STI.hasSPackHL()) {
760 Opc = AMDGPU::S_PACK_HL_B32_B16;
761 MI.getOperand(1).setReg(ShiftSrc0);
765 MI.setDesc(TII.get(
Opc));
772bool AMDGPUInstructionSelector::selectS16MergeToWide(
MachineInstr &
MI)
const {
776 const uint64_t DstSize = MRI->getType(DstReg).getSizeInBits();
777 const RegisterBank *DstBank = RBI.getRegBank(DstReg, *MRI, TRI);
778 const unsigned NumSrc =
MI.getNumOperands() - 1;
782 for (
unsigned I = 0;
I != NumSrc;
I += 2) {
783 Register S32 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
793 TRI.getRegClassForSizeOnBank(DstSize, *DstBank);
794 if (!DstRC || !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))
796 ArrayRef<int16_t> SubRegs = TRI.getRegSplitParts(DstRC, 4);
797 auto MIB =
BuildMI(*BB,
MI,
DL, TII.get(TargetOpcode::REG_SEQUENCE), DstReg);
798 for (
size_t I = 0,
E = S32Regs.
size();
I !=
E; ++
I)
799 MIB.addReg(S32Regs[
I]).addImm(SubRegs[
I]);
801 MI.eraseFromParent();
805bool AMDGPUInstructionSelector::selectG_MERGE_VALUES(
MachineInstr &
MI)
const {
808 LLT DstTy = MRI->getType(DstReg);
809 LLT SrcTy = MRI->getType(
MI.getOperand(1).getReg());
815 MI.getNumOperands() == 3) {
816 return selectS16MergeToS32(
MI);
820 bool IsWideS16Merge = SrcSize == 16 && DstTy.
getSizeInBits() > 32 &&
824 if (IsWideS16Merge &&
825 RBI.getRegBank(DstReg, *MRI, TRI)->getID() != AMDGPU::VGPRRegBankID)
826 return selectS16MergeToWide(
MI);
834 const RegisterBank *DstBank = RBI.getRegBank(DstReg, *MRI, TRI);
837 TRI.getRegClassForSizeOnBank(DstSize, *DstBank);
841 unsigned SrcSizeEnc =
static_cast<unsigned>(SrcSize);
842 ArrayRef<int16_t> SubRegs = TRI.getRegSplitParts(DstRC, SrcSizeEnc / 8);
843 MachineInstrBuilder MIB =
844 BuildMI(*BB, &
MI,
DL, TII.get(TargetOpcode::REG_SEQUENCE), DstReg);
845 for (
int I = 0,
E =
MI.getNumOperands() - 1;
I !=
E; ++
I) {
846 MachineOperand &Src =
MI.getOperand(
I + 1);
852 TRI.getConstrainedRegClassForReg(SrcReg, *MRI);
853 if (SrcRC && !RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI))
857 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))
860 MI.eraseFromParent();
864bool AMDGPUInstructionSelector::selectG_UNMERGE_VALUES(
MachineInstr &
MI)
const {
866 const int NumDst =
MI.getNumOperands() - 1;
868 MachineOperand &Src =
MI.getOperand(NumDst);
872 LLT DstTy = MRI->getType(DstReg0);
873 LLT SrcTy = MRI->getType(SrcReg);
878 const RegisterBank *SrcBank = RBI.getRegBank(SrcReg, *MRI, TRI);
881 TRI.getRegClassForSizeOnBank(SrcSize, *SrcBank);
886 unsigned DstSizeEnc =
static_cast<unsigned>(DstSize);
887 ArrayRef<int16_t> SubRegs = TRI.getRegSplitParts(SrcRC, DstSizeEnc / 8);
888 for (
int I = 0,
E = NumDst;
I !=
E; ++
I) {
891 if (SrcBank->
getID() == AMDGPU::SGPRRegBankID &&
892 SubRegs[
I] == AMDGPU::hi16) {
893 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::S_LSHR_B32), DstReg)
897 BuildMI(*BB, &
MI,
DL, TII.get(TargetOpcode::COPY), DstReg)
898 .
addReg(SrcReg, {}, SubRegs[
I]);
901 SrcRC = TRI.getSubClassWithSubReg(SrcRC, SubRegs[
I]);
904 if (!SrcRC || !RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI))
908 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
909 if (DstRC && !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))
913 MI.eraseFromParent();
917bool AMDGPUInstructionSelector::selectG_BUILD_VECTOR(
MachineInstr &
MI)
const {
918 assert(
MI.getOpcode() == AMDGPU::G_BUILD_VECTOR_TRUNC ||
919 MI.getOpcode() == AMDGPU::G_BUILD_VECTOR);
923 LLT SrcTy = MRI->getType(Src0);
927 if (
MI.getOpcode() == AMDGPU::G_BUILD_VECTOR && SrcSize >= 32) {
928 return selectG_MERGE_VALUES(
MI);
935 (
MI.getOpcode() == AMDGPU::G_BUILD_VECTOR_TRUNC &&
939 const RegisterBank *DstBank = RBI.getRegBank(Dst, *MRI, TRI);
940 if (DstBank->
getID() == AMDGPU::AGPRRegBankID)
943 assert(DstBank->
getID() == AMDGPU::SGPRRegBankID ||
944 DstBank->
getID() == AMDGPU::VGPRRegBankID);
945 const bool IsVector = DstBank->
getID() == AMDGPU::VGPRRegBankID;
958 const int64_t K0 = ConstSrc0->Value.getSExtValue();
959 const int64_t K1 = ConstSrc1->Value.getSExtValue();
960 uint32_t
Lo16 =
static_cast<uint32_t
>(K0) & 0xffff;
961 uint32_t
Hi16 =
static_cast<uint32_t
>(K1) & 0xffff;
967 MI.eraseFromParent();
968 return RBI.constrainGenericRegister(Dst, AMDGPU::VGPR_32RegClass, *MRI);
973 MI.eraseFromParent();
974 return RBI.constrainGenericRegister(Dst, AMDGPU::SReg_32RegClass, *MRI);
985 if (Src1Def->
getOpcode() == AMDGPU::G_IMPLICIT_DEF) {
986 MI.setDesc(TII.get(AMDGPU::COPY));
989 IsVector ? AMDGPU::VGPR_32RegClass : AMDGPU::SReg_32RegClass;
990 return RBI.constrainGenericRegister(Dst, RC, *MRI) &&
991 RBI.constrainGenericRegister(Src0, RC, *MRI);
994 return selectS16MergeToS32(
MI);
997bool AMDGPUInstructionSelector::selectG_IMPLICIT_DEF(
MachineInstr &
I)
const {
998 const MachineOperand &MO =
I.getOperand(0);
1003 TRI.getConstrainedRegClassForReg(MO.
getReg(), *MRI);
1004 if ((!RC && !MRI->getRegBankOrNull(MO.
getReg())) ||
1005 (RC && RBI.constrainGenericRegister(MO.
getReg(), *RC, *MRI))) {
1006 I.setDesc(TII.get(TargetOpcode::IMPLICIT_DEF));
1013bool AMDGPUInstructionSelector::selectG_INSERT(
MachineInstr &
I)
const {
1016 Register DstReg =
I.getOperand(0).getReg();
1017 Register Src0Reg =
I.getOperand(1).getReg();
1018 Register Src1Reg =
I.getOperand(2).getReg();
1019 LLT Src1Ty = MRI->getType(Src1Reg);
1021 uint64_t DstSize = MRI->getType(DstReg).getSizeInBits();
1024 int64_t
Offset =
I.getOperand(3).getImm();
1027 if (
Offset % 32 != 0 || InsSize % 32 != 0)
1034 unsigned SubReg = TRI.getSubRegFromChannel(
Offset / 32, InsSize / 32);
1035 if (SubReg == AMDGPU::NoSubRegister)
1038 const RegisterBank *DstBank = RBI.getRegBank(DstReg, *MRI, TRI);
1040 TRI.getRegClassForSizeOnBank(DstSize, *DstBank);
1044 const RegisterBank *Src0Bank = RBI.getRegBank(Src0Reg, *MRI, TRI);
1045 const RegisterBank *Src1Bank = RBI.getRegBank(Src1Reg, *MRI, TRI);
1047 TRI.getRegClassForSizeOnBank(DstSize, *Src0Bank);
1049 TRI.getRegClassForSizeOnBank(InsSize, *Src1Bank);
1053 Src0RC = TRI.getSubClassWithSubReg(Src0RC, SubReg);
1054 if (!Src0RC || !Src1RC)
1057 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI) ||
1058 !RBI.constrainGenericRegister(Src0Reg, *Src0RC, *MRI) ||
1059 !RBI.constrainGenericRegister(Src1Reg, *Src1RC, *MRI))
1063 BuildMI(*BB, &
I,
DL, TII.get(TargetOpcode::INSERT_SUBREG), DstReg)
1068 I.eraseFromParent();
1072bool AMDGPUInstructionSelector::selectG_SBFX_UBFX(
MachineInstr &
MI)
const {
1075 Register OffsetReg =
MI.getOperand(2).getReg();
1076 Register WidthReg =
MI.getOperand(3).getReg();
1078 assert(RBI.getRegBank(DstReg, *MRI, TRI)->getID() == AMDGPU::VGPRRegBankID &&
1079 "scalar BFX instructions are expanded in regbankselect");
1080 assert(MRI->getType(
MI.getOperand(0).getReg()).getSizeInBits() == 32 &&
1081 "64-bit vector BFX instructions are expanded in regbankselect");
1086 bool IsSigned =
MI.getOpcode() == TargetOpcode::G_SBFX;
1087 unsigned Opc = IsSigned ? AMDGPU::V_BFE_I32_e64 : AMDGPU::V_BFE_U32_e64;
1092 MI.eraseFromParent();
1097bool AMDGPUInstructionSelector::selectInterpP1F16(
MachineInstr &
MI)
const {
1098 if (STI.getLDSBankCount() != 16)
1104 if (!RBI.constrainGenericRegister(M0Val, AMDGPU::SReg_32RegClass, *MRI) ||
1105 !RBI.constrainGenericRegister(Dst, AMDGPU::VGPR_32RegClass, *MRI) ||
1106 !RBI.constrainGenericRegister(Src0, AMDGPU::VGPR_32RegClass, *MRI))
1116 Register InterpMov = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
1122 BuildMI(*
MBB, &
MI,
DL, TII.get(AMDGPU::V_INTERP_MOV_F32), InterpMov)
1125 .
addImm(
MI.getOperand(3).getImm());
1138 MI.eraseFromParent();
1147bool AMDGPUInstructionSelector::selectWritelane(
MachineInstr &
MI)
const {
1149 if (STI.getConstantBusLimit(AMDGPU::V_WRITELANE_B32) > 1)
1156 Register LaneSelect =
MI.getOperand(3).getReg();
1159 auto MIB =
BuildMI(*
MBB, &
MI,
DL, TII.get(AMDGPU::V_WRITELANE_B32), VDst);
1161 std::optional<ValueAndVReg> ConstSelect =
1167 MIB.
addImm(ConstSelect->Value.getSExtValue() &
1170 std::optional<ValueAndVReg> ConstVal =
1176 static_cast<int32_t
>(ConstVal->Value.getSExtValue()),
1177 STI.hasInv2PiInlineImm())) {
1178 MIB.
addImm(ConstVal->Value.getSExtValue());
1186 RBI.constrainGenericRegister(LaneSelect, AMDGPU::SReg_32_XM0RegClass, *MRI);
1188 BuildMI(*
MBB, *MIB,
DL, TII.get(AMDGPU::COPY), AMDGPU::M0)
1196 MI.eraseFromParent();
1203bool AMDGPUInstructionSelector::selectDivScale(
MachineInstr &
MI)
const {
1207 LLT Ty = MRI->getType(Dst0);
1210 Opc = AMDGPU::V_DIV_SCALE_F32_e64;
1212 Opc = AMDGPU::V_DIV_SCALE_F64_e64;
1223 unsigned ChooseDenom =
static_cast<unsigned>(
MI.getOperand(5).
getImm());
1238 MI.eraseFromParent();
1243bool AMDGPUInstructionSelector::selectG_INTRINSIC(
MachineInstr &
I)
const {
1245 switch (IntrinsicID) {
1246 case Intrinsic::amdgcn_if_break: {
1251 BuildMI(*BB, &
I,
I.getDebugLoc(), TII.get(AMDGPU::SI_IF_BREAK))
1252 .
add(
I.getOperand(0))
1253 .
add(
I.getOperand(2))
1254 .
add(
I.getOperand(3))
1257 Register DstReg =
I.getOperand(0).getReg();
1258 Register Src0Reg =
I.getOperand(2).getReg();
1259 Register Src1Reg =
I.getOperand(3).getReg();
1261 I.eraseFromParent();
1264 MRI->setRegClass(
Reg, TRI.getWaveMaskRegClass());
1268 case Intrinsic::amdgcn_interp_p1_f16:
1269 return selectInterpP1F16(
I);
1270 case Intrinsic::amdgcn_wqm:
1271 return constrainCopyLikeIntrin(
I, AMDGPU::WQM);
1272 case Intrinsic::amdgcn_softwqm:
1273 return constrainCopyLikeIntrin(
I, AMDGPU::SOFT_WQM);
1274 case Intrinsic::amdgcn_strict_wwm:
1275 case Intrinsic::amdgcn_wwm:
1276 return constrainCopyLikeIntrin(
I, AMDGPU::STRICT_WWM);
1277 case Intrinsic::amdgcn_strict_wqm:
1278 return constrainCopyLikeIntrin(
I, AMDGPU::STRICT_WQM);
1279 case Intrinsic::amdgcn_writelane:
1280 return selectWritelane(
I);
1281 case Intrinsic::amdgcn_div_scale:
1282 return selectDivScale(
I);
1283 case Intrinsic::amdgcn_ballot:
1284 return selectBallot(
I);
1285 case Intrinsic::amdgcn_reloc_constant:
1286 return selectRelocConstant(
I);
1287 case Intrinsic::amdgcn_groupstaticsize:
1288 return selectGroupStaticSize(
I);
1289 case Intrinsic::returnaddress:
1290 return selectReturnAddress(
I);
1291 case Intrinsic::amdgcn_smfmac_f32_16x16x32_f16:
1292 case Intrinsic::amdgcn_smfmac_f32_32x32x16_f16:
1293 case Intrinsic::amdgcn_smfmac_f32_16x16x32_bf16:
1294 case Intrinsic::amdgcn_smfmac_f32_32x32x16_bf16:
1295 case Intrinsic::amdgcn_smfmac_i32_16x16x64_i8:
1296 case Intrinsic::amdgcn_smfmac_i32_32x32x32_i8:
1297 case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf8_bf8:
1298 case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf8_fp8:
1299 case Intrinsic::amdgcn_smfmac_f32_16x16x64_fp8_bf8:
1300 case Intrinsic::amdgcn_smfmac_f32_16x16x64_fp8_fp8:
1301 case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf8_bf8:
1302 case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf8_fp8:
1303 case Intrinsic::amdgcn_smfmac_f32_32x32x32_fp8_bf8:
1304 case Intrinsic::amdgcn_smfmac_f32_32x32x32_fp8_fp8:
1305 case Intrinsic::amdgcn_smfmac_f32_16x16x64_f16:
1306 case Intrinsic::amdgcn_smfmac_f32_32x32x32_f16:
1307 case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf16:
1308 case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf16:
1309 case Intrinsic::amdgcn_smfmac_i32_16x16x128_i8:
1310 case Intrinsic::amdgcn_smfmac_i32_32x32x64_i8:
1311 case Intrinsic::amdgcn_smfmac_f32_16x16x128_bf8_bf8:
1312 case Intrinsic::amdgcn_smfmac_f32_16x16x128_bf8_fp8:
1313 case Intrinsic::amdgcn_smfmac_f32_16x16x128_fp8_bf8:
1314 case Intrinsic::amdgcn_smfmac_f32_16x16x128_fp8_fp8:
1315 case Intrinsic::amdgcn_smfmac_f32_32x32x64_bf8_bf8:
1316 case Intrinsic::amdgcn_smfmac_f32_32x32x64_bf8_fp8:
1317 case Intrinsic::amdgcn_smfmac_f32_32x32x64_fp8_bf8:
1318 case Intrinsic::amdgcn_smfmac_f32_32x32x64_fp8_fp8:
1319 return selectSMFMACIntrin(
I);
1320 case Intrinsic::amdgcn_permlane16_swap:
1321 case Intrinsic::amdgcn_permlane32_swap:
1322 return selectPermlaneSwapIntrin(
I, IntrinsicID);
1323 case Intrinsic::amdgcn_wave_shuffle:
1324 return selectWaveShuffleIntrin(
I);
1335 if (
Size == 16 && !ST.has16BitInsts())
1338 const auto Select = [&](
unsigned S16Opc,
unsigned TrueS16Opc,
1339 unsigned FakeS16Opc,
unsigned S32Opc,
1342 return ST.hasTrue16BitInsts()
1343 ? ST.useRealTrue16Insts() ? TrueS16Opc : FakeS16Opc
1354 return Select(AMDGPU::V_CMP_NE_U16_e64, AMDGPU::V_CMP_NE_U16_t16_e64,
1355 AMDGPU::V_CMP_NE_U16_fake16_e64, AMDGPU::V_CMP_NE_U32_e64,
1356 AMDGPU::V_CMP_NE_U64_e64);
1358 return Select(AMDGPU::V_CMP_EQ_U16_e64, AMDGPU::V_CMP_EQ_U16_t16_e64,
1359 AMDGPU::V_CMP_EQ_U16_fake16_e64, AMDGPU::V_CMP_EQ_U32_e64,
1360 AMDGPU::V_CMP_EQ_U64_e64);
1362 return Select(AMDGPU::V_CMP_GT_I16_e64, AMDGPU::V_CMP_GT_I16_t16_e64,
1363 AMDGPU::V_CMP_GT_I16_fake16_e64, AMDGPU::V_CMP_GT_I32_e64,
1364 AMDGPU::V_CMP_GT_I64_e64);
1366 return Select(AMDGPU::V_CMP_GE_I16_e64, AMDGPU::V_CMP_GE_I16_t16_e64,
1367 AMDGPU::V_CMP_GE_I16_fake16_e64, AMDGPU::V_CMP_GE_I32_e64,
1368 AMDGPU::V_CMP_GE_I64_e64);
1370 return Select(AMDGPU::V_CMP_LT_I16_e64, AMDGPU::V_CMP_LT_I16_t16_e64,
1371 AMDGPU::V_CMP_LT_I16_fake16_e64, AMDGPU::V_CMP_LT_I32_e64,
1372 AMDGPU::V_CMP_LT_I64_e64);
1374 return Select(AMDGPU::V_CMP_LE_I16_e64, AMDGPU::V_CMP_LE_I16_t16_e64,
1375 AMDGPU::V_CMP_LE_I16_fake16_e64, AMDGPU::V_CMP_LE_I32_e64,
1376 AMDGPU::V_CMP_LE_I64_e64);
1378 return Select(AMDGPU::V_CMP_GT_U16_e64, AMDGPU::V_CMP_GT_U16_t16_e64,
1379 AMDGPU::V_CMP_GT_U16_fake16_e64, AMDGPU::V_CMP_GT_U32_e64,
1380 AMDGPU::V_CMP_GT_U64_e64);
1382 return Select(AMDGPU::V_CMP_GE_U16_e64, AMDGPU::V_CMP_GE_U16_t16_e64,
1383 AMDGPU::V_CMP_GE_U16_fake16_e64, AMDGPU::V_CMP_GE_U32_e64,
1384 AMDGPU::V_CMP_GE_U64_e64);
1386 return Select(AMDGPU::V_CMP_LT_U16_e64, AMDGPU::V_CMP_LT_U16_t16_e64,
1387 AMDGPU::V_CMP_LT_U16_fake16_e64, AMDGPU::V_CMP_LT_U32_e64,
1388 AMDGPU::V_CMP_LT_U64_e64);
1390 return Select(AMDGPU::V_CMP_LE_U16_e64, AMDGPU::V_CMP_LE_U16_t16_e64,
1391 AMDGPU::V_CMP_LE_U16_fake16_e64, AMDGPU::V_CMP_LE_U32_e64,
1392 AMDGPU::V_CMP_LE_U64_e64);
1395 return Select(AMDGPU::V_CMP_EQ_F16_e64, AMDGPU::V_CMP_EQ_F16_t16_e64,
1396 AMDGPU::V_CMP_EQ_F16_fake16_e64, AMDGPU::V_CMP_EQ_F32_e64,
1397 AMDGPU::V_CMP_EQ_F64_e64);
1399 return Select(AMDGPU::V_CMP_GT_F16_e64, AMDGPU::V_CMP_GT_F16_t16_e64,
1400 AMDGPU::V_CMP_GT_F16_fake16_e64, AMDGPU::V_CMP_GT_F32_e64,
1401 AMDGPU::V_CMP_GT_F64_e64);
1403 return Select(AMDGPU::V_CMP_GE_F16_e64, AMDGPU::V_CMP_GE_F16_t16_e64,
1404 AMDGPU::V_CMP_GE_F16_fake16_e64, AMDGPU::V_CMP_GE_F32_e64,
1405 AMDGPU::V_CMP_GE_F64_e64);
1407 return Select(AMDGPU::V_CMP_LT_F16_e64, AMDGPU::V_CMP_LT_F16_t16_e64,
1408 AMDGPU::V_CMP_LT_F16_fake16_e64, AMDGPU::V_CMP_LT_F32_e64,
1409 AMDGPU::V_CMP_LT_F64_e64);
1411 return Select(AMDGPU::V_CMP_LE_F16_e64, AMDGPU::V_CMP_LE_F16_t16_e64,
1412 AMDGPU::V_CMP_LE_F16_fake16_e64, AMDGPU::V_CMP_LE_F32_e64,
1413 AMDGPU::V_CMP_LE_F64_e64);
1415 return Select(AMDGPU::V_CMP_NEQ_F16_e64, AMDGPU::V_CMP_NEQ_F16_t16_e64,
1416 AMDGPU::V_CMP_NEQ_F16_fake16_e64, AMDGPU::V_CMP_NEQ_F32_e64,
1417 AMDGPU::V_CMP_NEQ_F64_e64);
1419 return Select(AMDGPU::V_CMP_O_F16_e64, AMDGPU::V_CMP_O_F16_t16_e64,
1420 AMDGPU::V_CMP_O_F16_fake16_e64, AMDGPU::V_CMP_O_F32_e64,
1421 AMDGPU::V_CMP_O_F64_e64);
1423 return Select(AMDGPU::V_CMP_U_F16_e64, AMDGPU::V_CMP_U_F16_t16_e64,
1424 AMDGPU::V_CMP_U_F16_fake16_e64, AMDGPU::V_CMP_U_F32_e64,
1425 AMDGPU::V_CMP_U_F64_e64);
1427 return Select(AMDGPU::V_CMP_NLG_F16_e64, AMDGPU::V_CMP_NLG_F16_t16_e64,
1428 AMDGPU::V_CMP_NLG_F16_fake16_e64, AMDGPU::V_CMP_NLG_F32_e64,
1429 AMDGPU::V_CMP_NLG_F64_e64);
1431 return Select(AMDGPU::V_CMP_NLE_F16_e64, AMDGPU::V_CMP_NLE_F16_t16_e64,
1432 AMDGPU::V_CMP_NLE_F16_fake16_e64, AMDGPU::V_CMP_NLE_F32_e64,
1433 AMDGPU::V_CMP_NLE_F64_e64);
1435 return Select(AMDGPU::V_CMP_NLT_F16_e64, AMDGPU::V_CMP_NLT_F16_t16_e64,
1436 AMDGPU::V_CMP_NLT_F16_fake16_e64, AMDGPU::V_CMP_NLT_F32_e64,
1437 AMDGPU::V_CMP_NLT_F64_e64);
1439 return Select(AMDGPU::V_CMP_NGE_F16_e64, AMDGPU::V_CMP_NGE_F16_t16_e64,
1440 AMDGPU::V_CMP_NGE_F16_fake16_e64, AMDGPU::V_CMP_NGE_F32_e64,
1441 AMDGPU::V_CMP_NGE_F64_e64);
1443 return Select(AMDGPU::V_CMP_NGT_F16_e64, AMDGPU::V_CMP_NGT_F16_t16_e64,
1444 AMDGPU::V_CMP_NGT_F16_fake16_e64, AMDGPU::V_CMP_NGT_F32_e64,
1445 AMDGPU::V_CMP_NGT_F64_e64);
1447 return Select(AMDGPU::V_CMP_NEQ_F16_e64, AMDGPU::V_CMP_NEQ_F16_t16_e64,
1448 AMDGPU::V_CMP_NEQ_F16_fake16_e64, AMDGPU::V_CMP_NEQ_F32_e64,
1449 AMDGPU::V_CMP_NEQ_F64_e64);
1451 return Select(AMDGPU::V_CMP_TRU_F16_e64, AMDGPU::V_CMP_TRU_F16_t16_e64,
1452 AMDGPU::V_CMP_TRU_F16_fake16_e64, AMDGPU::V_CMP_TRU_F32_e64,
1453 AMDGPU::V_CMP_TRU_F64_e64);
1455 return Select(AMDGPU::V_CMP_F_F16_e64, AMDGPU::V_CMP_F_F16_t16_e64,
1456 AMDGPU::V_CMP_F_F16_fake16_e64, AMDGPU::V_CMP_F_F32_e64,
1457 AMDGPU::V_CMP_F_F64_e64);
1464 if (!STI.hasScalarCompareEq64())
1469 return AMDGPU::S_CMP_LG_U64;
1471 return AMDGPU::S_CMP_EQ_U64;
1480 return AMDGPU::S_CMP_LG_U32;
1482 return AMDGPU::S_CMP_EQ_U32;
1484 return AMDGPU::S_CMP_GT_I32;
1486 return AMDGPU::S_CMP_GE_I32;
1488 return AMDGPU::S_CMP_LT_I32;
1490 return AMDGPU::S_CMP_LE_I32;
1492 return AMDGPU::S_CMP_GT_U32;
1494 return AMDGPU::S_CMP_GE_U32;
1496 return AMDGPU::S_CMP_LT_U32;
1498 return AMDGPU::S_CMP_LE_U32;
1500 return AMDGPU::S_CMP_EQ_F32;
1502 return AMDGPU::S_CMP_GT_F32;
1504 return AMDGPU::S_CMP_GE_F32;
1506 return AMDGPU::S_CMP_LT_F32;
1508 return AMDGPU::S_CMP_LE_F32;
1510 return AMDGPU::S_CMP_LG_F32;
1512 return AMDGPU::S_CMP_O_F32;
1514 return AMDGPU::S_CMP_U_F32;
1516 return AMDGPU::S_CMP_NLG_F32;
1518 return AMDGPU::S_CMP_NLE_F32;
1520 return AMDGPU::S_CMP_NLT_F32;
1522 return AMDGPU::S_CMP_NGE_F32;
1524 return AMDGPU::S_CMP_NGT_F32;
1526 return AMDGPU::S_CMP_NEQ_F32;
1533 if (!STI.hasSALUFloatInsts())
1538 return AMDGPU::S_CMP_EQ_F16;
1540 return AMDGPU::S_CMP_GT_F16;
1542 return AMDGPU::S_CMP_GE_F16;
1544 return AMDGPU::S_CMP_LT_F16;
1546 return AMDGPU::S_CMP_LE_F16;
1548 return AMDGPU::S_CMP_LG_F16;
1550 return AMDGPU::S_CMP_O_F16;
1552 return AMDGPU::S_CMP_U_F16;
1554 return AMDGPU::S_CMP_NLG_F16;
1556 return AMDGPU::S_CMP_NLE_F16;
1558 return AMDGPU::S_CMP_NLT_F16;
1560 return AMDGPU::S_CMP_NGE_F16;
1562 return AMDGPU::S_CMP_NGT_F16;
1564 return AMDGPU::S_CMP_NEQ_F16;
1573bool AMDGPUInstructionSelector::selectG_ICMP_or_FCMP(
MachineInstr &
I)
const {
1578 Register SrcReg =
I.getOperand(2).getReg();
1583 Register CCReg =
I.getOperand(0).getReg();
1584 if (!isVCC(CCReg, *MRI)) {
1585 int Opcode = getS_CMPOpcode(Pred,
Size);
1588 MachineInstr *ICmp =
BuildMI(*BB, &
I,
DL, TII.get(Opcode))
1589 .
add(
I.getOperand(2))
1590 .
add(
I.getOperand(3));
1591 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::COPY), CCReg)
1595 RBI.constrainGenericRegister(CCReg, AMDGPU::SReg_32RegClass, *MRI);
1596 I.eraseFromParent();
1600 if (
I.getOpcode() == AMDGPU::G_FCMP)
1607 MachineInstrBuilder ICmp;
1610 ICmp =
BuildMI(*BB, &
I,
DL, TII.get(Opcode),
I.getOperand(0).getReg())
1612 .
add(
I.getOperand(2))
1614 .
add(
I.getOperand(3))
1617 ICmp =
BuildMI(*BB, &
I,
DL, TII.get(Opcode),
I.getOperand(0).getReg())
1618 .
add(
I.getOperand(2))
1619 .
add(
I.getOperand(3));
1623 *TRI.getBoolRC(), *MRI);
1625 I.eraseFromParent();
1636 if (
MI->getParent() !=
MBB)
1640 if (
MI->getOpcode() == AMDGPU::COPY) {
1641 auto DstRB =
MRI.getRegBankOrNull(
MI->getOperand(0).getReg());
1642 auto SrcRB =
MRI.getRegBankOrNull(
MI->getOperand(1).getReg());
1643 if (DstRB && SrcRB && DstRB->
getID() == AMDGPU::VCCRegBankID &&
1644 SrcRB->getID() == AMDGPU::SGPRRegBankID)
1649 if (
MI->getOpcode() == AMDGPU::G_AMDGPU_COPY_VCC_SCC)
1665bool AMDGPUInstructionSelector::selectBallot(
MachineInstr &
I)
const {
1668 Register DstReg =
I.getOperand(0).getReg();
1669 Register SrcReg =
I.getOperand(2).getReg();
1670 const uint64_t BallotSize = MRI->getType(DstReg).getSizeInBits();
1671 const unsigned WaveSize = STI.getWavefrontSize();
1675 if (BallotSize != WaveSize && (BallotSize != 64 || WaveSize != 32))
1678 std::optional<ValueAndVReg> Arg =
1683 if (BallotSize != WaveSize) {
1684 Dst = MRI->createVirtualRegister(TRI.getBoolRC());
1688 const int64_t
Value = Arg->Value.getZExtValue();
1691 unsigned Opcode = WaveSize == 64 ? AMDGPU::S_MOV_B64 : AMDGPU::S_MOV_B32;
1698 if (!RBI.constrainGenericRegister(Dst, *TRI.getBoolRC(), *MRI))
1704 if (!RBI.constrainGenericRegister(Dst, *TRI.getBoolRC(), *MRI))
1708 unsigned AndOpc = WaveSize == 64 ? AMDGPU::S_AND_B64 : AMDGPU::S_AND_B32;
1718 if (BallotSize != WaveSize) {
1719 Register HiReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
1721 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)
1728 I.eraseFromParent();
1732bool AMDGPUInstructionSelector::selectRelocConstant(
MachineInstr &
I)
const {
1733 Register DstReg =
I.getOperand(0).getReg();
1734 const RegisterBank *DstBank = RBI.getRegBank(DstReg, *MRI, TRI);
1736 if (!DstRC || !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))
1739 const bool IsVALU = DstBank->
getID() == AMDGPU::VGPRRegBankID;
1741 Module *
M =
MF->getFunction().getParent();
1742 const MDNode *
Metadata =
I.getOperand(2).getMetadata();
1749 TII.get(IsVALU ? AMDGPU::V_MOV_B32_e32 : AMDGPU::S_MOV_B32), DstReg)
1752 I.eraseFromParent();
1756bool AMDGPUInstructionSelector::selectGroupStaticSize(
MachineInstr &
I)
const {
1759 Register DstReg =
I.getOperand(0).getReg();
1760 const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
1761 unsigned Mov = DstRB->
getID() == AMDGPU::SGPRRegBankID ?
1762 AMDGPU::S_MOV_B32 : AMDGPU::V_MOV_B32_e32;
1770 const SIMachineFunctionInfo *MFI =
MF->getInfo<SIMachineFunctionInfo>();
1773 Module *
M =
MF->getFunction().getParent();
1774 const GlobalValue *GV =
1779 I.eraseFromParent();
1784bool AMDGPUInstructionSelector::selectReturnAddress(
MachineInstr &
I)
const {
1789 Register DstReg =
I.getOperand(0).getReg();
1790 unsigned Depth =
static_cast<unsigned>(
I.getOperand(2).
getImm());
1793 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
1795 !RBI.constrainGenericRegister(DstReg, *RC, *MRI))
1800 MF.getInfo<SIMachineFunctionInfo>()->isEntryFunction()) {
1803 I.eraseFromParent();
1807 MachineFrameInfo &MFI =
MF.getFrameInfo();
1812 Register ReturnAddrReg = TRI.getReturnAddressReg(
MF);
1814 AMDGPU::SReg_64RegClass,
DL);
1817 I.eraseFromParent();
1821bool AMDGPUInstructionSelector::selectEndCfIntrinsic(
MachineInstr &
MI)
const {
1825 BuildMI(*BB, &
MI,
MI.getDebugLoc(), TII.get(AMDGPU::SI_END_CF))
1826 .
add(
MI.getOperand(1))
1830 MI.eraseFromParent();
1832 if (!MRI->getRegClassOrNull(
Reg))
1833 MRI->setRegClass(
Reg, TRI.getWaveMaskRegClass());
1837bool AMDGPUInstructionSelector::selectDSOrderedIntrinsic(
1843 unsigned IndexOperand =
static_cast<unsigned>(
MI.getOperand(7).
getImm());
1844 bool WaveRelease =
MI.getOperand(8).getImm() != 0;
1845 bool WaveDone =
MI.getOperand(9).getImm() != 0;
1847 if (WaveDone && !WaveRelease) {
1851 Fn,
"ds_ordered_count: wave_done requires wave_release",
DL));
1854 unsigned OrderedCountIndex = IndexOperand & 0x3f;
1855 IndexOperand &= ~0x3f;
1856 unsigned CountDw = 0;
1859 CountDw = (IndexOperand >> 24) & 0xf;
1860 IndexOperand &= ~(0xf << 24);
1862 if (CountDw < 1 || CountDw > 4) {
1865 Fn,
"ds_ordered_count: dword count must be between 1 and 4",
DL));
1873 Fn,
"ds_ordered_count: bad index operand",
DL));
1876 unsigned Instruction = IntrID == Intrinsic::amdgcn_ds_ordered_add ? 0 : 1;
1879 unsigned Offset0 = OrderedCountIndex << 2;
1880 unsigned Offset1 = WaveRelease | (WaveDone << 1) | (Instruction << 4);
1883 Offset1 |= (CountDw - 1) << 6;
1886 Offset1 |= ShaderType << 2;
1888 unsigned Offset = Offset0 | (Offset1 << 8);
1896 MachineInstrBuilder
DS =
1897 BuildMI(*
MBB, &
MI,
DL, TII.get(AMDGPU::DS_ORDERED_COUNT), DstReg)
1902 if (!RBI.constrainGenericRegister(M0Val, AMDGPU::SReg_32RegClass, *MRI))
1906 MI.eraseFromParent();
1912 case Intrinsic::amdgcn_ds_gws_init:
1913 return AMDGPU::DS_GWS_INIT;
1914 case Intrinsic::amdgcn_ds_gws_barrier:
1915 return AMDGPU::DS_GWS_BARRIER;
1916 case Intrinsic::amdgcn_ds_gws_sema_v:
1917 return AMDGPU::DS_GWS_SEMA_V;
1918 case Intrinsic::amdgcn_ds_gws_sema_br:
1919 return AMDGPU::DS_GWS_SEMA_BR;
1920 case Intrinsic::amdgcn_ds_gws_sema_p:
1921 return AMDGPU::DS_GWS_SEMA_P;
1922 case Intrinsic::amdgcn_ds_gws_sema_release_all:
1923 return AMDGPU::DS_GWS_SEMA_RELEASE_ALL;
1929bool AMDGPUInstructionSelector::selectDSGWSIntrinsic(
MachineInstr &
MI,
1931 if (!STI.hasGWS() || (IID == Intrinsic::amdgcn_ds_gws_sema_release_all &&
1932 !STI.hasGWSSemaReleaseAll()))
1936 const bool HasVSrc =
MI.getNumOperands() == 3;
1937 assert(HasVSrc ||
MI.getNumOperands() == 2);
1939 Register BaseOffset =
MI.getOperand(HasVSrc ? 2 : 1).getReg();
1940 const RegisterBank *OffsetRB = RBI.getRegBank(BaseOffset, *MRI, TRI);
1941 if (OffsetRB->
getID() != AMDGPU::SGPRRegBankID)
1950 MachineInstr *Readfirstlane =
nullptr;
1955 if (OffsetDef->
getOpcode() == AMDGPU::V_READFIRSTLANE_B32) {
1956 Readfirstlane = OffsetDef;
1961 if (OffsetDef->
getOpcode() == AMDGPU::G_CONSTANT) {
1967 ImmOffset =
static_cast<unsigned>(
1968 OffsetDef->
getOperand(1).getCImm()->getZExtValue());
1972 std::tie(BaseOffset, ImmOffset) =
1975 if (Readfirstlane) {
1978 if (!RBI.constrainGenericRegister(BaseOffset, AMDGPU::VGPR_32RegClass, *MRI))
1984 if (!RBI.constrainGenericRegister(BaseOffset,
1985 AMDGPU::SReg_32RegClass, *MRI))
1989 Register M0Base = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
2004 const MCInstrDesc &InstrDesc = TII.get(
Opc);
2009 int Data0Idx = AMDGPU::getNamedOperandIdx(
Opc, AMDGPU::OpName::data0);
2012 TRI.getSubRegisterClass(DataRC, AMDGPU::sub0);
2016 if (!RBI.constrainGenericRegister(VSrc, *DataRC, *MRI))
2026 Register DataReg = MRI->createVirtualRegister(DataRC);
2027 if (!RBI.constrainGenericRegister(VSrc, *SubRC, *MRI))
2030 Register UndefReg = MRI->createVirtualRegister(SubRC);
2049 MI.eraseFromParent();
2053bool AMDGPUInstructionSelector::selectDSAppendConsume(
MachineInstr &
MI,
2054 bool IsAppend)
const {
2055 Register PtrBase =
MI.getOperand(2).getReg();
2056 LLT PtrTy = MRI->getType(PtrBase);
2060 std::tie(PtrBase,
Offset) = selectDS1Addr1OffsetImpl(
MI.getOperand(2));
2063 if (!isDSOffsetLegal(PtrBase,
Offset)) {
2064 PtrBase =
MI.getOperand(2).getReg();
2070 const unsigned Opc = IsAppend ? AMDGPU::DS_APPEND : AMDGPU::DS_CONSUME;
2074 if (!RBI.constrainGenericRegister(PtrBase, AMDGPU::SReg_32RegClass, *MRI))
2081 MI.eraseFromParent();
2086bool AMDGPUInstructionSelector::selectInitWholeWave(
MachineInstr &
MI)
const {
2088 SIMachineFunctionInfo *MFInfo =
MF->getInfo<SIMachineFunctionInfo>();
2099 TFE = TexFailCtrl & 0x1;
2101 LWE = TexFailCtrl & 0x2;
2104 return TexFailCtrl == 0;
2107bool AMDGPUInstructionSelector::selectImageIntrinsic(
2115 Register ResultDef =
MI.getOperand(0).getReg();
2116 if (MRI->use_nodbg_empty(ResultDef))
2120 const AMDGPU::MIMGBaseOpcodeInfo *BaseOpcode =
2129 const unsigned ArgOffset =
MI.getNumExplicitDefs() + 1;
2131 Register VDataIn = AMDGPU::NoRegister;
2132 Register VDataOut = AMDGPU::NoRegister;
2134 int NumVDataDwords = -1;
2135 bool IsD16 =
MI.getOpcode() == AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD_D16 ||
2136 MI.getOpcode() == AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE_D16;
2142 Unorm =
MI.getOperand(ArgOffset + Intr->
UnormIndex).getImm() != 0;
2146 bool IsTexFail =
false;
2148 TFE, LWE, IsTexFail))
2151 const int64_t
Flags =
MI.getOperand(ArgOffset + Intr->
NumArgs).getImm();
2152 const bool IsA16 = (
Flags & 1) != 0;
2153 const bool IsG16 = (
Flags & 2) != 0;
2156 if (IsA16 && !STI.hasG16() && !IsG16)
2160 unsigned DMaskLanes = 0;
2162 if (BaseOpcode->
Atomic) {
2164 VDataOut =
MI.getOperand(0).getReg();
2165 VDataIn =
MI.getOperand(2).getReg();
2166 LLT Ty = MRI->getType(VDataIn);
2169 const bool Is64Bit = BaseOpcode->
AtomicX2 ?
2174 assert(
MI.getOperand(3).getReg() == AMDGPU::NoRegister);
2176 DMask = Is64Bit ? 0xf : 0x3;
2177 NumVDataDwords = Is64Bit ? 4 : 2;
2179 DMask = Is64Bit ? 0x3 : 0x1;
2180 NumVDataDwords = Is64Bit ? 2 : 1;
2183 DMask =
static_cast<unsigned>(
2187 if (BaseOpcode->
Store) {
2188 VDataIn =
MI.getOperand(1).getReg();
2189 VDataTy = MRI->getType(VDataIn);
2190 NumVDataDwords =
static_cast<int>((VDataTy.
getSizeInBits() + 31) / 32);
2194 VDataOut =
MI.getOperand(0).getReg();
2195 VDataTy = MRI->getType(VDataOut);
2196 NumVDataDwords = DMaskLanes;
2198 if (IsD16 && !STI.hasUnpackedD16VMem())
2199 NumVDataDwords = (DMaskLanes + 1) / 2;
2204 if (Subtarget->hasG16() && IsG16) {
2205 const AMDGPU::MIMGG16MappingInfo *G16MappingInfo =
2208 IntrOpcode = G16MappingInfo->
G16;
2212 assert((!IsTexFail || DMaskLanes >= 1) &&
"should have legalized this");
2214 unsigned CPol =
static_cast<unsigned>(
2223 int NumVAddrRegs = 0;
2224 int NumVAddrDwords = 0;
2227 MachineOperand &AddrOp =
MI.getOperand(ArgOffset +
I);
2228 if (!AddrOp.
isReg())
2237 static_cast<int>((MRI->getType(Addr).getSizeInBits() + 31) / 32);
2244 NumVAddrRegs != 1 &&
2245 (STI.hasPartialNSAEncoding() ? NumVAddrDwords >= NumVAddrRegs
2246 : NumVAddrDwords == NumVAddrRegs);
2247 if (UseNSA && !STI.hasFeature(AMDGPU::FeatureNSAEncoding)) {
2259 bool IndexedRsrc = MRI->getType(RsrcReg) ==
I32;
2260 bool IndexedSamp =
false;
2263 IndexedSamp = MRI->getType(SampReg) ==
I32;
2267 NumVAddrDwords, IndexedRsrc, IndexedSamp);
2268 }
else if (IsGFX12Plus) {
2270 NumVDataDwords, NumVAddrDwords);
2271 }
else if (IsGFX11Plus) {
2273 UseNSA ? AMDGPU::MIMGEncGfx11NSA
2274 : AMDGPU::MIMGEncGfx11Default,
2275 NumVDataDwords, NumVAddrDwords);
2276 }
else if (IsGFX10Plus) {
2278 UseNSA ? AMDGPU::MIMGEncGfx10NSA
2279 : AMDGPU::MIMGEncGfx10Default,
2280 NumVDataDwords, NumVAddrDwords);
2282 if (Subtarget->hasGFX90AInsts()) {
2284 NumVDataDwords, NumVAddrDwords);
2288 <<
"requested image instruction is not supported on this GPU\n");
2295 NumVDataDwords, NumVAddrDwords);
2298 NumVDataDwords, NumVAddrDwords);
2308 const bool Is64 = MRI->getType(VDataOut).getSizeInBits() == 64;
2310 Register TmpReg = MRI->createVirtualRegister(
2311 Is64 ? &AMDGPU::VReg_128RegClass : &AMDGPU::VReg_64RegClass);
2312 unsigned SubReg = Is64 ? AMDGPU::sub0_sub1 : AMDGPU::sub0;
2315 if (!MRI->use_empty(VDataOut)) {
2317 .
addReg(TmpReg, {}, SubReg);
2328 for (
int I = 0;
I != NumVAddrRegs; ++
I) {
2329 MachineOperand &SrcOp =
MI.getOperand(ArgOffset + Intr->
VAddrStart +
I);
2330 if (SrcOp.
isReg()) {
2349 STI.hasFeature(AMDGPU::FeatureR128A16) ? -1 : 0);
2351 MIB.
addImm(IsA16 ? -1 : 0);
2353 if (!Subtarget->hasGFX90AInsts()) {
2365 MIB.
addImm(IsD16 ? -1 : 0);
2367 MI.eraseFromParent();
2369 TII.enforceOperandRCAlignment(*MIB, AMDGPU::OpName::vaddr);
2375bool AMDGPUInstructionSelector::selectDSBvhStackIntrinsic(
2386 unsigned Offset =
static_cast<unsigned>(
MI.getOperand(6).
getImm());
2390 case Intrinsic::amdgcn_ds_bvh_stack_rtn:
2391 case Intrinsic::amdgcn_ds_bvh_stack_push4_pop1_rtn:
2392 Opc = AMDGPU::DS_BVH_STACK_RTN_B32;
2394 case Intrinsic::amdgcn_ds_bvh_stack_push8_pop1_rtn:
2395 Opc = AMDGPU::DS_BVH_STACK_PUSH8_POP1_RTN_B32;
2397 case Intrinsic::amdgcn_ds_bvh_stack_push8_pop2_rtn:
2398 Opc = AMDGPU::DS_BVH_STACK_PUSH8_POP2_RTN_B64;
2410 MI.eraseFromParent();
2415bool AMDGPUInstructionSelector::selectG_INTRINSIC_W_SIDE_EFFECTS(
2418 switch (IntrinsicID) {
2419 case Intrinsic::amdgcn_end_cf:
2420 return selectEndCfIntrinsic(
I);
2421 case Intrinsic::amdgcn_ds_ordered_add:
2422 case Intrinsic::amdgcn_ds_ordered_swap:
2423 return selectDSOrderedIntrinsic(
I, IntrinsicID);
2424 case Intrinsic::amdgcn_ds_gws_init:
2425 case Intrinsic::amdgcn_ds_gws_barrier:
2426 case Intrinsic::amdgcn_ds_gws_sema_v:
2427 case Intrinsic::amdgcn_ds_gws_sema_br:
2428 case Intrinsic::amdgcn_ds_gws_sema_p:
2429 case Intrinsic::amdgcn_ds_gws_sema_release_all:
2430 return selectDSGWSIntrinsic(
I, IntrinsicID);
2431 case Intrinsic::amdgcn_ds_append:
2432 return selectDSAppendConsume(
I,
true);
2433 case Intrinsic::amdgcn_ds_consume:
2434 return selectDSAppendConsume(
I,
false);
2435 case Intrinsic::amdgcn_init_whole_wave:
2436 return selectInitWholeWave(
I);
2437 case Intrinsic::amdgcn_raw_buffer_load_lds:
2438 case Intrinsic::amdgcn_raw_buffer_load_async_lds:
2439 case Intrinsic::amdgcn_raw_ptr_buffer_load_lds:
2440 case Intrinsic::amdgcn_raw_ptr_buffer_load_async_lds:
2441 case Intrinsic::amdgcn_struct_buffer_load_lds:
2442 case Intrinsic::amdgcn_struct_buffer_load_async_lds:
2443 case Intrinsic::amdgcn_struct_ptr_buffer_load_lds:
2444 case Intrinsic::amdgcn_struct_ptr_buffer_load_async_lds:
2445 return selectBufferLoadLds(
I);
2450 case Intrinsic::amdgcn_load_to_lds:
2451 case Intrinsic::amdgcn_load_async_to_lds:
2452 case Intrinsic::amdgcn_global_load_lds:
2453 case Intrinsic::amdgcn_global_load_async_lds:
2454 return selectGlobalLoadLds(
I);
2455 case Intrinsic::amdgcn_tensor_load_to_lds:
2456 case Intrinsic::amdgcn_tensor_store_from_lds:
2457 return selectTensorLoadStore(
I, IntrinsicID);
2458 case Intrinsic::amdgcn_asyncmark:
2459 case Intrinsic::amdgcn_wait_asyncmark:
2460 if (!Subtarget->hasAsyncMark())
2463 case Intrinsic::amdgcn_ds_bvh_stack_rtn:
2464 case Intrinsic::amdgcn_ds_bvh_stack_push4_pop1_rtn:
2465 case Intrinsic::amdgcn_ds_bvh_stack_push8_pop1_rtn:
2466 case Intrinsic::amdgcn_ds_bvh_stack_push8_pop2_rtn:
2467 return selectDSBvhStackIntrinsic(
I);
2468 case Intrinsic::amdgcn_s_alloc_vgpr: {
2474 Register ResReg =
I.getOperand(0).getReg();
2476 MachineInstr *AllocMI =
BuildMI(*
MBB, &
I,
DL, TII.get(AMDGPU::S_ALLOC_VGPR))
2477 .
add(
I.getOperand(2));
2480 I.eraseFromParent();
2482 return RBI.constrainGenericRegister(ResReg, AMDGPU::SReg_32RegClass, *MRI);
2484 case Intrinsic::amdgcn_s_barrier_init:
2485 case Intrinsic::amdgcn_s_barrier_signal_var:
2486 return selectNamedBarrierInit(
I, IntrinsicID);
2487 case Intrinsic::amdgcn_s_wakeup_barrier:
2488 case Intrinsic::amdgcn_s_barrier_join:
2489 case Intrinsic::amdgcn_s_get_named_barrier_state:
2490 return selectNamedBarrierInst(
I, IntrinsicID);
2491 case Intrinsic::amdgcn_s_get_barrier_state:
2492 return selectSGetBarrierState(
I, IntrinsicID);
2493 case Intrinsic::amdgcn_s_barrier_signal_isfirst:
2494 return selectSBarrierSignalIsfirst(
I, IntrinsicID);
2499bool AMDGPUInstructionSelector::selectG_SELECT(
MachineInstr &
I)
const {
2506 Register DstReg =
I.getOperand(0).getReg();
2509 const MachineOperand &CCOp =
I.getOperand(1);
2511 if (!isVCC(CCReg, *MRI)) {
2512 unsigned SelectOpcode =
Size == 64 ? AMDGPU::S_CSELECT_B64 :
2513 AMDGPU::S_CSELECT_B32;
2514 MachineInstr *CopySCC =
BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::COPY), AMDGPU::SCC)
2520 if (!MRI->getRegClassOrNull(CCReg))
2521 MRI->setRegClass(CCReg, TRI.getConstrainedRegClassForReg(CCReg, *MRI));
2523 .
add(
I.getOperand(2))
2524 .
add(
I.getOperand(3));
2528 I.eraseFromParent();
2537 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::V_CNDMASK_B32_e64), DstReg)
2539 .
add(
I.getOperand(3))
2541 .
add(
I.getOperand(2))
2542 .
add(
I.getOperand(1));
2545 I.eraseFromParent();
2549bool AMDGPUInstructionSelector::selectG_TRUNC(
MachineInstr &
I)
const {
2550 Register DstReg =
I.getOperand(0).getReg();
2551 Register SrcReg =
I.getOperand(1).getReg();
2552 const LLT DstTy = MRI->getType(DstReg);
2553 const LLT SrcTy = MRI->getType(SrcReg);
2556 const RegisterBank *SrcRB = RBI.getRegBank(SrcReg, *MRI, TRI);
2557 const RegisterBank *DstRB;
2563 DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
2568 const bool IsVALU = DstRB->
getID() == AMDGPU::VGPRRegBankID;
2574 TRI.getRegClassForSizeOnBank(SrcSize, *SrcRB);
2576 TRI.getRegClassForSizeOnBank(DstSize, *DstRB);
2577 if (!SrcRC || !DstRC)
2580 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI) ||
2581 !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI)) {
2586 if (DstRC == &AMDGPU::VGPR_16RegClass && SrcSize == 32) {
2587 assert(STI.useRealTrue16Insts());
2591 .
addReg(SrcReg, {}, AMDGPU::lo16);
2592 I.eraseFromParent();
2600 Register LoReg = MRI->createVirtualRegister(DstRC);
2601 Register HiReg = MRI->createVirtualRegister(DstRC);
2603 .
addReg(SrcReg, {}, AMDGPU::sub0);
2605 .
addReg(SrcReg, {}, AMDGPU::sub1);
2607 if (IsVALU && STI.hasSDWA()) {
2610 MachineInstr *MovSDWA =
2611 BuildMI(*
MBB,
I,
DL, TII.get(AMDGPU::V_MOV_B32_sdwa), DstReg)
2621 Register TmpReg0 = MRI->createVirtualRegister(DstRC);
2622 Register TmpReg1 = MRI->createVirtualRegister(DstRC);
2623 Register ImmReg = MRI->createVirtualRegister(DstRC);
2625 BuildMI(*
MBB,
I,
DL, TII.get(AMDGPU::V_LSHLREV_B32_e64), TmpReg0)
2635 unsigned MovOpc = IsVALU ? AMDGPU::V_MOV_B32_e32 : AMDGPU::S_MOV_B32;
2636 unsigned AndOpc = IsVALU ? AMDGPU::V_AND_B32_e64 : AMDGPU::S_AND_B32;
2637 unsigned OrOpc = IsVALU ? AMDGPU::V_OR_B32_e64 : AMDGPU::S_OR_B32;
2649 And.setOperandDead(3);
2650 Or.setOperandDead(3);
2654 I.eraseFromParent();
2662 unsigned SubRegIdx = DstSize < 32
2663 ?
static_cast<unsigned>(AMDGPU::sub0)
2664 : TRI.getSubRegFromChannel(0, DstSize / 32);
2665 if (SubRegIdx == AMDGPU::NoSubRegister)
2671 = TRI.getSubClassWithSubReg(SrcRC, SubRegIdx);
2675 if (SrcWithSubRC != SrcRC) {
2676 if (!RBI.constrainGenericRegister(SrcReg, *SrcWithSubRC, *MRI))
2680 I.getOperand(1).setSubReg(SubRegIdx);
2683 I.setDesc(TII.get(TargetOpcode::COPY));
2690 int SignedMask =
static_cast<int>(Mask);
2691 return SignedMask >= -16 && SignedMask <= 64;
2695const RegisterBank *AMDGPUInstructionSelector::getArtifactRegBank(
2704 return &RBI.getRegBankFromRegClass(*RC, LLT());
2708bool AMDGPUInstructionSelector::selectG_SZA_EXT(
MachineInstr &
I)
const {
2709 bool InReg =
I.getOpcode() == AMDGPU::G_SEXT_INREG;
2710 bool Signed =
I.getOpcode() == AMDGPU::G_SEXT || InReg;
2713 const Register DstReg =
I.getOperand(0).getReg();
2714 const Register SrcReg =
I.getOperand(1).getReg();
2716 const LLT DstTy = MRI->getType(DstReg);
2717 const LLT SrcTy = MRI->getType(SrcReg);
2718 const uint64_t SrcSize =
I.getOpcode() == AMDGPU::G_SEXT_INREG
2719 ?
I.getOperand(2).getImm()
2726 const RegisterBank *SrcBank = getArtifactRegBank(SrcReg, *MRI, TRI);
2729 if (
I.getOpcode() == AMDGPU::G_ANYEXT) {
2731 return selectCOPY(
I);
2734 TRI.getRegClassForTypeOnBank(SrcTy, *SrcBank);
2735 const RegisterBank *DstBank = RBI.getRegBank(DstReg, *MRI, TRI);
2737 TRI.getRegClassForSizeOnBank(DstSize, *DstBank);
2739 Register UndefReg = MRI->createVirtualRegister(SrcRC);
2740 BuildMI(
MBB,
I,
DL, TII.get(AMDGPU::IMPLICIT_DEF), UndefReg);
2746 I.eraseFromParent();
2748 return RBI.constrainGenericRegister(DstReg, *DstRC, *MRI) &&
2749 RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI);
2752 if (SrcBank->
getID() == AMDGPU::VGPRRegBankID && DstSize <= 32) {
2758 MachineInstr *ExtI =
2762 I.eraseFromParent();
2767 const unsigned BFE =
Signed ? AMDGPU::V_BFE_I32_e64 : AMDGPU::V_BFE_U32_e64;
2768 MachineInstr *ExtI =
2773 I.eraseFromParent();
2778 if (SrcBank->
getID() == AMDGPU::SGPRRegBankID && DstSize <= 64) {
2780 AMDGPU::SReg_64RegClass : AMDGPU::SReg_32RegClass;
2781 if (!RBI.constrainGenericRegister(SrcReg, SrcRC, *MRI))
2784 if (
Signed && DstSize == 32 && (SrcSize == 8 || SrcSize == 16)) {
2785 const unsigned SextOpc = SrcSize == 8 ?
2786 AMDGPU::S_SEXT_I32_I8 : AMDGPU::S_SEXT_I32_I16;
2789 I.eraseFromParent();
2790 return RBI.constrainGenericRegister(DstReg, AMDGPU::SReg_32RegClass, *MRI);
2795 if (DstSize > 32 && SrcSize == 32) {
2796 Register HiReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
2797 unsigned SubReg = InReg ? AMDGPU::sub0 : AMDGPU::NoSubRegister;
2800 .
addReg(SrcReg, {}, SubReg)
2808 .
addReg(SrcReg, {}, SubReg)
2809 .addImm(AMDGPU::sub0)
2812 I.eraseFromParent();
2813 return RBI.constrainGenericRegister(DstReg, AMDGPU::SReg_64RegClass,
2817 const unsigned BFE64 =
Signed ? AMDGPU::S_BFE_I64 : AMDGPU::S_BFE_U64;
2818 const unsigned BFE32 =
Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32;
2821 if (DstSize > 32 && (SrcSize <= 32 || InReg)) {
2823 Register ExtReg = MRI->createVirtualRegister(&AMDGPU::SReg_64RegClass);
2824 Register UndefReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
2825 unsigned SubReg = InReg ? AMDGPU::sub0 : AMDGPU::NoSubRegister;
2827 BuildMI(
MBB,
I,
DL, TII.get(AMDGPU::IMPLICIT_DEF), UndefReg);
2829 .
addReg(SrcReg, {}, SubReg)
2830 .addImm(AMDGPU::sub0)
2838 I.eraseFromParent();
2839 return RBI.constrainGenericRegister(DstReg, AMDGPU::SReg_64RegClass, *MRI);
2854 I.eraseFromParent();
2855 return RBI.constrainGenericRegister(DstReg, AMDGPU::SReg_32RegClass, *MRI);
2881 MRI.getType(In).getSizeInBits() == 16) {
2901 if (
MRI.getType(Result).getSizeInBits() != 32)
2914 assert(Mask.size() == 2);
2916 if (Mask[0] == 1 && Mask[1] <= 1) {
2931 if (Unmerge->getNumDefs() == 2 && Unmerge->getOperand(0).getReg() == In &&
2932 MRI.getType(In).getSizeInBits() == 16) {
2941 MRI.getType(Trunc).getSizeInBits() == 32) {
2949bool AMDGPUInstructionSelector::selectG_FPEXT(
MachineInstr &
I)
const {
2950 if (!Subtarget->hasSALUFloatInsts())
2953 Register Dst =
I.getOperand(0).getReg();
2954 const RegisterBank *DstRB = RBI.getRegBank(Dst, *MRI, TRI);
2955 if (DstRB->
getID() != AMDGPU::SGPRRegBankID)
2958 Register Src =
I.getOperand(1).getReg();
2964 BuildMI(*BB, &
I,
I.getDebugLoc(), TII.get(AMDGPU::S_CVT_HI_F32_F16), Dst)
2966 I.eraseFromParent();
2967 return RBI.constrainGenericRegister(Dst, AMDGPU::SReg_32RegClass, *MRI);
2974bool AMDGPUInstructionSelector::selectG_FNEG(
MachineInstr &
MI)
const {
2987 const RegisterBank *DstRB = RBI.getRegBank(Dst, *MRI, TRI);
2988 if (DstRB->
getID() != AMDGPU::SGPRRegBankID ||
2993 MachineInstr *Fabs =
getOpcodeDef(TargetOpcode::G_FABS, Src, *MRI);
2997 if (!RBI.constrainGenericRegister(Src, AMDGPU::SReg_64RegClass, *MRI) ||
2998 !RBI.constrainGenericRegister(Dst, AMDGPU::SReg_64RegClass, *MRI))
3003 Register LoReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
3004 Register HiReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
3005 Register ConstReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
3006 Register OpReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
3008 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::COPY), LoReg)
3009 .
addReg(Src, {}, AMDGPU::sub0);
3010 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::COPY), HiReg)
3011 .
addReg(Src, {}, AMDGPU::sub1);
3012 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::S_MOV_B32), ConstReg)
3016 unsigned Opc = Fabs ? AMDGPU::S_OR_B32 : AMDGPU::S_XOR_B32;
3021 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::REG_SEQUENCE), Dst)
3026 MI.eraseFromParent();
3031bool AMDGPUInstructionSelector::selectG_FABS(
MachineInstr &
MI)
const {
3033 const RegisterBank *DstRB = RBI.getRegBank(Dst, *MRI, TRI);
3034 if (DstRB->
getID() != AMDGPU::SGPRRegBankID ||
3041 Register LoReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
3042 Register HiReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
3043 Register ConstReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
3044 Register OpReg = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
3046 if (!RBI.constrainGenericRegister(Src, AMDGPU::SReg_64RegClass, *MRI) ||
3047 !RBI.constrainGenericRegister(Dst, AMDGPU::SReg_64RegClass, *MRI))
3050 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::COPY), LoReg)
3051 .
addReg(Src, {}, AMDGPU::sub0);
3052 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::COPY), HiReg)
3053 .
addReg(Src, {}, AMDGPU::sub1);
3054 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::S_MOV_B32), ConstReg)
3059 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::S_AND_B32), OpReg)
3063 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::REG_SEQUENCE), Dst)
3069 MI.eraseFromParent();
3074 return MI.getOpcode() == TargetOpcode::G_CONSTANT;
3080 unsigned OpNo =
Load.getOpcode() == AMDGPU::G_PREFETCH ? 0 : 1;
3081 const MachineInstr *PtrMI =
3082 MRI.getUniqueVRegDef(
Load.getOperand(OpNo).getReg());
3086 if (PtrMI->
getOpcode() != TargetOpcode::G_PTR_ADD)
3091 for (
unsigned i = 1; i != 3; ++i) {
3092 const MachineOperand &GEPOp = PtrMI->
getOperand(i);
3093 const MachineInstr *OpDef = MRI.getUniqueVRegDef(GEPOp.
getReg());
3098 assert(GEPInfo.Imm == 0);
3102 const RegisterBank *OpBank = RBI.getRegBank(GEPOp.
getReg(), MRI, TRI);
3103 if (OpBank->
getID() == AMDGPU::SGPRRegBankID)
3104 GEPInfo.SgprParts.push_back(GEPOp.
getReg());
3106 GEPInfo.VgprParts.push_back(GEPOp.
getReg());
3110 getAddrModeInfo(*PtrMI, MRI, AddrInfo);
3113bool AMDGPUInstructionSelector::isSGPR(
Register Reg)
const {
3114 return RBI.getRegBank(
Reg, *MRI, TRI)->getID() == AMDGPU::SGPRRegBankID;
3117bool AMDGPUInstructionSelector::isInstrUniform(
const MachineInstr &
MI)
const {
3118 if (!
MI.hasOneMemOperand())
3121 const MachineMemOperand *MMO = *
MI.memoperands_begin();
3134 if (
MI.getOpcode() == AMDGPU::G_PREFETCH)
3135 return RBI.getRegBank(
MI.getOperand(0).getReg(), *MRI, TRI)->getID() ==
3136 AMDGPU::SGPRRegBankID;
3139 return I &&
I->getMetadata(
"amdgpu.uniform");
3143 for (
const GEPInfo &GEPInfo : AddrInfo) {
3144 if (!GEPInfo.VgprParts.empty())
3150void AMDGPUInstructionSelector::initM0(
MachineInstr &
I)
const {
3151 const LLT PtrTy = MRI->getType(
I.getOperand(1).getReg());
3154 STI.ldsRequiresM0Init()) {
3158 BuildMI(*BB, &
I,
I.getDebugLoc(), TII.get(AMDGPU::S_MOV_B32), AMDGPU::M0)
3163bool AMDGPUInstructionSelector::selectG_LOAD_STORE_ATOMICRMW(
3170 if (
Reg.isPhysical())
3174 const unsigned Opcode =
MI.getOpcode();
3176 if (Opcode == AMDGPU::COPY)
3179 if (Opcode == AMDGPU::G_AND || Opcode == AMDGPU::G_OR ||
3180 Opcode == AMDGPU::G_XOR)
3185 return GI->is(Intrinsic::amdgcn_class);
3187 return Opcode == AMDGPU::G_ICMP || Opcode == AMDGPU::G_FCMP;
3190bool AMDGPUInstructionSelector::selectG_BRCOND(
MachineInstr &
I)
const {
3192 MachineOperand &CondOp =
I.getOperand(0);
3205 if (!isVCC(CondReg, *MRI)) {
3209 CondPhysReg = AMDGPU::SCC;
3210 BrOpcode = AMDGPU::S_CBRANCH_SCC1;
3211 ConstrainRC = &AMDGPU::SReg_32RegClass;
3218 const bool Is64 = STI.isWave64();
3219 const unsigned Opcode = Is64 ? AMDGPU::S_AND_B64 : AMDGPU::S_AND_B32;
3220 const Register Exec = Is64 ? AMDGPU::EXEC : AMDGPU::EXEC_LO;
3222 Register TmpReg = MRI->createVirtualRegister(TRI.getBoolRC());
3223 BuildMI(*BB, &
I,
DL, TII.get(Opcode), TmpReg)
3230 CondPhysReg = TRI.getVCC();
3231 BrOpcode = AMDGPU::S_CBRANCH_VCCNZ;
3232 ConstrainRC = TRI.getBoolRC();
3235 if (!MRI->getRegClassOrNull(CondReg))
3236 MRI->setRegClass(CondReg, ConstrainRC);
3238 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::COPY), CondPhysReg)
3241 .
addMBB(
I.getOperand(1).getMBB());
3243 I.eraseFromParent();
3247bool AMDGPUInstructionSelector::selectG_GLOBAL_VALUE(
3249 Register DstReg =
I.getOperand(0).getReg();
3250 const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
3251 const bool IsVGPR = DstRB->
getID() == AMDGPU::VGPRRegBankID;
3252 I.setDesc(TII.get(IsVGPR ? AMDGPU::V_MOV_B32_e32 : AMDGPU::S_MOV_B32));
3256 return RBI.constrainGenericRegister(
3257 DstReg, IsVGPR ? AMDGPU::VGPR_32RegClass : AMDGPU::SReg_32RegClass, *MRI);
3260bool AMDGPUInstructionSelector::selectG_PTRMASK(
MachineInstr &
I)
const {
3261 Register DstReg =
I.getOperand(0).getReg();
3262 Register SrcReg =
I.getOperand(1).getReg();
3263 Register MaskReg =
I.getOperand(2).getReg();
3264 LLT Ty = MRI->getType(DstReg);
3265 LLT MaskTy = MRI->getType(MaskReg);
3269 const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
3270 const RegisterBank *SrcRB = RBI.getRegBank(SrcReg, *MRI, TRI);
3271 const RegisterBank *MaskRB = RBI.getRegBank(MaskReg, *MRI, TRI);
3272 const bool IsVGPR = DstRB->
getID() == AMDGPU::VGPRRegBankID;
3278 APInt MaskOnes =
VT->getKnownOnes(MaskReg).zext(64);
3282 const bool CanCopyLow32 = (MaskOnes & MaskLo32) == MaskLo32;
3283 const bool CanCopyHi32 = (MaskOnes & MaskHi32) == MaskHi32;
3286 !CanCopyLow32 && !CanCopyHi32) {
3287 auto MIB =
BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::S_AND_B64), DstReg)
3291 I.eraseFromParent();
3296 unsigned NewOpc = IsVGPR ? AMDGPU::V_AND_B32_e64 : AMDGPU::S_AND_B32;
3298 = IsVGPR ? AMDGPU::VGPR_32RegClass : AMDGPU::SReg_32RegClass;
3303 TRI.getRegClassForTypeOnBank(MaskTy, *MaskRB);
3305 if (!RBI.constrainGenericRegister(DstReg, *DstRC, *MRI) ||
3306 !RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI) ||
3307 !RBI.constrainGenericRegister(MaskReg, *MaskRC, *MRI))
3312 "ptrmask should have been narrowed during legalize");
3314 auto NewOp =
BuildMI(*BB, &
I,
DL, TII.get(NewOpc), DstReg)
3320 I.eraseFromParent();
3324 Register HiReg = MRI->createVirtualRegister(&RegRC);
3325 Register LoReg = MRI->createVirtualRegister(&RegRC);
3328 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::COPY), LoReg)
3329 .
addReg(SrcReg, {}, AMDGPU::sub0);
3330 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::COPY), HiReg)
3331 .
addReg(SrcReg, {}, AMDGPU::sub1);
3340 Register MaskLo = MRI->createVirtualRegister(&RegRC);
3341 MaskedLo = MRI->createVirtualRegister(&RegRC);
3343 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::COPY), MaskLo)
3344 .
addReg(MaskReg, {}, AMDGPU::sub0);
3345 BuildMI(*BB, &
I,
DL, TII.get(NewOpc), MaskedLo)
3354 Register MaskHi = MRI->createVirtualRegister(&RegRC);
3355 MaskedHi = MRI->createVirtualRegister(&RegRC);
3357 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::COPY), MaskHi)
3358 .
addReg(MaskReg, {}, AMDGPU::sub1);
3359 BuildMI(*BB, &
I,
DL, TII.get(NewOpc), MaskedHi)
3364 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::REG_SEQUENCE), DstReg)
3369 I.eraseFromParent();
3375static std::pair<Register, unsigned>
3382 std::tie(IdxBaseReg,
Offset) =
3384 if (IdxBaseReg == AMDGPU::NoRegister) {
3388 IdxBaseReg = IdxReg;
3395 if (
static_cast<unsigned>(
Offset) >= SubRegs.
size())
3396 return std::pair(IdxReg, SubRegs[0]);
3397 return std::pair(IdxBaseReg, SubRegs[
Offset]);
3400bool AMDGPUInstructionSelector::selectG_EXTRACT_VECTOR_ELT(
3406 LLT DstTy = MRI->getType(DstReg);
3407 LLT SrcTy = MRI->getType(SrcReg);
3409 const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
3410 const RegisterBank *SrcRB = RBI.getRegBank(SrcReg, *MRI, TRI);
3411 const RegisterBank *IdxRB = RBI.getRegBank(IdxReg, *MRI, TRI);
3415 if (IdxRB->
getID() != AMDGPU::SGPRRegBankID)
3419 TRI.getRegClassForTypeOnBank(SrcTy, *SrcRB);
3421 TRI.getRegClassForTypeOnBank(DstTy, *DstRB);
3422 if (!SrcRC || !DstRC)
3424 if (!RBI.constrainGenericRegister(SrcReg, *SrcRC, *MRI) ||
3425 !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI) ||
3426 !RBI.constrainGenericRegister(IdxReg, AMDGPU::SReg_32RegClass, *MRI))
3435 *MRI, TRI, SrcRC, IdxReg,
3438 if (SrcRB->
getID() == AMDGPU::SGPRRegBankID) {
3442 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::COPY), AMDGPU::M0)
3445 unsigned Opc = Is64 ? AMDGPU::S_MOVRELS_B64 : AMDGPU::S_MOVRELS_B32;
3447 .
addReg(SrcReg, {}, SubReg)
3449 MI.eraseFromParent();
3456 if (!STI.useVGPRIndexMode()) {
3457 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::COPY), AMDGPU::M0)
3459 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::V_MOVRELS_B32_e32), DstReg)
3460 .
addReg(SrcReg, {}, SubReg)
3462 MI.eraseFromParent();
3466 const MCInstrDesc &GPRIDXDesc = TII.getIndirectGPRIDXPseudo(
3467 static_cast<unsigned>(TRI.getRegSizeInBits(*SrcRC)),
true);
3473 MI.eraseFromParent();
3478bool AMDGPUInstructionSelector::selectG_INSERT_VECTOR_ELT(
3485 LLT VecTy = MRI->getType(DstReg);
3486 LLT ValTy = MRI->getType(ValReg);
3488 unsigned ValSize =
static_cast<unsigned>(ValTy.
getSizeInBits());
3490 const RegisterBank *VecRB = RBI.getRegBank(VecReg, *MRI, TRI);
3491 const RegisterBank *ValRB = RBI.getRegBank(ValReg, *MRI, TRI);
3492 const RegisterBank *IdxRB = RBI.getRegBank(IdxReg, *MRI, TRI);
3498 if (IdxRB->
getID() != AMDGPU::SGPRRegBankID)
3502 TRI.getRegClassForTypeOnBank(VecTy, *VecRB);
3504 TRI.getRegClassForTypeOnBank(ValTy, *ValRB);
3506 if (!RBI.constrainGenericRegister(VecReg, *VecRC, *MRI) ||
3507 !RBI.constrainGenericRegister(DstReg, *VecRC, *MRI) ||
3508 !RBI.constrainGenericRegister(ValReg, *ValRC, *MRI) ||
3509 !RBI.constrainGenericRegister(IdxReg, AMDGPU::SReg_32RegClass, *MRI))
3512 if (VecRB->
getID() == AMDGPU::VGPRRegBankID && ValSize != 32)
3516 std::tie(IdxReg, SubReg) =
3519 const bool IndexMode = VecRB->
getID() == AMDGPU::VGPRRegBankID &&
3520 STI.useVGPRIndexMode();
3526 BuildMI(*BB, &
MI,
DL, TII.get(AMDGPU::COPY), AMDGPU::M0)
3529 const MCInstrDesc &RegWriteOp = TII.getIndirectRegWriteMovRelPseudo(
3530 VecSize, ValSize, VecRB->
getID() == AMDGPU::SGPRRegBankID);
3535 MI.eraseFromParent();
3539 const MCInstrDesc &GPRIDXDesc = TII.getIndirectGPRIDXPseudo(
3540 static_cast<unsigned>(TRI.getRegSizeInBits(*VecRC)),
false);
3547 MI.eraseFromParent();
3553 case Intrinsic::amdgcn_raw_buffer_load_async_lds:
3554 case Intrinsic::amdgcn_raw_ptr_buffer_load_async_lds:
3555 case Intrinsic::amdgcn_struct_buffer_load_async_lds:
3556 case Intrinsic::amdgcn_struct_ptr_buffer_load_async_lds:
3557 case Intrinsic::amdgcn_load_async_to_lds:
3558 case Intrinsic::amdgcn_global_load_async_lds:
3564bool AMDGPUInstructionSelector::selectBufferLoadLds(
MachineInstr &
MI)
const {
3565 if (!Subtarget->hasVMemToLDSLoad())
3568 unsigned Size =
static_cast<unsigned>(
MI.getOperand(3).
getImm());
3572 const bool HasVIndex =
MI.getNumOperands() == 9;
3576 VIndex =
MI.getOperand(4).getReg();
3580 Register VOffset =
MI.getOperand(4 + OpOffset).getReg();
3581 std::optional<ValueAndVReg> MaybeVOffset =
3583 const bool HasVOffset = !MaybeVOffset || MaybeVOffset->Value.getZExtValue();
3589 Opc = HasVIndex ? HasVOffset ? AMDGPU::BUFFER_LOAD_UBYTE_LDS_BOTHEN
3590 : AMDGPU::BUFFER_LOAD_UBYTE_LDS_IDXEN
3591 : HasVOffset ? AMDGPU::BUFFER_LOAD_UBYTE_LDS_OFFEN
3592 : AMDGPU::BUFFER_LOAD_UBYTE_LDS_OFFSET;
3595 Opc = HasVIndex ? HasVOffset ? AMDGPU::BUFFER_LOAD_USHORT_LDS_BOTHEN
3596 : AMDGPU::BUFFER_LOAD_USHORT_LDS_IDXEN
3597 : HasVOffset ? AMDGPU::BUFFER_LOAD_USHORT_LDS_OFFEN
3598 : AMDGPU::BUFFER_LOAD_USHORT_LDS_OFFSET;
3601 Opc = HasVIndex ? HasVOffset ? AMDGPU::BUFFER_LOAD_DWORD_LDS_BOTHEN
3602 : AMDGPU::BUFFER_LOAD_DWORD_LDS_IDXEN
3603 : HasVOffset ? AMDGPU::BUFFER_LOAD_DWORD_LDS_OFFEN
3604 : AMDGPU::BUFFER_LOAD_DWORD_LDS_OFFSET;
3607 if (!Subtarget->hasLDSLoadB96_B128())
3610 Opc = HasVIndex ? HasVOffset ? AMDGPU::BUFFER_LOAD_DWORDX3_LDS_BOTHEN
3611 : AMDGPU::BUFFER_LOAD_DWORDX3_LDS_IDXEN
3612 : HasVOffset ? AMDGPU::BUFFER_LOAD_DWORDX3_LDS_OFFEN
3613 : AMDGPU::BUFFER_LOAD_DWORDX3_LDS_OFFSET;
3616 if (!Subtarget->hasLDSLoadB96_B128())
3619 Opc = HasVIndex ? HasVOffset ? AMDGPU::BUFFER_LOAD_DWORDX4_LDS_BOTHEN
3620 : AMDGPU::BUFFER_LOAD_DWORDX4_LDS_IDXEN
3621 : HasVOffset ? AMDGPU::BUFFER_LOAD_DWORDX4_LDS_OFFEN
3622 : AMDGPU::BUFFER_LOAD_DWORDX4_LDS_OFFSET;
3629 .
add(
MI.getOperand(2));
3633 if (HasVIndex && HasVOffset) {
3634 Register IdxReg = MRI->createVirtualRegister(TRI.getVGPR64Class());
3635 BuildMI(*
MBB, &*MIB,
DL, TII.get(AMDGPU::REG_SEQUENCE), IdxReg)
3642 }
else if (HasVIndex) {
3644 }
else if (HasVOffset) {
3648 MIB.
add(
MI.getOperand(1));
3649 MIB.
add(
MI.getOperand(5 + OpOffset));
3650 MIB.
add(
MI.getOperand(6 + OpOffset));
3652 int64_t Aux =
MI.getOperand(7 + OpOffset).getImm();
3661 MachineMemOperand *LoadMMO = *
MI.memoperands_begin();
3666 MachinePointerInfo StorePtrI = LoadPtrI;
3677 MachineMemOperand *StoreMMO =
3683 MI.eraseFromParent();
3696 if (
Def->getOpcode() != AMDGPU::G_MERGE_VALUES)
3702 return Def->getOperand(1).getReg();
3716 if (
Def->getOpcode() != AMDGPU::G_MERGE_VALUES)
3724 return Def->getOperand(1).getReg();
3727 if (ZextSrc &&
VT->signBitIsZero(ZextSrc))
3736AMDGPUInstructionSelector::matchZeroExtendFromS32OrS32(
Register Reg)
const {
3738 : matchZeroExtendFromS32(
Reg);
3744AMDGPUInstructionSelector::matchSignExtendFromS32OrS32(
Register Reg)
const {
3746 : matchSignExtendFromS32(
Reg);
3750AMDGPUInstructionSelector::matchExtendFromS32OrS32(
Register Reg,
3751 bool IsSigned)
const {
3753 return matchSignExtendFromS32OrS32(
Reg);
3755 return matchZeroExtendFromS32OrS32(
Reg);
3765 if (
Def->getOpcode() != AMDGPU::G_MERGE_VALUES)
3772 return Def->getOperand(1).getReg();
3777bool AMDGPUInstructionSelector::selectGlobalLoadLds(
MachineInstr &
MI)
const{
3778 if (!Subtarget->hasVMemToLDSLoad())
3782 unsigned Size =
static_cast<unsigned>(
MI.getOperand(3).
getImm());
3789 Opc = AMDGPU::GLOBAL_LOAD_LDS_UBYTE;
3792 Opc = AMDGPU::GLOBAL_LOAD_LDS_USHORT;
3795 Opc = AMDGPU::GLOBAL_LOAD_LDS_DWORD;
3798 if (!Subtarget->hasLDSLoadB96_B128())
3800 Opc = AMDGPU::GLOBAL_LOAD_LDS_DWORDX3;
3803 if (!Subtarget->hasLDSLoadB96_B128())
3805 Opc = AMDGPU::GLOBAL_LOAD_LDS_DWORDX4;
3812 .
add(
MI.getOperand(2));
3818 if (!isSGPR(Addr)) {
3820 if (isSGPR(AddrDef->Reg)) {
3821 Addr = AddrDef->Reg;
3822 }
else if (AddrDef->MI->getOpcode() == AMDGPU::G_PTR_ADD) {
3825 if (isSGPR(SAddr)) {
3826 Register PtrBaseOffset = AddrDef->MI->getOperand(2).getReg();
3827 if (
Register Off = matchZeroExtendFromS32(PtrBaseOffset)) {
3838 VOffset = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
3850 MIB.
add(
MI.getOperand(4));
3852 unsigned Aux =
static_cast<unsigned>(
MI.getOperand(5).
getImm());
3856 MachineMemOperand *LoadMMO = *
MI.memoperands_begin();
3858 LoadPtrI.
Offset =
MI.getOperand(4).getImm();
3859 MachinePointerInfo StorePtrI = LoadPtrI;
3868 MachineMemOperand *StoreMMO =
3870 sizeof(int32_t),
Align(4));
3874 MI.eraseFromParent();
3879bool AMDGPUInstructionSelector::selectTensorLoadStore(
MachineInstr &
MI,
3881 bool IsLoad = IID == Intrinsic::amdgcn_tensor_load_to_lds;
3883 IsLoad ? AMDGPU::TENSOR_LOAD_TO_LDS_d4 : AMDGPU::TENSOR_STORE_FROM_LDS_d4;
3887 const auto isAllZeros = [&](MachineOperand &Opnd) {
3888 const MachineInstr *
DefMI = MRI->getVRegDef(Opnd.getReg());
3897 Opc = IsLoad ? AMDGPU::TENSOR_LOAD_TO_LDS_d2
3898 : AMDGPU::TENSOR_STORE_FROM_LDS_d2;
3905 .
add(
MI.getOperand(1))
3906 .
add(
MI.getOperand(2));
3908 if (NumGroups >= 4) {
3909 MIB.
add(
MI.getOperand(3))
3910 .
add(
MI.getOperand(4));
3914 .
add(
MI.getOperand(6));
3916 MI.eraseFromParent();
3920bool AMDGPUInstructionSelector::selectBVHIntersectRayIntrinsic(
3922 unsigned OpcodeOpIdx =
3923 MI.getOpcode() == AMDGPU::G_AMDGPU_BVH_INTERSECT_RAY ? 1 : 3;
3925 TII.get(
static_cast<unsigned>(
MI.getOperand(OpcodeOpIdx).getImm())));
3926 MI.removeOperand(OpcodeOpIdx);
3927 MI.addImplicitDefUseOperands(*
MI.getMF());
3934bool AMDGPUInstructionSelector::selectSMFMACIntrin(
MachineInstr &
MI)
const {
3937 case Intrinsic::amdgcn_smfmac_f32_16x16x32_f16:
3938 Opc = AMDGPU::V_SMFMAC_F32_16X16X32_F16_e64;
3940 case Intrinsic::amdgcn_smfmac_f32_32x32x16_f16:
3941 Opc = AMDGPU::V_SMFMAC_F32_32X32X16_F16_e64;
3943 case Intrinsic::amdgcn_smfmac_f32_16x16x32_bf16:
3944 Opc = AMDGPU::V_SMFMAC_F32_16X16X32_BF16_e64;
3946 case Intrinsic::amdgcn_smfmac_f32_32x32x16_bf16:
3947 Opc = AMDGPU::V_SMFMAC_F32_32X32X16_BF16_e64;
3949 case Intrinsic::amdgcn_smfmac_i32_16x16x64_i8:
3950 Opc = AMDGPU::V_SMFMAC_I32_16X16X64_I8_e64;
3952 case Intrinsic::amdgcn_smfmac_i32_32x32x32_i8:
3953 Opc = AMDGPU::V_SMFMAC_I32_32X32X32_I8_e64;
3955 case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf8_bf8:
3956 Opc = AMDGPU::V_SMFMAC_F32_16X16X64_BF8_BF8_e64;
3958 case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf8_fp8:
3959 Opc = AMDGPU::V_SMFMAC_F32_16X16X64_BF8_FP8_e64;
3961 case Intrinsic::amdgcn_smfmac_f32_16x16x64_fp8_bf8:
3962 Opc = AMDGPU::V_SMFMAC_F32_16X16X64_FP8_BF8_e64;
3964 case Intrinsic::amdgcn_smfmac_f32_16x16x64_fp8_fp8:
3965 Opc = AMDGPU::V_SMFMAC_F32_16X16X64_FP8_FP8_e64;
3967 case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf8_bf8:
3968 Opc = AMDGPU::V_SMFMAC_F32_32X32X32_BF8_BF8_e64;
3970 case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf8_fp8:
3971 Opc = AMDGPU::V_SMFMAC_F32_32X32X32_BF8_FP8_e64;
3973 case Intrinsic::amdgcn_smfmac_f32_32x32x32_fp8_bf8:
3974 Opc = AMDGPU::V_SMFMAC_F32_32X32X32_FP8_BF8_e64;
3976 case Intrinsic::amdgcn_smfmac_f32_32x32x32_fp8_fp8:
3977 Opc = AMDGPU::V_SMFMAC_F32_32X32X32_FP8_FP8_e64;
3979 case Intrinsic::amdgcn_smfmac_f32_16x16x64_f16:
3980 Opc = AMDGPU::V_SMFMAC_F32_16X16X64_F16_e64;
3982 case Intrinsic::amdgcn_smfmac_f32_32x32x32_f16:
3983 Opc = AMDGPU::V_SMFMAC_F32_32X32X32_F16_e64;
3985 case Intrinsic::amdgcn_smfmac_f32_16x16x64_bf16:
3986 Opc = AMDGPU::V_SMFMAC_F32_16X16X64_BF16_e64;
3988 case Intrinsic::amdgcn_smfmac_f32_32x32x32_bf16:
3989 Opc = AMDGPU::V_SMFMAC_F32_32X32X32_BF16_e64;
3991 case Intrinsic::amdgcn_smfmac_i32_16x16x128_i8:
3992 Opc = AMDGPU::V_SMFMAC_I32_16X16X128_I8_e64;
3994 case Intrinsic::amdgcn_smfmac_i32_32x32x64_i8:
3995 Opc = AMDGPU::V_SMFMAC_I32_32X32X64_I8_e64;
3997 case Intrinsic::amdgcn_smfmac_f32_16x16x128_bf8_bf8:
3998 Opc = AMDGPU::V_SMFMAC_F32_16X16X128_BF8_BF8_e64;
4000 case Intrinsic::amdgcn_smfmac_f32_16x16x128_bf8_fp8:
4001 Opc = AMDGPU::V_SMFMAC_F32_16X16X128_BF8_FP8_e64;
4003 case Intrinsic::amdgcn_smfmac_f32_16x16x128_fp8_bf8:
4004 Opc = AMDGPU::V_SMFMAC_F32_16X16X128_FP8_BF8_e64;
4006 case Intrinsic::amdgcn_smfmac_f32_16x16x128_fp8_fp8:
4007 Opc = AMDGPU::V_SMFMAC_F32_16X16X128_FP8_FP8_e64;
4009 case Intrinsic::amdgcn_smfmac_f32_32x32x64_bf8_bf8:
4010 Opc = AMDGPU::V_SMFMAC_F32_32X32X64_BF8_BF8_e64;
4012 case Intrinsic::amdgcn_smfmac_f32_32x32x64_bf8_fp8:
4013 Opc = AMDGPU::V_SMFMAC_F32_32X32X64_BF8_FP8_e64;
4015 case Intrinsic::amdgcn_smfmac_f32_32x32x64_fp8_bf8:
4016 Opc = AMDGPU::V_SMFMAC_F32_32X32X64_FP8_BF8_e64;
4018 case Intrinsic::amdgcn_smfmac_f32_32x32x64_fp8_fp8:
4019 Opc = AMDGPU::V_SMFMAC_F32_32X32X64_FP8_FP8_e64;
4025 auto VDst_In =
MI.getOperand(4);
4027 MI.setDesc(TII.get(
Opc));
4028 MI.removeOperand(4);
4029 MI.removeOperand(1);
4030 MI.addOperand(VDst_In);
4031 MI.addImplicitDefUseOperands(*
MI.getMF());
4032 const MCInstrDesc &MCID =
MI.getDesc();
4034 MI.getOperand(0).setIsEarlyClobber(
true);
4039bool AMDGPUInstructionSelector::selectPermlaneSwapIntrin(
4041 if (IntrID == Intrinsic::amdgcn_permlane16_swap &&
4042 !Subtarget->hasPermlane16Swap())
4044 if (IntrID == Intrinsic::amdgcn_permlane32_swap &&
4045 !Subtarget->hasPermlane32Swap())
4048 unsigned Opcode = IntrID == Intrinsic::amdgcn_permlane16_swap
4049 ? AMDGPU::V_PERMLANE16_SWAP_B32_e64
4050 : AMDGPU::V_PERMLANE32_SWAP_B32_e64;
4052 MI.removeOperand(2);
4053 MI.setDesc(TII.get(Opcode));
4056 MachineOperand &FI =
MI.getOperand(4);
4063bool AMDGPUInstructionSelector::selectWaveAddress(
MachineInstr &
MI)
const {
4066 const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
4067 const bool IsVALU = DstRB->
getID() == AMDGPU::VGPRRegBankID;
4072 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::V_LSHRREV_B32_e64), DstReg)
4073 .
addImm(Subtarget->getWavefrontSizeLog2())
4078 .
addImm(Subtarget->getWavefrontSizeLog2())
4083 IsVALU ? AMDGPU::VGPR_32RegClass : AMDGPU::SReg_32RegClass;
4084 if (!RBI.constrainGenericRegister(DstReg, RC, *MRI))
4087 MI.eraseFromParent();
4091bool AMDGPUInstructionSelector::selectWaveShuffleIntrin(
4101 const LLT DstTy = MRI->getType(DstReg);
4103 const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
4105 TRI.getRegClassForSizeOnBank(DstSize, *DstRB);
4110 if (!Subtarget->supportsBPermute())
4114 if (Subtarget->supportsWaveWideBPermute()) {
4115 Register ShiftIdxReg = MRI->createVirtualRegister(DstRC);
4116 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::V_LSHLREV_B32_e64), ShiftIdxReg)
4126 assert(Subtarget->isWave64());
4130 MRI->createVirtualRegister(TRI.getRegClass(AMDGPU::SReg_32RegClassID));
4131 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::IMPLICIT_DEF), UndefValReg);
4133 Register UndefExecReg = MRI->createVirtualRegister(
4134 TRI.getRegClass(AMDGPU::SReg_64_XEXECRegClassID));
4135 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::IMPLICIT_DEF), UndefExecReg);
4137 Register PoisonValReg = MRI->createVirtualRegister(DstRC);
4138 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::V_SET_INACTIVE_B32), PoisonValReg)
4146 Register ShiftIdxReg = MRI->createVirtualRegister(DstRC);
4147 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::V_LSHLREV_B32_e64), ShiftIdxReg)
4151 Register PoisonIdxReg = MRI->createVirtualRegister(DstRC);
4152 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::V_SET_INACTIVE_B32), PoisonIdxReg)
4159 Register PoisonUnshiftedIdxReg = MRI->createVirtualRegister(DstRC);
4161 PoisonUnshiftedIdxReg)
4169 Register SameSidePermReg = MRI->createVirtualRegister(DstRC);
4170 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::DS_BPERMUTE_B32), SameSidePermReg)
4175 Register SwappedValReg = MRI->createVirtualRegister(DstRC);
4176 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::V_PERMLANE64_B32), SwappedValReg)
4179 Register OppSidePermReg = MRI->createVirtualRegister(DstRC);
4180 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::DS_BPERMUTE_B32), OppSidePermReg)
4185 Register WWMSwapPermReg = MRI->createVirtualRegister(DstRC);
4186 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::STRICT_WWM), WWMSwapPermReg)
4193 Register ThreadIDReg = MRI->createVirtualRegister(DstRC);
4194 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::V_MBCNT_LO_U32_B32_e64), ThreadIDReg)
4198 Register XORReg = MRI->createVirtualRegister(DstRC);
4201 .
addReg(PoisonUnshiftedIdxReg);
4203 Register ANDReg = MRI->createVirtualRegister(DstRC);
4208 Register CompareReg = MRI->createVirtualRegister(
4209 TRI.getRegClass(AMDGPU::SReg_64_XEXECRegClassID));
4210 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::V_CMP_EQ_U32_e64), CompareReg)
4215 BuildMI(*
MBB,
MI,
DL, TII.get(AMDGPU::V_CNDMASK_B32_e64), DstReg)
4223 MI.eraseFromParent();
4232 unsigned NumOpcodes = 0;
4245 const uint8_t SrcBits[3] = { 0xf0, 0xcc, 0xaa };
4256 for (
unsigned I = 0;
I < Src.size(); ++
I) {
4270 if (Src.size() == 3) {
4277 for (
unsigned I = 0;
I < Src.size(); ++
I) {
4278 if (Src[
I] ==
LHS) {
4288 Bits = SrcBits[Src.size()];
4294 switch (
MI->getOpcode()) {
4295 case TargetOpcode::G_AND:
4296 case TargetOpcode::G_OR:
4297 case TargetOpcode::G_XOR: {
4302 if (!getOperandBits(
LHS, LHSBits) ||
4303 !getOperandBits(
RHS, RHSBits)) {
4304 Src = std::move(Backup);
4326 uint8_t LHSBitsOrig = LHSBits;
4327 uint8_t RHSBitsOrig = RHSBits;
4331 NumOpcodes += LHSOp.first;
4332 LHSBits = LHSOp.second;
4339 NumOpcodes += RHSOp.first;
4340 RHSBits = RHSOp.second;
4344 auto dependsOnSlot = [](
uint8_t TT,
int Slot) ->
bool {
4345 if (Slot < 0 || Slot > 2)
4347 const uint8_t Masks[3] = {0x0f, 0x33, 0x55};
4348 const int Shifts[3] = {4, 2, 1};
4349 return ((TT ^ (TT >> Shifts[Slot])) & Masks[Slot]) != 0;
4355 const uint8_t SrcBitsConst[3] = {0xf0, 0xcc, 0xaa};
4362 for (
int I = 0;
I < (int)S.size();
I++) {
4363 if (Bits == SrcBitsConst[
I] && S[
I] ==
Op)
4365 if (IsNegationOp && Bits == (
uint8_t)~SrcBitsConst[
I] &&
4366 S[
I] == NegatedInner)
4377 for (
int I = 0;
I < (int)SrcAfterLHS.
size() &&
I < 3;
I++) {
4378 if (
I < (
int)Src.size() && Src[
I] != SrcAfterLHS[
I] &&
4379 dependsOnSlot(LHSBits,
I)) {
4388 if (!Stale && !RHSOp.first) {
4389 int Slot = findSlot(RHSBitsOrig,
RHS, SrcBeforeRecurse);
4391 (Slot >= (
int)Src.size() || Src[Slot] != SrcBeforeRecurse[Slot]))
4397 if (!Stale && !LHSOp.first) {
4398 int Slot = findSlot(LHSBitsOrig,
LHS, SrcBeforeRecurse);
4400 (Slot >= (
int)Src.size() || Src[Slot] != SrcBeforeRecurse[Slot]))
4405 Src = std::move(SrcBeforeRecurse);
4406 LHSBits = LHSBitsOrig;
4407 RHSBits = RHSBitsOrig;
4417 switch (
MI->getOpcode()) {
4418 case TargetOpcode::G_AND:
4419 TTbl = LHSBits & RHSBits;
4421 case TargetOpcode::G_OR:
4422 TTbl = LHSBits | RHSBits;
4424 case TargetOpcode::G_XOR:
4425 TTbl = LHSBits ^ RHSBits;
4431 return std::make_pair(NumOpcodes + 1, TTbl);
4434bool AMDGPUInstructionSelector::selectBITOP3(
MachineInstr &
MI)
const {
4435 if (!Subtarget->hasBitOp3Insts())
4439 const RegisterBank *DstRB = RBI.getRegBank(DstReg, *MRI, TRI);
4440 const bool IsVALU = DstRB->
getID() == AMDGPU::VGPRRegBankID;
4446 unsigned NumOpcodes;
4448 std::tie(NumOpcodes, TTbl) =
BitOp3_Op(DstReg, Src, *MRI);
4452 if (NumOpcodes < 2 || Src.empty())
4457 unsigned Size = MRI->getType(DstReg).getSizeInBits();
4458 assert((
Size == 16 ||
Size == 32) &&
"unexpected VALU logic op size");
4459 const bool IsB32 =
Size == 32;
4460 if (NumOpcodes == 2 && IsB32) {
4468 }
else if (NumOpcodes < 4) {
4475 unsigned Opc = IsB32 ? AMDGPU::V_BITOP3_B32_e64 : AMDGPU::V_BITOP3_B16_e64;
4476 if (!IsB32 && STI.hasTrue16BitInsts())
4477 Opc = STI.useRealTrue16Insts() ? AMDGPU::V_BITOP3_B16_gfx1250_t16_e64
4478 : AMDGPU::V_BITOP3_B16_gfx1250_fake16_e64;
4479 unsigned CBL = STI.getConstantBusLimit(
Opc);
4483 for (
unsigned I = 0;
I < Src.size(); ++
I) {
4484 const RegisterBank *RB = RBI.getRegBank(Src[
I], *MRI, TRI);
4485 if (RB->
getID() != AMDGPU::SGPRRegBankID)
4491 Register NewReg = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
4502 while (Src.size() < 3)
4503 Src.push_back(Src[0]);
4520 MI.eraseFromParent();
4525bool AMDGPUInstructionSelector::selectWriteRegister(
MachineInstr &
MI)
const {
4526 const MDString *RegStr =
4529 LLT Ty = MRI->getType(SrcReg);
4531 Register PhysReg = Subtarget->getTargetLowering()->getRegisterByName(
4536 "invalid register \"" + Twine(RegStr->
getString()) +
4537 "\" for llvm.write_register",
4538 Fn,
MI.getDebugLoc()));
4539 MI.eraseFromParent();
4543 if (!RBI.constrainGenericRegister(
4544 SrcReg, *TRI.getSGPRClassForBitWidth(Ty.
getSizeInBits()), *MRI))
4547 BuildMI(*
MI.getParent(),
MI,
MI.getDebugLoc(), TII.get(AMDGPU::COPY), PhysReg)
4549 MI.eraseFromParent();
4553bool AMDGPUInstructionSelector::selectStackRestore(
MachineInstr &
MI)
const {
4555 if (!RBI.constrainGenericRegister(SrcReg, AMDGPU::SReg_32RegClass, *MRI))
4558 MachineInstr *
DefMI = MRI->getVRegDef(SrcReg);
4560 Subtarget->getTargetLowering()->getStackPointerRegisterToSaveRestore();
4566 WaveAddr = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
4569 .
addImm(Subtarget->getWavefrontSizeLog2())
4576 MI.eraseFromParent();
4582 if (!
I.isPreISelOpcode()) {
4584 return selectCOPY(
I);
4588 switch (
I.getOpcode()) {
4589 case TargetOpcode::G_AND:
4590 case TargetOpcode::G_OR:
4591 case TargetOpcode::G_XOR:
4592 if (selectBITOP3(
I))
4596 return selectG_AND_OR_XOR(
I);
4597 case TargetOpcode::G_ADD:
4598 case TargetOpcode::G_SUB:
4599 case TargetOpcode::G_PTR_ADD:
4602 return selectG_ADD_SUB(
I);
4603 case TargetOpcode::G_UADDO:
4604 case TargetOpcode::G_USUBO:
4605 case TargetOpcode::G_UADDE:
4606 case TargetOpcode::G_USUBE:
4607 return selectG_UADDO_USUBO_UADDE_USUBE(
I);
4608 case AMDGPU::G_AMDGPU_MAD_U64_U32:
4609 case AMDGPU::G_AMDGPU_MAD_I64_I32:
4610 return selectG_AMDGPU_MAD_64_32(
I);
4611 case TargetOpcode::G_INTTOPTR:
4612 case TargetOpcode::G_BITCAST:
4613 case TargetOpcode::G_PTRTOINT:
4614 case TargetOpcode::G_FREEZE:
4615 return selectCOPY(
I);
4616 case TargetOpcode::G_FNEG:
4619 return selectG_FNEG(
I);
4620 case TargetOpcode::G_FABS:
4623 return selectG_FABS(
I);
4624 case TargetOpcode::G_EXTRACT:
4625 return selectG_EXTRACT(
I);
4626 case TargetOpcode::G_MERGE_VALUES:
4627 case TargetOpcode::G_CONCAT_VECTORS:
4628 return selectG_MERGE_VALUES(
I);
4629 case TargetOpcode::G_UNMERGE_VALUES:
4630 return selectG_UNMERGE_VALUES(
I);
4631 case TargetOpcode::G_BUILD_VECTOR:
4632 case TargetOpcode::G_BUILD_VECTOR_TRUNC:
4633 return selectG_BUILD_VECTOR(
I);
4634 case TargetOpcode::G_IMPLICIT_DEF:
4635 return selectG_IMPLICIT_DEF(
I);
4636 case TargetOpcode::G_INSERT:
4637 return selectG_INSERT(
I);
4638 case TargetOpcode::G_INTRINSIC:
4639 case TargetOpcode::G_INTRINSIC_CONVERGENT:
4640 return selectG_INTRINSIC(
I);
4641 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
4642 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
4643 return selectG_INTRINSIC_W_SIDE_EFFECTS(
I);
4644 case TargetOpcode::G_ICMP:
4645 case TargetOpcode::G_FCMP:
4646 if (selectG_ICMP_or_FCMP(
I))
4649 case TargetOpcode::G_LOAD:
4650 case TargetOpcode::G_ZEXTLOAD:
4651 case TargetOpcode::G_SEXTLOAD:
4652 case TargetOpcode::G_STORE:
4653 case TargetOpcode::G_ATOMIC_CMPXCHG:
4654 case TargetOpcode::G_ATOMICRMW_XCHG:
4655 case TargetOpcode::G_ATOMICRMW_ADD:
4656 case TargetOpcode::G_ATOMICRMW_SUB:
4657 case TargetOpcode::G_ATOMICRMW_AND:
4658 case TargetOpcode::G_ATOMICRMW_OR:
4659 case TargetOpcode::G_ATOMICRMW_XOR:
4660 case TargetOpcode::G_ATOMICRMW_MIN:
4661 case TargetOpcode::G_ATOMICRMW_MAX:
4662 case TargetOpcode::G_ATOMICRMW_UMIN:
4663 case TargetOpcode::G_ATOMICRMW_UMAX:
4664 case TargetOpcode::G_ATOMICRMW_UINC_WRAP:
4665 case TargetOpcode::G_ATOMICRMW_UDEC_WRAP:
4666 case TargetOpcode::G_ATOMICRMW_USUB_COND:
4667 case TargetOpcode::G_ATOMICRMW_USUB_SAT:
4668 case TargetOpcode::G_ATOMICRMW_FADD:
4669 case TargetOpcode::G_ATOMICRMW_FMIN:
4670 case TargetOpcode::G_ATOMICRMW_FMAX:
4671 return selectG_LOAD_STORE_ATOMICRMW(
I);
4672 case TargetOpcode::G_SELECT:
4673 return selectG_SELECT(
I);
4674 case TargetOpcode::G_TRUNC:
4675 return selectG_TRUNC(
I);
4676 case TargetOpcode::G_SEXT:
4677 case TargetOpcode::G_ZEXT:
4678 case TargetOpcode::G_ANYEXT:
4679 case TargetOpcode::G_SEXT_INREG:
4683 if (MRI->getType(
I.getOperand(1).getReg()) !=
LLT::scalar(1) &&
4686 return selectG_SZA_EXT(
I);
4687 case TargetOpcode::G_FPEXT:
4688 if (selectG_FPEXT(
I))
4691 case TargetOpcode::G_BRCOND:
4692 return selectG_BRCOND(
I);
4693 case TargetOpcode::G_GLOBAL_VALUE:
4694 return selectG_GLOBAL_VALUE(
I);
4695 case TargetOpcode::G_PTRMASK:
4696 return selectG_PTRMASK(
I);
4697 case TargetOpcode::G_EXTRACT_VECTOR_ELT:
4698 return selectG_EXTRACT_VECTOR_ELT(
I);
4699 case TargetOpcode::G_INSERT_VECTOR_ELT:
4700 return selectG_INSERT_VECTOR_ELT(
I);
4701 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD:
4702 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD_D16:
4703 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_LOAD_NORET:
4704 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE:
4705 case AMDGPU::G_AMDGPU_INTRIN_IMAGE_STORE_D16: {
4708 assert(Intr &&
"not an image intrinsic with image pseudo");
4709 return selectImageIntrinsic(
I, Intr);
4711 case AMDGPU::G_AMDGPU_BVH_DUAL_INTERSECT_RAY:
4712 case AMDGPU::G_AMDGPU_BVH_INTERSECT_RAY:
4713 case AMDGPU::G_AMDGPU_BVH8_INTERSECT_RAY:
4714 return selectBVHIntersectRayIntrinsic(
I);
4715 case AMDGPU::G_SBFX:
4716 case AMDGPU::G_UBFX:
4717 return selectG_SBFX_UBFX(
I);
4718 case AMDGPU::G_SI_CALL:
4719 I.setDesc(TII.get(AMDGPU::SI_CALL));
4721 case AMDGPU::G_AMDGPU_WAVE_ADDRESS:
4722 return selectWaveAddress(
I);
4723 case AMDGPU::G_AMDGPU_WHOLE_WAVE_FUNC_RETURN: {
4724 I.setDesc(TII.get(AMDGPU::SI_WHOLE_WAVE_FUNC_RETURN));
4727 case AMDGPU::G_STACKRESTORE:
4728 return selectStackRestore(
I);
4729 case TargetOpcode::G_WRITE_REGISTER:
4730 return selectWriteRegister(
I);
4732 return selectPHI(
I);
4733 case AMDGPU::G_AMDGPU_COPY_SCC_VCC:
4734 return selectCOPY_SCC_VCC(
I);
4735 case AMDGPU::G_AMDGPU_COPY_VCC_SCC:
4736 return selectCOPY_VCC_SCC(
I);
4737 case AMDGPU::G_AMDGPU_READANYLANE:
4738 return selectReadAnyLane(
I);
4739 case TargetOpcode::G_CONSTANT:
4740 case TargetOpcode::G_FCONSTANT:
4748AMDGPUInstructionSelector::selectVCSRC(
MachineOperand &Root)
const {
4755std::pair<Register, unsigned> AMDGPUInstructionSelector::selectVOP3ModsImpl(
4756 Register Src,
bool IsCanonicalizing,
bool AllowAbs,
bool OpSel)
const {
4760 if (
MI->getOpcode() == AMDGPU::G_FNEG) {
4761 Src =
MI->getOperand(1).getReg();
4764 }
else if (
MI->getOpcode() == AMDGPU::G_FSUB && IsCanonicalizing) {
4769 if (
LHS &&
LHS->isZero()) {
4771 Src =
MI->getOperand(2).getReg();
4775 if (AllowAbs &&
MI->getOpcode() == AMDGPU::G_FABS) {
4776 Src =
MI->getOperand(1).getReg();
4783 return std::pair(Src, Mods);
4786std::pair<Register, unsigned>
4787AMDGPUInstructionSelector::selectVOP3PModsF32Impl(
Register Src)
const {
4789 std::tie(Src, Mods) = selectVOP3ModsImpl(Src);
4791 return std::pair(Src, Mods);
4794Register AMDGPUInstructionSelector::copyToVGPRIfSrcFolded(
4796 bool ForceVGPR)
const {
4797 if ((Mods != 0 || ForceVGPR) &&
4798 RBI.getRegBank(Src, *MRI, TRI)->getID() != AMDGPU::VGPRRegBankID) {
4805 TII.
get(AMDGPU::COPY), VGPRSrc)
4817AMDGPUInstructionSelector::widenSrcIfVGPR16(
Register Src,
4819 if (!Subtarget->useRealTrue16Insts() || MRI->getType(Src) !=
LLT::scalar(16))
4822 const RegisterBank *SrcRB = RBI.getRegBank(Src, *MRI, TRI);
4823 if (!SrcRB || SrcRB->
getID() != AMDGPU::VGPRRegBankID)
4826 MachineIRBuilder
B(*InsertPt);
4828 Register ImpDefReg = MRI->createVirtualRegister(&AMDGPU::VGPR_16RegClass);
4829 B.buildInstr(TargetOpcode::IMPLICIT_DEF).addDef(ImpDefReg);
4831 Register DstReg = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
4832 B.buildInstr(AMDGPU::REG_SEQUENCE)
4835 .addImm(AMDGPU::lo16)
4837 .addImm(AMDGPU::hi16);
4846AMDGPUInstructionSelector::selectVSRC0(
MachineOperand &Root)
const {
4848 [=](MachineInstrBuilder &MIB) { MIB.
add(Root); }
4853AMDGPUInstructionSelector::selectVOP3Mods0(
MachineOperand &Root)
const {
4856 std::tie(Src, Mods) = selectVOP3ModsImpl(Root.
getReg());
4859 [=](MachineInstrBuilder &MIB) {
4860 MIB.
addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));
4862 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); },
4863 [=](MachineInstrBuilder &MIB) { MIB.
addImm(0); },
4864 [=](MachineInstrBuilder &MIB) { MIB.
addImm(0); }
4869AMDGPUInstructionSelector::selectVOP3BMods0(
MachineOperand &Root)
const {
4872 std::tie(Src, Mods) = selectVOP3ModsImpl(Root.
getReg(),
4877 [=](MachineInstrBuilder &MIB) {
4878 MIB.
addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));
4880 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); },
4881 [=](MachineInstrBuilder &MIB) { MIB.
addImm(0); },
4882 [=](MachineInstrBuilder &MIB) { MIB.
addImm(0); }
4887AMDGPUInstructionSelector::selectVOP3OMods(
MachineOperand &Root)
const {
4889 [=](MachineInstrBuilder &MIB) { MIB.
add(Root); },
4890 [=](MachineInstrBuilder &MIB) { MIB.
addImm(0); },
4891 [=](MachineInstrBuilder &MIB) { MIB.
addImm(0); }
4896AMDGPUInstructionSelector::selectVOP3Mods(
MachineOperand &Root)
const {
4899 std::tie(Src, Mods) = selectVOP3ModsImpl(Root.
getReg());
4902 [=](MachineInstrBuilder &MIB) {
4903 MIB.
addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));
4905 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }
4910AMDGPUInstructionSelector::selectVOP3ModsNonCanonicalizing(
4914 std::tie(Src, Mods) =
4915 selectVOP3ModsImpl(Root.
getReg(),
false);
4918 [=](MachineInstrBuilder &MIB) {
4919 MIB.
addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));
4921 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }
4926AMDGPUInstructionSelector::selectVOP3BMods(
MachineOperand &Root)
const {
4929 std::tie(Src, Mods) =
4930 selectVOP3ModsImpl(Root.
getReg(),
true,
4934 [=](MachineInstrBuilder &MIB) {
4935 MIB.
addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));
4937 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }
4942AMDGPUInstructionSelector::selectVOP3NoMods(
MachineOperand &Root)
const {
4945 if (
Def->getOpcode() == AMDGPU::G_FNEG ||
Def->getOpcode() == AMDGPU::G_FABS)
4948 [=](MachineInstrBuilder &MIB) { MIB.
addReg(
Reg); },
4973 if (
MI->getOpcode() != AMDGPU::G_TRUNC)
4976 uint64_t DstSize =
MRI.getType(
MI->getOperand(0).getReg()).getSizeInBits();
4977 uint64_t SrcSize =
MRI.getType(
MI->getOperand(1).getReg()).getSizeInBits();
4978 return DstSize * 2 == SrcSize;
4984 if (
MI->getOpcode() != AMDGPU::G_LSHR)
4988 std::optional<ValueAndVReg> ShiftAmt;
4991 uint64_t SrcSize =
MRI.getType(
MI->getOperand(1).getReg()).getSizeInBits();
4992 unsigned Shift =
static_cast<unsigned>(ShiftAmt->Value.getZExtValue());
4993 return Shift * 2 == SrcSize;
5001 if (
MI->getOpcode() != AMDGPU::G_SHL)
5005 std::optional<ValueAndVReg> ShiftAmt;
5008 uint64_t SrcSize =
MRI.getType(
MI->getOperand(1).getReg()).getSizeInBits();
5009 unsigned Shift =
static_cast<unsigned>(ShiftAmt->Value.getZExtValue());
5010 return Shift * 2 == SrcSize;
5018 if (
MI->getOpcode() != AMDGPU::G_UNMERGE_VALUES)
5020 return MI->getNumOperands() == 3 &&
MI->getOperand(0).isDef() &&
5021 MI->getOperand(1).isDef() && !
MI->getOperand(2).isDef();
5029 if (
OpTy.isScalar())
5031 if (
OpTy.isVector() &&
OpTy.getNumElements() == 2)
5191static std::optional<std::pair<Register, SrcStatus>>
5196 unsigned Opc =
MI->getOpcode();
5200 case AMDGPU::G_BITCAST:
5201 return std::optional<std::pair<Register, SrcStatus>>(
5202 {
MI->getOperand(1).getReg(), Curr.second});
5204 if (
MI->getOperand(1).getReg().isPhysical())
5205 return std::nullopt;
5206 return std::optional<std::pair<Register, SrcStatus>>(
5207 {
MI->getOperand(1).getReg(), Curr.second});
5208 case AMDGPU::G_FNEG: {
5211 return std::nullopt;
5212 return std::optional<std::pair<Register, SrcStatus>>(
5213 {
MI->getOperand(1).getReg(), Stat});
5220 switch (Curr.second) {
5223 return std::optional<std::pair<Register, SrcStatus>>(
5226 if (Curr.first ==
MI->getOperand(0).getReg())
5227 return std::optional<std::pair<Register, SrcStatus>>(
5229 return std::optional<std::pair<Register, SrcStatus>>(
5241 return std::optional<std::pair<Register, SrcStatus>>(
5245 if (Curr.first ==
MI->getOperand(0).getReg())
5246 return std::optional<std::pair<Register, SrcStatus>>(
5248 return std::optional<std::pair<Register, SrcStatus>>(
5254 return std::optional<std::pair<Register, SrcStatus>>(
5259 return std::optional<std::pair<Register, SrcStatus>>(
5264 return std::optional<std::pair<Register, SrcStatus>>(
5269 return std::optional<std::pair<Register, SrcStatus>>(
5275 return std::nullopt;
5285 bool HasNeg =
false;
5287 bool HasOpsel =
true;
5292 unsigned Opc =
MI->getOpcode();
5294 if (
Opc == TargetOpcode::G_INTRINSIC) {
5297 if (IntrinsicID == Intrinsic::amdgcn_fdot2)
5324 while (
Depth <= MaxDepth && Curr.has_value()) {
5327 Statlist.push_back(Curr.value());
5334static std::pair<Register, SrcStatus>
5341 while (
Depth <= MaxDepth && Curr.has_value()) {
5347 LastSameOrNeg = Curr.value();
5352 return LastSameOrNeg;
5357 uint64_t Width1 =
MRI.getType(Reg1).getSizeInBits();
5358 uint64_t Width2 =
MRI.getType(Reg2).getSizeInBits();
5359 return Width1 == Width2;
5395 IsHalfState(HiStat);
5398std::pair<Register, unsigned> AMDGPUInstructionSelector::selectVOP3PModsImpl(
5400 bool NoOpSel0)
const {
5405 return {RootReg, Mods};
5408 SearchOptions SO(RootReg, MRI);
5421 if (MRI.getType(RootReg).getSizeInBits() == 128) {
5423 return {Stat.first, Mods};
5428 MI->getNumOperands() != 3 || (IsDOT && Subtarget->hasDOTOpSelHazard())) {
5430 return {Stat.first, Mods};
5436 if (StatlistHi.
empty()) {
5438 return {Stat.first, Mods};
5444 if (StatlistLo.
empty()) {
5446 return {Stat.first, Mods};
5449 for (
int I =
static_cast<int>(StatlistHi.
size()) - 1;
I >= 0;
I--) {
5450 for (
int J =
static_cast<int>(StatlistLo.
size()) - 1; J >= 0; J--) {
5451 if (StatlistHi[
I].first == StatlistLo[J].first &&
5453 StatlistHi[
I].first, RootReg, TII, MRI)) {
5455 updateMods(StatlistHi[
I].second, StatlistLo[J].second, Mods);
5458 return {StatlistHi[
I].first, NewMods};
5465 return {Stat.first, Mods};
5475 return RB->
getID() == RBNo;
5491 if (
checkRB(RootReg, AMDGPU::SGPRRegBankID, RBI,
MRI,
TRI) ||
5500 Register DstReg =
MRI.cloneVirtualRegister(RootReg);
5502 TII.get(AMDGPU::COPY), DstReg)
5510AMDGPUInstructionSelector::selectVOP3PRetHelper(
MachineOperand &Root,
5512 bool NoOpSel0)
const {
5516 std::tie(
Reg, Mods) =
5517 selectVOP3PModsImpl(Root.
getReg(), MRI, IsDOT, NoOpSel0);
5520 [=, &Root, &MRI](MachineInstrBuilder &MIB) {
5524 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }
5529AMDGPUInstructionSelector::selectVOP3PMods(
MachineOperand &Root)
const {
5531 return selectVOP3PRetHelper(Root);
5535AMDGPUInstructionSelector::selectVOP3PModsPkFmaOpSel0(
5538 LLT Ty = MRI.getType(Root.
getReg());
5539 bool NoOpSel0 = Subtarget->hasPkF32InvalidOpSel() && Ty.
isFixedVector() &&
5541 return selectVOP3PRetHelper(Root,
false, NoOpSel0);
5545AMDGPUInstructionSelector::selectVOP3PModsPkAddMulOpSel0(
5548 LLT Ty = MRI.getType(Root.
getReg());
5549 if (Subtarget->hasPkF32InvalidOpSel() && Ty.
isFixedVector() &&
5552 return std::nullopt;
5553 return selectVOP3PRetHelper(Root);
5557AMDGPUInstructionSelector::selectVOP3PModsDOT(
MachineOperand &Root)
const {
5559 return selectVOP3PRetHelper(Root,
true);
5563AMDGPUInstructionSelector::selectVOP3PNoModsDOT(
MachineOperand &Root)
const {
5567 std::tie(Src, Mods) = selectVOP3PModsImpl(Root.
getReg(), MRI,
true );
5571 return {{[=](MachineInstrBuilder &MIB) { MIB.
addReg(Src); }}};
5575AMDGPUInstructionSelector::selectVOP3PModsF32(
MachineOperand &Root)
const {
5578 std::tie(Src, Mods) = selectVOP3PModsF32Impl(Root.
getReg());
5581 [=](MachineInstrBuilder &MIB) { MIB.
addReg(Src); },
5582 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }
5587AMDGPUInstructionSelector::selectVOP3PNoModsF32(
MachineOperand &Root)
const {
5590 std::tie(Src, Mods) = selectVOP3PModsF32Impl(Root.
getReg());
5594 return {{[=](MachineInstrBuilder &MIB) { MIB.
addReg(Src); }}};
5598AMDGPUInstructionSelector::selectWMMAOpSelVOP3PMods(
5601 "expected i1 value");
5607 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }
5615 switch (Elts.
size()) {
5617 DstRegClass = &AMDGPU::VReg_256RegClass;
5620 DstRegClass = &AMDGPU::VReg_128RegClass;
5623 DstRegClass = &AMDGPU::VReg_64RegClass;
5630 auto MIB =
B.buildInstr(AMDGPU::REG_SEQUENCE)
5631 .addDef(
MRI.createVirtualRegister(DstRegClass));
5632 for (
unsigned i = 0; i < Elts.
size(); ++i) {
5643 if (ModOpcode == TargetOpcode::G_FNEG) {
5647 for (
auto El : Elts) {
5653 if (Elts.size() != NegAbsElts.
size()) {
5662 assert(ModOpcode == TargetOpcode::G_FABS);
5670AMDGPUInstructionSelector::selectWMMAModsF32NegAbs(
MachineOperand &Root)
const {
5679 MachineInstr *ElF32 = MRI->getVRegDef(BV->
getSourceReg(0));
5680 unsigned ModOpcode = (ElF32->
getOpcode() == AMDGPU::G_FNEG)
5697 return {{[=](MachineInstrBuilder &MIB) { MIB.
addReg(Src); },
5698 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }}};
5702AMDGPUInstructionSelector::selectWMMAModsF16Neg(
MachineOperand &Root)
const {
5724 return {{[=](MachineInstrBuilder &MIB) { MIB.
addReg(Src); },
5725 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }}};
5729AMDGPUInstructionSelector::selectWMMAModsF16NegAbs(
MachineOperand &Root)
const {
5737 MachineInstr *ElV2F16 = MRI->getVRegDef(CV->
getSourceReg(0));
5739 unsigned ModOpcode = (ElV2F16->
getOpcode() == AMDGPU::G_FNEG)
5758 return {{[=](MachineInstrBuilder &MIB) { MIB.
addReg(Src); },
5759 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }}};
5763AMDGPUInstructionSelector::selectWMMAVISrc(
MachineOperand &Root)
const {
5764 std::optional<FPValueAndVReg> FPValReg;
5766 if (TII.isInlineConstant(FPValReg->Value)) {
5767 return {{[=](MachineInstrBuilder &MIB) {
5768 MIB.
addImm(FPValReg->Value.bitcastToAPInt().getSExtValue());
5778 if (TII.isInlineConstant(ICst)) {
5788AMDGPUInstructionSelector::selectSWMMACIndex8(
MachineOperand &Root)
const {
5794 std::optional<ValueAndVReg> ShiftAmt;
5796 MRI->getType(ShiftSrc).getSizeInBits() == 32 &&
5797 ShiftAmt->Value.getZExtValue() % 8 == 0) {
5798 Key =
static_cast<unsigned>(ShiftAmt->Value.getZExtValue() / 8);
5803 [=](MachineInstrBuilder &MIB) { MIB.
addReg(Src); },
5804 [=](MachineInstrBuilder &MIB) { MIB.
addImm(
Key); }
5809AMDGPUInstructionSelector::selectSWMMACIndex16(
MachineOperand &Root)
const {
5816 std::optional<ValueAndVReg> ShiftAmt;
5818 MRI->getType(ShiftSrc).getSizeInBits() == 32 &&
5819 ShiftAmt->Value.getZExtValue() == 16) {
5825 [=](MachineInstrBuilder &MIB) { MIB.
addReg(Src); },
5826 [=](MachineInstrBuilder &MIB) { MIB.
addImm(
Key); }
5831AMDGPUInstructionSelector::selectSWMMACIndex32(
MachineOperand &Root)
const {
5838 S32 = matchAnyExtendFromS32(Src);
5842 if (
Def->getOpcode() == TargetOpcode::G_UNMERGE_VALUES) {
5847 Src =
Def->getOperand(2).getReg();
5854 [=](MachineInstrBuilder &MIB) { MIB.
addReg(Src); },
5855 [=](MachineInstrBuilder &MIB) { MIB.
addImm(
Key); }
5860AMDGPUInstructionSelector::selectVOP3OpSelMods(
MachineOperand &Root)
const {
5863 std::tie(Src, Mods) = selectVOP3ModsImpl(Root.
getReg());
5866 if (!Subtarget->useRealTrue16Insts() &&
5867 MRI->getType(Root.
getReg()).getSizeInBits() == 16 &&
5874 [=](MachineInstrBuilder &MIB) {
5875 MIB.
addReg(copyToVGPRIfSrcFolded(Src, Mods, Root, MIB));
5877 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }
5883AMDGPUInstructionSelector::selectVINTERPMods(
MachineOperand &Root)
const {
5886 std::tie(Src, Mods) = selectVOP3ModsImpl(Root.
getReg(),
5892 [=](MachineInstrBuilder &MIB) {
5894 copyToVGPRIfSrcFolded(Src, Mods, Root, MIB,
true));
5896 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); },
5901AMDGPUInstructionSelector::selectVINTERPModsHi(
MachineOperand &Root)
const {
5904 std::tie(Src, Mods) = selectVOP3ModsImpl(Root.
getReg(),
5910 [=](MachineInstrBuilder &MIB) {
5912 copyToVGPRIfSrcFolded(Src, Mods, Root, MIB,
true));
5914 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); },
5921bool AMDGPUInstructionSelector::selectScaleOffset(
MachineOperand &Root,
5924 bool IsSMEM)
const {
5925 if (!Subtarget->hasScaleOffset())
5929 MachineMemOperand *MMO = *
MI.memoperands_begin();
5937 bool IsExtended = OffsetReg && OffsetReg !=
Offset;
5942 OffsetReg =
Def->Reg;
5957 m_BinOp(IsSigned ? AMDGPU::S_MUL_I64_I32_PSEUDO : AMDGPU::S_MUL_U64,
5961 (
Mul->getOpcode() == (IsSigned ? AMDGPU::G_AMDGPU_MAD_I64_I32
5962 : AMDGPU::G_AMDGPU_MAD_U64_U32) ||
5963 (IsSigned &&
Mul->getOpcode() == AMDGPU::G_AMDGPU_MAD_U64_U32 &&
5964 VT->signBitIsZero(
Mul->getOperand(2).getReg()))) &&
5977 if (!IsExtended && MRI->getType(
Offset).getSizeInBits() == 64) {
5978 KnownBits
Known =
VT->getKnownBits(Op0);
5979 if (
Known.countMaxActiveBits() + Bits > 32)
5982 }
else if (IsExtended) {
5983 const MachineInstr *Scale = MRI->getVRegDef(OffsetReg);
5985 VT->computeNumSignBits(Op0) <= Bits)
5988 VT->getKnownBits(Op0).countMinLeadingZeros() < Bits)
5996bool AMDGPUInstructionSelector::selectSmrdOffset(
MachineOperand &Root,
6000 bool *ScaleOffset)
const {
6007 getAddrModeInfo(*
MI, *MRI, AddrInfo);
6009 if (AddrInfo.
empty())
6012 const GEPInfo &GEPI = AddrInfo[0];
6013 std::optional<int64_t> EncodedImm;
6016 *ScaleOffset =
false;
6021 if (GEPI.SgprParts.size() == 1 && GEPI.Imm != 0 && EncodedImm &&
6022 AddrInfo.
size() > 1) {
6023 const GEPInfo &GEPI2 = AddrInfo[1];
6024 if (GEPI2.SgprParts.size() == 2 && GEPI2.Imm == 0) {
6025 Register OffsetReg = GEPI2.SgprParts[1];
6027 *ScaleOffset = selectScaleOffset(
6028 Root, OffsetReg,
false ,
true );
6029 OffsetReg = matchZeroExtendFromS32OrS32(OffsetReg);
6031 Base = GEPI2.SgprParts[0];
6032 *SOffset = OffsetReg;
6041 auto SKnown =
VT->getKnownBits(*SOffset);
6042 if (*
Offset + SKnown.getMinValue().getSExtValue() < 0)
6054 if (
Offset && GEPI.SgprParts.size() == 1 && EncodedImm) {
6055 Base = GEPI.SgprParts[0];
6061 if (SOffset && GEPI.SgprParts.size() == 1 &&
isUInt<32>(GEPI.Imm) &&
6067 Base = GEPI.SgprParts[0];
6068 *SOffset = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
6069 BuildMI(*
MBB,
MI,
MI->getDebugLoc(), TII.get(AMDGPU::S_MOV_B32), *SOffset)
6074 if (SOffset && GEPI.SgprParts.size() && GEPI.Imm == 0) {
6075 Register OffsetReg = GEPI.SgprParts[1];
6077 *ScaleOffset = selectScaleOffset(Root, OffsetReg,
false ,
6079 OffsetReg = matchZeroExtendFromS32OrS32(OffsetReg);
6081 Base = GEPI.SgprParts[0];
6082 *SOffset = OffsetReg;
6091AMDGPUInstructionSelector::selectSmrdImm(
MachineOperand &Root)
const {
6094 if (!selectSmrdOffset(Root,
Base,
nullptr, &
Offset,
6096 return std::nullopt;
6098 return {{[=](MachineInstrBuilder &MIB) { MIB.
addReg(
Base); },
6099 [=](MachineInstrBuilder &MIB) { MIB.
addImm(
Offset); }}};
6103AMDGPUInstructionSelector::selectSmrdImm32(
MachineOperand &Root)
const {
6105 getAddrModeInfo(*Root.
getParent(), *MRI, AddrInfo);
6107 if (AddrInfo.
empty() || AddrInfo[0].SgprParts.size() != 1)
6108 return std::nullopt;
6110 const GEPInfo &GEPInfo = AddrInfo[0];
6111 Register PtrReg = GEPInfo.SgprParts[0];
6112 std::optional<int64_t> EncodedImm =
6115 return std::nullopt;
6118 [=](MachineInstrBuilder &MIB) { MIB.
addReg(PtrReg); },
6119 [=](MachineInstrBuilder &MIB) { MIB.
addImm(*EncodedImm); }
6124AMDGPUInstructionSelector::selectSmrdSgpr(
MachineOperand &Root)
const {
6127 if (!selectSmrdOffset(Root,
Base, &SOffset,
nullptr,
6129 return std::nullopt;
6132 return {{[=](MachineInstrBuilder &MIB) { MIB.
addReg(
Base); },
6133 [=](MachineInstrBuilder &MIB) { MIB.
addReg(SOffset); },
6134 [=](MachineInstrBuilder &MIB) { MIB.
addImm(CPol); }}};
6138AMDGPUInstructionSelector::selectSmrdSgprImm(
MachineOperand &Root)
const {
6142 if (!selectSmrdOffset(Root,
Base, &SOffset, &
Offset, &ScaleOffset))
6143 return std::nullopt;
6146 return {{[=](MachineInstrBuilder &MIB) { MIB.
addReg(
Base); },
6147 [=](MachineInstrBuilder &MIB) { MIB.
addReg(SOffset); },
6149 [=](MachineInstrBuilder &MIB) { MIB.
addImm(CPol); }}};
6152std::pair<Register, int64_t> AMDGPUInstructionSelector::selectFlatOffsetImpl(
6158 if (!STI.hasFlatInstOffsets())
6162 int64_t ConstOffset;
6164 std::tie(PtrBase, ConstOffset, IsInBounds) =
6165 getPtrBaseWithConstantOffset(Root.
getReg(), *MRI);
6171 if (ConstOffset == 0 ||
6173 !isFlatScratchBaseLegal(Root.
getReg())) ||
6177 unsigned AddrSpace = (*
MI->memoperands_begin())->getAddrSpace();
6178 if (!TII.isLegalFLATOffset(ConstOffset, AddrSpace, FlatVariant))
6181 return std::pair(PtrBase, ConstOffset);
6185AMDGPUInstructionSelector::selectFlatOffset(
MachineOperand &Root)
const {
6189 [=](MachineInstrBuilder &MIB) { MIB.
addReg(PtrWithOffset.first); },
6190 [=](MachineInstrBuilder &MIB) { MIB.
addImm(PtrWithOffset.second); },
6195AMDGPUInstructionSelector::selectGlobalOffset(
MachineOperand &Root)
const {
6196 auto PtrWithOffset =
6200 [=](MachineInstrBuilder &MIB) { MIB.
addReg(PtrWithOffset.first); },
6201 [=](MachineInstrBuilder &MIB) { MIB.
addImm(PtrWithOffset.second); },
6206AMDGPUInstructionSelector::selectScratchOffset(
MachineOperand &Root)
const {
6207 auto PtrWithOffset =
6211 [=](MachineInstrBuilder &MIB) { MIB.
addReg(PtrWithOffset.first); },
6212 [=](MachineInstrBuilder &MIB) { MIB.
addImm(PtrWithOffset.second); },
6218AMDGPUInstructionSelector::selectGlobalSAddr(
MachineOperand &Root,
6220 bool NeedIOffset)
const {
6223 int64_t ConstOffset;
6224 int64_t ImmOffset = 0;
6228 std::tie(PtrBase, ConstOffset, std::ignore) =
6229 getPtrBaseWithConstantOffset(Addr, *MRI);
6231 if (ConstOffset != 0) {
6236 ImmOffset = ConstOffset;
6239 if (isSGPR(PtrBaseDef->Reg)) {
6245 int64_t SplitImmOffset = 0, RemainderOffset = ConstOffset;
6247 std::tie(SplitImmOffset, RemainderOffset) =
6252 if (Subtarget->hasSignedGVSOffset() ?
isInt<32>(RemainderOffset)
6257 MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6259 BuildMI(*
MBB,
MI,
MI->getDebugLoc(), TII.get(AMDGPU::V_MOV_B32_e32),
6261 .
addImm(RemainderOffset);
6265 [=](MachineInstrBuilder &MIB) { MIB.
addReg(PtrBase); },
6266 [=](MachineInstrBuilder &MIB) {
6269 [=](MachineInstrBuilder &MIB) { MIB.
addImm(SplitImmOffset); },
6270 [=](MachineInstrBuilder &MIB) { MIB.
addImm(CPolBits); },
6273 [=](MachineInstrBuilder &MIB) { MIB.
addReg(PtrBase); },
6274 [=](MachineInstrBuilder &MIB) {
6277 [=](MachineInstrBuilder &MIB) { MIB.
addImm(CPolBits); },
6286 unsigned NumLiterals =
6287 !TII.isInlineConstant(APInt(32,
Lo_32(ConstOffset))) +
6288 !TII.isInlineConstant(APInt(32,
Hi_32(ConstOffset)));
6289 if (STI.getConstantBusLimit(AMDGPU::V_ADD_U32_e64) > NumLiterals)
6290 return std::nullopt;
6297 if (AddrDef->MI->getOpcode() == AMDGPU::G_PTR_ADD) {
6302 if (isSGPR(SAddr)) {
6303 Register PtrBaseOffset = AddrDef->MI->getOperand(2).getReg();
6307 bool ScaleOffset = selectScaleOffset(Root, PtrBaseOffset,
6308 Subtarget->hasSignedGVSOffset());
6309 if (
Register VOffset = matchExtendFromS32OrS32(
6310 PtrBaseOffset, Subtarget->hasSignedGVSOffset())) {
6312 return {{[=](MachineInstrBuilder &MIB) {
6315 [=](MachineInstrBuilder &MIB) {
6318 [=](MachineInstrBuilder &MIB) {
6321 [=](MachineInstrBuilder &MIB) {
6325 return {{[=](MachineInstrBuilder &MIB) {
6328 [=](MachineInstrBuilder &MIB) {
6331 [=](MachineInstrBuilder &MIB) {
6341 if (AddrDef->MI->getOpcode() == AMDGPU::G_IMPLICIT_DEF ||
6342 AddrDef->MI->getOpcode() == AMDGPU::G_CONSTANT || !isSGPR(AddrDef->Reg))
6343 return std::nullopt;
6349 Register VOffset = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6351 BuildMI(*
MBB,
MI,
MI->getDebugLoc(), TII.get(AMDGPU::V_MOV_B32_e32), VOffset)
6356 [=](MachineInstrBuilder &MIB) { MIB.
addReg(AddrDef->Reg); },
6357 [=](MachineInstrBuilder &MIB) { MIB.
addReg(VOffset); },
6358 [=](MachineInstrBuilder &MIB) { MIB.
addImm(ImmOffset); },
6359 [=](MachineInstrBuilder &MIB) { MIB.
addImm(CPolBits); }
6362 [=](MachineInstrBuilder &MIB) { MIB.
addReg(AddrDef->Reg); },
6363 [=](MachineInstrBuilder &MIB) { MIB.
addReg(VOffset); },
6364 [=](MachineInstrBuilder &MIB) { MIB.
addImm(CPolBits); }
6369AMDGPUInstructionSelector::selectGlobalSAddr(
MachineOperand &Root)
const {
6370 return selectGlobalSAddr(Root, 0);
6374AMDGPUInstructionSelector::selectGlobalSAddrCPol(
MachineOperand &Root)
const {
6380 return selectGlobalSAddr(Root,
static_cast<unsigned>(PassedCPol));
6384AMDGPUInstructionSelector::selectGlobalSAddrCPolM0(
MachineOperand &Root)
const {
6390 return selectGlobalSAddr(Root,
static_cast<unsigned>(PassedCPol));
6394AMDGPUInstructionSelector::selectGlobalSAddrGLC(
MachineOperand &Root)
const {
6399AMDGPUInstructionSelector::selectGlobalSAddrNoIOffset(
6406 return selectGlobalSAddr(Root,
static_cast<unsigned>(PassedCPol),
false);
6410AMDGPUInstructionSelector::selectGlobalSAddrNoIOffsetM0(
6417 return selectGlobalSAddr(Root,
static_cast<unsigned>(PassedCPol),
false);
6421AMDGPUInstructionSelector::selectScratchSAddr(
MachineOperand &Root)
const {
6424 int64_t ConstOffset;
6425 int64_t ImmOffset = 0;
6429 std::tie(PtrBase, ConstOffset, std::ignore) =
6430 getPtrBaseWithConstantOffset(Addr, *MRI);
6432 if (ConstOffset != 0 && isFlatScratchBaseLegal(Addr) &&
6436 ImmOffset = ConstOffset;
6440 if (AddrDef->MI->getOpcode() == AMDGPU::G_FRAME_INDEX) {
6441 int FI = AddrDef->MI->getOperand(1).
getIndex();
6444 [=](MachineInstrBuilder &MIB) { MIB.
addImm(ImmOffset); }
6450 if (AddrDef->MI->getOpcode() == AMDGPU::G_PTR_ADD) {
6451 Register LHS = AddrDef->MI->getOperand(1).getReg();
6452 Register RHS = AddrDef->MI->getOperand(2).getReg();
6456 if (LHSDef->MI->getOpcode() == AMDGPU::G_FRAME_INDEX &&
6457 isSGPR(RHSDef->Reg)) {
6458 int FI = LHSDef->MI->getOperand(1).getIndex();
6462 SAddr = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
6464 BuildMI(*BB, &
I,
DL, TII.get(AMDGPU::S_ADD_I32), SAddr)
6472 return std::nullopt;
6475 [=](MachineInstrBuilder &MIB) { MIB.
addReg(SAddr); },
6476 [=](MachineInstrBuilder &MIB) { MIB.
addImm(ImmOffset); }
6481bool AMDGPUInstructionSelector::checkFlatScratchSVSSwizzleBug(
6483 if (!Subtarget->hasFlatScratchSVSSwizzleBug())
6489 auto VKnown =
VT->getKnownBits(VAddr);
6492 uint64_t VMax = VKnown.getMaxValue().getZExtValue();
6494 return (VMax & 3) + (
SMax & 3) >= 4;
6498AMDGPUInstructionSelector::selectScratchSVAddr(
MachineOperand &Root)
const {
6501 int64_t ConstOffset;
6502 int64_t ImmOffset = 0;
6506 std::tie(PtrBase, ConstOffset, std::ignore) =
6507 getPtrBaseWithConstantOffset(Addr, *MRI);
6510 if (ConstOffset != 0 &&
6514 ImmOffset = ConstOffset;
6518 if (AddrDef->MI->getOpcode() != AMDGPU::G_PTR_ADD)
6519 return std::nullopt;
6521 Register RHS = AddrDef->MI->getOperand(2).getReg();
6522 if (RBI.getRegBank(
RHS, *MRI, TRI)->getID() != AMDGPU::VGPRRegBankID)
6523 return std::nullopt;
6525 Register LHS = AddrDef->MI->getOperand(1).getReg();
6528 if (OrigAddr != Addr) {
6529 if (!isFlatScratchBaseLegalSVImm(OrigAddr))
6530 return std::nullopt;
6532 if (!isFlatScratchBaseLegalSV(OrigAddr))
6533 return std::nullopt;
6536 if (checkFlatScratchSVSSwizzleBug(
RHS,
LHS, ImmOffset))
6537 return std::nullopt;
6539 unsigned CPol = selectScaleOffset(Root,
RHS,
true )
6543 if (LHSDef->MI->getOpcode() == AMDGPU::G_FRAME_INDEX) {
6544 int FI = LHSDef->MI->getOperand(1).getIndex();
6546 [=](MachineInstrBuilder &MIB) { MIB.
addReg(
RHS); },
6548 [=](MachineInstrBuilder &MIB) { MIB.
addImm(ImmOffset); },
6549 [=](MachineInstrBuilder &MIB) { MIB.
addImm(CPol); }
6558 return std::nullopt;
6561 [=](MachineInstrBuilder &MIB) { MIB.
addReg(
RHS); },
6562 [=](MachineInstrBuilder &MIB) { MIB.
addReg(
LHS); },
6563 [=](MachineInstrBuilder &MIB) { MIB.
addImm(ImmOffset); },
6564 [=](MachineInstrBuilder &MIB) { MIB.
addImm(CPol); }
6569AMDGPUInstructionSelector::selectMUBUFScratchOffen(
MachineOperand &Root)
const {
6573 const SIMachineFunctionInfo *
Info =
MF->getInfo<SIMachineFunctionInfo>();
6578 Register HighBits = MRI->createVirtualRegister(&AMDGPU::VGPR_32RegClass);
6583 BuildMI(*
MBB,
MI,
MI->getDebugLoc(), TII.get(AMDGPU::V_MOV_B32_e32),
6587 return {{[=](MachineInstrBuilder &MIB) {
6590 [=](MachineInstrBuilder &MIB) {
6593 [=](MachineInstrBuilder &MIB) {
6598 [=](MachineInstrBuilder &MIB) {
6607 std::optional<int> FI;
6611 int64_t ConstOffset;
6612 std::tie(PtrBase, ConstOffset, std::ignore) =
6613 getPtrBaseWithConstantOffset(VAddr, *MRI);
6615 if (ConstOffset != 0) {
6616 if (TII.isLegalMUBUFImmOffset(ConstOffset) &&
6617 (!STI.privateMemoryResourceIsRangeChecked() ||
6618 VT->signBitIsZero(PtrBase))) {
6629 return {{[=](MachineInstrBuilder &MIB) {
6632 [=](MachineInstrBuilder &MIB) {
6638 [=](MachineInstrBuilder &MIB) {
6643 [=](MachineInstrBuilder &MIB) {
6648bool AMDGPUInstructionSelector::isDSOffsetLegal(
Register Base,
6653 if (STI.hasUsableDSOffset() || STI.unsafeDSOffsetFoldingEnabled())
6658 return VT->signBitIsZero(
Base);
6661bool AMDGPUInstructionSelector::isDSOffset2Legal(
Register Base, int64_t Offset0,
6663 unsigned Size)
const {
6664 if (Offset0 %
Size != 0 || Offset1 %
Size != 0)
6669 if (STI.hasUsableDSOffset() || STI.unsafeDSOffsetFoldingEnabled())
6674 return VT->signBitIsZero(
Base);
6679 return Addr->
getOpcode() == TargetOpcode::G_OR ||
6680 (Addr->
getOpcode() == TargetOpcode::G_PTR_ADD &&
6687bool AMDGPUInstructionSelector::isFlatScratchBaseLegal(
Register Addr)
const {
6695 if (STI.hasSignedScratchOffsets())
6701 if (AddrMI->
getOpcode() == TargetOpcode::G_PTR_ADD) {
6702 std::optional<ValueAndVReg> RhsValReg =
6708 if (RhsValReg && RhsValReg->Value.getSExtValue() < 0 &&
6709 RhsValReg->Value.getSExtValue() > -0x40000000)
6713 return VT->signBitIsZero(
LHS);
6718bool AMDGPUInstructionSelector::isFlatScratchBaseLegalSV(
Register Addr)
const {
6726 if (STI.hasSignedScratchOffsets())
6731 return VT->signBitIsZero(
RHS) &&
VT->signBitIsZero(
LHS);
6736bool AMDGPUInstructionSelector::isFlatScratchBaseLegalSVImm(
6740 if (STI.hasSignedScratchOffsets())
6745 std::optional<DefinitionAndSourceRegister> BaseDef =
6747 std::optional<ValueAndVReg> RHSOffset =
6757 (RHSOffset->Value.getSExtValue() < 0 &&
6758 RHSOffset->Value.getSExtValue() > -0x40000000)))
6761 Register LHS = BaseDef->MI->getOperand(1).getReg();
6762 Register RHS = BaseDef->MI->getOperand(2).getReg();
6763 return VT->signBitIsZero(
RHS) &&
VT->signBitIsZero(
LHS);
6766bool AMDGPUInstructionSelector::isUnneededShiftMask(
const MachineInstr &
MI,
6767 unsigned ShAmtBits)
const {
6768 assert(
MI.getOpcode() == TargetOpcode::G_AND);
6772 std::optional<ValueAndVReg>
RHS =
6777 if (
RHS->
Value.countr_one() >= ShAmtBits)
6780 const APInt &LHSKnownZeros =
VT->getKnownZeroes(
MI.getOperand(1).getReg());
6781 return (LHSKnownZeros |
RHS->
Value).countr_one() >= ShAmtBits;
6785AMDGPUInstructionSelector::selectMUBUFScratchOffset(
6788 const SIMachineFunctionInfo *
Info =
MF->getInfo<SIMachineFunctionInfo>();
6790 std::optional<DefinitionAndSourceRegister>
Def =
6792 assert(Def &&
"this shouldn't be an optional result");
6797 [=](MachineInstrBuilder &MIB) {
6800 [=](MachineInstrBuilder &MIB) {
6803 [=](MachineInstrBuilder &MIB) { MIB.
addImm(0); }
6814 if (!TII.isLegalMUBUFImmOffset(
Offset))
6822 [=](MachineInstrBuilder &MIB) {
6825 [=](MachineInstrBuilder &MIB) {
6833 !TII.isLegalMUBUFImmOffset(
Offset))
6837 [=](MachineInstrBuilder &MIB) {
6840 [=](MachineInstrBuilder &MIB) {
6847std::pair<Register, int64_t>
6848AMDGPUInstructionSelector::selectDS1Addr1OffsetImpl(
6850 int64_t ConstAddr = 0;
6854 std::tie(PtrBase,
Offset, std::ignore) =
6855 getPtrBaseWithConstantOffset(Root.
getReg(), *MRI);
6858 if (isDSOffsetLegal(PtrBase,
Offset)) {
6860 return std::pair(PtrBase,
Offset);
6869 return std::pair(Root.
getReg(), 0);
6873AMDGPUInstructionSelector::selectDS1Addr1Offset(
MachineOperand &Root)
const {
6876 std::tie(
Reg,
Offset) = selectDS1Addr1OffsetImpl(Root);
6878 [=](MachineInstrBuilder &MIB) { MIB.
addReg(
Reg); },
6884AMDGPUInstructionSelector::selectDS64Bit4ByteAligned(
MachineOperand &Root)
const {
6885 return selectDSReadWrite2(Root, 4);
6889AMDGPUInstructionSelector::selectDS128Bit8ByteAligned(
MachineOperand &Root)
const {
6890 return selectDSReadWrite2(Root, 8);
6894AMDGPUInstructionSelector::selectDSReadWrite2(
MachineOperand &Root,
6895 unsigned Size)
const {
6900 [=](MachineInstrBuilder &MIB) { MIB.
addReg(
Reg); },
6902 [=](MachineInstrBuilder &MIB) { MIB.
addImm(
Offset+1); }
6906std::pair<Register, int64_t>
6907AMDGPUInstructionSelector::selectDSReadWrite2Impl(
MachineOperand &Root,
6908 unsigned Size)
const {
6909 int64_t ConstAddr = 0;
6913 std::tie(PtrBase,
Offset, std::ignore) =
6914 getPtrBaseWithConstantOffset(Root.
getReg(), *MRI);
6917 int64_t OffsetValue0 =
Offset;
6919 if (isDSOffset2Legal(PtrBase, OffsetValue0, OffsetValue1,
Size)) {
6921 return std::pair(PtrBase, OffsetValue0 /
Size);
6930 return std::pair(Root.
getReg(), 0);
6938std::tuple<Register, int64_t, bool>
6939AMDGPUInstructionSelector::getPtrBaseWithConstantOffset(
6942 if (RootI->
getOpcode() != TargetOpcode::G_PTR_ADD)
6943 return {Root, 0,
false};
6946 std::optional<ValueAndVReg> MaybeOffset =
6949 return {Root, 0,
false};
6964 Register RSrc2 =
MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6965 Register RSrc3 =
MRI.createVirtualRegister(&AMDGPU::SReg_32RegClass);
6966 Register RSrcHi =
MRI.createVirtualRegister(&AMDGPU::SReg_64RegClass);
6967 Register RSrc =
MRI.createVirtualRegister(&AMDGPU::SGPR_128RegClass);
6969 B.buildInstr(AMDGPU::S_MOV_B32)
6972 B.buildInstr(AMDGPU::S_MOV_B32)
6979 B.buildInstr(AMDGPU::REG_SEQUENCE)
6982 .addImm(AMDGPU::sub0)
6984 .addImm(AMDGPU::sub1);
6988 RSrcLo =
MRI.createVirtualRegister(&AMDGPU::SReg_64RegClass);
6989 B.buildInstr(AMDGPU::S_MOV_B64)
6994 B.buildInstr(AMDGPU::REG_SEQUENCE)
6997 .addImm(AMDGPU::sub0_sub1)
6999 .addImm(AMDGPU::sub2_sub3);
7006 uint64_t DefaultFormat =
TII.getDefaultRsrcDataFormat();
7015 uint64_t DefaultFormat =
TII.getDefaultRsrcDataFormat();
7022AMDGPUInstructionSelector::MUBUFAddressData
7023AMDGPUInstructionSelector::parseMUBUFAddress(
Register Src)
const {
7024 MUBUFAddressData
Data;
7030 std::tie(PtrBase,
Offset, std::ignore) =
7031 getPtrBaseWithConstantOffset(Src, *MRI);
7037 if (MachineInstr *InputAdd
7039 Data.N2 = InputAdd->getOperand(1).getReg();
7040 Data.N3 = InputAdd->getOperand(2).getReg();
7055bool AMDGPUInstructionSelector::shouldUseAddr64(MUBUFAddressData Addr)
const {
7061 const RegisterBank *N0Bank = RBI.getRegBank(Addr.N0, *MRI, TRI);
7062 return N0Bank->
getID() == AMDGPU::VGPRRegBankID;
7068void AMDGPUInstructionSelector::splitIllegalMUBUFOffset(
7070 if (TII.isLegalMUBUFImmOffset(ImmOffset))
7074 SOffset = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
7075 B.buildInstr(AMDGPU::S_MOV_B32)
7081bool AMDGPUInstructionSelector::selectMUBUFAddr64Impl(
7086 if (!STI.hasAddr64() || STI.useFlatForGlobal())
7089 MUBUFAddressData AddrData = parseMUBUFAddress(Root.
getReg());
7090 if (!shouldUseAddr64(AddrData))
7096 Offset = AddrData.Offset;
7102 if (RBI.getRegBank(N2, *MRI, TRI)->getID() == AMDGPU::VGPRRegBankID) {
7104 if (RBI.getRegBank(N3, *MRI, TRI)->getID() == AMDGPU::VGPRRegBankID) {
7117 }
else if (RBI.getRegBank(N0, *MRI, TRI)->getID() == AMDGPU::VGPRRegBankID) {
7128 splitIllegalMUBUFOffset(
B, SOffset,
Offset);
7132bool AMDGPUInstructionSelector::selectMUBUFOffsetImpl(
7137 if (STI.useFlatForGlobal())
7140 MUBUFAddressData AddrData = parseMUBUFAddress(Root.
getReg());
7141 if (shouldUseAddr64(AddrData))
7147 Offset = AddrData.Offset;
7153 splitIllegalMUBUFOffset(
B, SOffset,
Offset);
7158AMDGPUInstructionSelector::selectMUBUFAddr64(
MachineOperand &Root)
const {
7164 if (!selectMUBUFAddr64Impl(Root, VAddr, RSrcReg, SOffset,
Offset))
7170 [=](MachineInstrBuilder &MIB) {
7173 [=](MachineInstrBuilder &MIB) {
7176 [=](MachineInstrBuilder &MIB) {
7179 else if (STI.hasRestrictedSOffset())
7180 MIB.
addReg(AMDGPU::SGPR_NULL);
7184 [=](MachineInstrBuilder &MIB) {
7194AMDGPUInstructionSelector::selectMUBUFOffset(
MachineOperand &Root)
const {
7199 if (!selectMUBUFOffsetImpl(Root, RSrcReg, SOffset,
Offset))
7203 [=](MachineInstrBuilder &MIB) {
7206 [=](MachineInstrBuilder &MIB) {
7209 else if (STI.hasRestrictedSOffset())
7210 MIB.
addReg(AMDGPU::SGPR_NULL);
7222AMDGPUInstructionSelector::selectBUFSOffset(
MachineOperand &Root)
const {
7227 SOffset = AMDGPU::SGPR_NULL;
7229 return {{[=](MachineInstrBuilder &MIB) { MIB.
addReg(SOffset); }}};
7233static std::optional<uint64_t>
7237 if (!OffsetVal || !
isInt<32>(*OffsetVal))
7238 return std::nullopt;
7239 return Lo_32(*OffsetVal);
7243AMDGPUInstructionSelector::selectSMRDBufferImm(
MachineOperand &Root)
const {
7244 std::optional<uint64_t> OffsetVal =
7249 std::optional<int64_t> EncodedImm =
7254 return {{ [=](MachineInstrBuilder &MIB) { MIB.
addImm(*EncodedImm); } }};
7258AMDGPUInstructionSelector::selectSMRDBufferImm32(
MachineOperand &Root)
const {
7265 std::optional<int64_t> EncodedImm =
7270 return {{ [=](MachineInstrBuilder &MIB) { MIB.
addImm(*EncodedImm); } }};
7274AMDGPUInstructionSelector::selectSMRDBufferSgprImm(
MachineOperand &Root)
const {
7282 return std::nullopt;
7284 std::optional<int64_t> EncodedOffset =
7287 return std::nullopt;
7289 assert(MRI->getType(SOffset).getSizeInBits() == 32);
7290 return {{[=](MachineInstrBuilder &MIB) { MIB.
addReg(SOffset); },
7291 [=](MachineInstrBuilder &MIB) { MIB.
addImm(*EncodedOffset); }}};
7294std::pair<Register, unsigned>
7295AMDGPUInstructionSelector::selectVOP3PMadMixModsImpl(
MachineOperand &Root,
7296 bool &Matched)
const {
7301 std::tie(Src, Mods) = selectVOP3ModsImpl(Root.
getReg());
7311 const auto CheckAbsNeg = [&]() {
7316 std::tie(Src, ModsTmp) = selectVOP3ModsImpl(Src);
7346 if (MRI->getType(Src).isFixedVector(2, 16))
7359AMDGPUInstructionSelector::selectVOP3PMadMixModsExt(
7364 std::tie(Src, Mods) = selectVOP3PMadMixModsImpl(Root, Matched);
7369 [=](MachineInstrBuilder &MIB) { MIB.
addReg(widenSrcIfVGPR16(Src, MIB)); },
7370 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }
7375AMDGPUInstructionSelector::selectVOP3PMadMixMods(
MachineOperand &Root)
const {
7379 std::tie(Src, Mods) = selectVOP3PMadMixModsImpl(Root, Matched);
7382 [=](MachineInstrBuilder &MIB) { MIB.
addReg(widenSrcIfVGPR16(Src, MIB)); },
7383 [=](MachineInstrBuilder &MIB) { MIB.
addImm(Mods); }
7388AMDGPUInstructionSelector::selectVOP3PMadMixModsExtNeg(
7393 std::tie(Src, Mods) = selectVOP3PMadMixModsImpl(Root, Matched);
7398 [=](MachineInstrBuilder &MIB) { MIB.
addReg(widenSrcIfVGPR16(Src, MIB)); },
7399 [=](MachineInstrBuilder &MIB) {
7406AMDGPUInstructionSelector::selectVOP3PMadMixModsNeg(
7411 std::tie(Src, Mods) = selectVOP3PMadMixModsImpl(Root, Matched);
7414 [=](MachineInstrBuilder &MIB) { MIB.
addReg(widenSrcIfVGPR16(Src, MIB)); },
7415 [=](MachineInstrBuilder &MIB) {
7421bool AMDGPUInstructionSelector::selectSBarrierSignalIsfirst(
7425 Register CCReg =
I.getOperand(0).getReg();
7430 BuildMI(*
MBB, &
I,
DL, TII.get(AMDGPU::S_BARRIER_SIGNAL_ISFIRST_IMM))
7431 .
addImm(
I.getOperand(2).getImm());
7435 I.eraseFromParent();
7436 return RBI.constrainGenericRegister(CCReg, AMDGPU::SReg_32_XM0_XEXECRegClass,
7440bool AMDGPUInstructionSelector::selectSGetBarrierState(
7444 const MachineOperand &BarOp =
I.getOperand(2);
7445 std::optional<int64_t> BarValImm =
7449 auto CopyMIB =
BuildMI(*
MBB, &
I,
DL, TII.get(AMDGPU::COPY), AMDGPU::M0)
7453 MachineInstrBuilder MIB;
7454 unsigned Opc = BarValImm ? AMDGPU::S_GET_BARRIER_STATE_IMM
7455 : AMDGPU::S_GET_BARRIER_STATE_M0;
7458 auto DstReg =
I.getOperand(0).getReg();
7460 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
7461 if (!DstRC || !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))
7467 I.eraseFromParent();
7472 if (HasInlineConst) {
7476 case Intrinsic::amdgcn_s_barrier_join:
7477 return AMDGPU::S_BARRIER_JOIN_IMM;
7478 case Intrinsic::amdgcn_s_wakeup_barrier:
7479 return AMDGPU::S_WAKEUP_BARRIER_IMM;
7480 case Intrinsic::amdgcn_s_get_named_barrier_state:
7481 return AMDGPU::S_GET_BARRIER_STATE_IMM;
7487 case Intrinsic::amdgcn_s_barrier_join:
7488 return AMDGPU::S_BARRIER_JOIN_M0;
7489 case Intrinsic::amdgcn_s_wakeup_barrier:
7490 return AMDGPU::S_WAKEUP_BARRIER_M0;
7491 case Intrinsic::amdgcn_s_get_named_barrier_state:
7492 return AMDGPU::S_GET_BARRIER_STATE_M0;
7497bool AMDGPUInstructionSelector::selectNamedBarrierInit(
7501 const MachineOperand &BarOp =
I.getOperand(1);
7502 const MachineOperand &CntOp =
I.getOperand(2);
7506 if (IntrID == Intrinsic::amdgcn_s_barrier_signal_var) {
7507 std::optional<int64_t> CntImm =
7509 if (CntImm && *CntImm == 0) {
7510 std::optional<int64_t> BarValImm =
7513 uint32_t BarID = *BarValImm & 0x3F;
7514 BuildMI(*
MBB, &
I,
DL, TII.get(AMDGPU::S_BARRIER_SIGNAL_IMM))
7516 I.eraseFromParent();
7523 Register TmpReg1 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
7532 Register TmpReg2 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
7538 Register TmpReg3 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
7539 constexpr unsigned ShAmt = 16;
7545 Register TmpReg4 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
7555 unsigned Opc = IntrID == Intrinsic::amdgcn_s_barrier_init
7556 ? AMDGPU::S_BARRIER_INIT_M0
7557 : AMDGPU::S_BARRIER_SIGNAL_M0;
7558 MachineInstrBuilder MIB;
7561 I.eraseFromParent();
7565bool AMDGPUInstructionSelector::selectNamedBarrierInst(
7569 MachineOperand BarOp = IntrID == Intrinsic::amdgcn_s_get_named_barrier_state
7572 std::optional<int64_t> BarValImm =
7577 Register TmpReg1 = MRI->createVirtualRegister(&AMDGPU::SReg_32RegClass);
7583 auto CopyMIB =
BuildMI(*
MBB, &
I,
DL, TII.get(AMDGPU::COPY), AMDGPU::M0)
7588 MachineInstrBuilder MIB;
7592 if (IntrID == Intrinsic::amdgcn_s_get_named_barrier_state) {
7593 auto DstReg =
I.getOperand(0).getReg();
7595 TRI.getConstrainedRegClassForReg(DstReg, *MRI);
7596 if (!DstRC || !RBI.constrainGenericRegister(DstReg, *DstRC, *MRI))
7602 uint32_t BarId = *BarValImm & 0x3F;
7606 I.eraseFromParent();
7613 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
7614 "Expected G_CONSTANT");
7615 MIB.
addImm(-
MI.getOperand(1).getCImm()->getSExtValue());
7621 const MachineOperand &
Op =
MI.getOperand(1);
7622 assert(
MI.getOpcode() == TargetOpcode::G_FCONSTANT && OpIdx == -1);
7623 MIB.
addImm(
Op.getFPImm()->getValueAPF().bitcastToAPInt().getZExtValue());
7626void AMDGPUInstructionSelector::renderCountTrailingOnesImm(
7628 assert(
MI.getOpcode() == TargetOpcode::G_CONSTANT && OpIdx == -1 &&
7629 "Expected G_CONSTANT");
7630 MIB.
addImm(
MI.getOperand(1).getCImm()->getValue().countTrailingOnes());
7638 const MachineOperand &
Op =
MI.getOperand(OpIdx);
7649 MIB.
addImm(
MI.getOperand(OpIdx).getImm() != 0);
7655 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7659void AMDGPUInstructionSelector::renderSrcAndDstSelToOpSelXForm_0_0(
7661 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7666void AMDGPUInstructionSelector::renderSrcAndDstSelToOpSelXForm_0_1(
7668 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7669 MIB.
addImm((
MI.getOperand(OpIdx).getImm() & 0x1)
7674void AMDGPUInstructionSelector::renderSrcAndDstSelToOpSelXForm_1_0(
7676 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7681void AMDGPUInstructionSelector::renderSrcAndDstSelToOpSelXForm_1_1(
7683 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7684 MIB.
addImm((
MI.getOperand(OpIdx).getImm() & 0x2)
7689void AMDGPUInstructionSelector::renderDstSelToOpSelXForm(
7691 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7696void AMDGPUInstructionSelector::renderSrcSelToOpSelXForm(
7698 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7703void AMDGPUInstructionSelector::renderSrcAndDstSelToOpSelXForm_2_0(
7705 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7710void AMDGPUInstructionSelector::renderDstSelToOpSel3XFormXForm(
7712 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7713 MIB.
addImm((
MI.getOperand(OpIdx).getImm() & 0x2)
7721 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7722 MIB.
addImm(
MI.getOperand(OpIdx).getImm() &
7730 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7731 const bool Swizzle =
MI.getOperand(OpIdx).getImm() &
7737void AMDGPUInstructionSelector::renderExtractCpolSetGLC(
7739 assert(OpIdx >= 0 &&
"expected to match an immediate operand");
7740 const uint32_t Cpol =
MI.getOperand(OpIdx).getImm() &
7749 const APFloat &APF =
MI.getOperand(1).getFPImm()->getValueAPF();
7751 assert(ExpVal != INT_MIN);
7762 MIB.
addImm((
MI.getOperand(OpIdx).getImm() + 3) % 4);
7769 if (
MI.getOperand(OpIdx).getImm())
7771 MIB.
addImm((int64_t)Mods);
7778 if (
MI.getOperand(OpIdx).getImm())
7780 MIB.
addImm((int64_t)Mods);
7786 unsigned Val =
static_cast<unsigned>(
MI.getOperand(OpIdx).
getImm());
7794 MIB.
addImm((int64_t)Mods);
7802 if (!Subtarget->hasSafeCUPrefetch())
7808void AMDGPUInstructionSelector::renderScaledMAIIntrinsicOperand(
7810 int64_t Val =
MI.getOperand(OpIdx).getImm();
7819bool AMDGPUInstructionSelector::isInlineImmediate(
const APInt &
Imm)
const {
7820 return TII.isInlineConstant(
Imm);
7823bool AMDGPUInstructionSelector::isInlineImmediate(
const APFloat &
Imm)
const {
7824 return TII.isInlineConstant(
Imm);
MachineInstrBuilder MachineInstrBuilder & DefMI
static unsigned getIntrinsicID(const SDNode *N)
#define GET_GLOBALISEL_PREDICATES_INIT
#define GET_GLOBALISEL_TEMPORARIES_INIT
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
static bool isShlHalf(const MachineInstr *MI, const MachineRegisterInfo &MRI)
Test if the MI is shift left with half bits, such as reg0:2n =G_SHL reg1:2n, CONST(n)
static bool isNoUnsignedWrap(MachineInstr *Addr)
static Register buildOffsetSrc(MachineIRBuilder &B, MachineRegisterInfo &MRI, const SIInstrInfo &TII, Register BasePtr)
unsigned getNamedBarrierOp(bool HasInlineConst, Intrinsic::ID IntrID)
static Register getLegalRegBank(Register NewReg, Register RootReg, MachineInstr &Use, const AMDGPURegisterBankInfo &RBI, MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI, const SIInstrInfo &TII)
static bool checkRB(Register Reg, unsigned int RBNo, const AMDGPURegisterBankInfo &RBI, const MachineRegisterInfo &MRI, const TargetRegisterInfo &TRI)
static unsigned updateMods(SrcStatus HiStat, SrcStatus LoStat, unsigned Mods)
static bool isTruncHalf(const MachineInstr *MI, const MachineRegisterInfo &MRI)
Test if the MI is truncating to half, such as reg0:n = G_TRUNC reg1:2n
static Register getWaveAddress(const MachineInstr *Def)
static int getV_CMPOpcode(CmpInst::Predicate P, uint64_t Size, const GCNSubtarget &ST)
static bool isExtractHiElt(MachineRegisterInfo &MRI, Register In, Register &Out)
static std::pair< unsigned, uint8_t > BitOp3_Op(Register R, SmallVectorImpl< Register > &Src, const MachineRegisterInfo &MRI)
static TypeClass isVectorOfTwoOrScalar(Register Reg, const MachineRegisterInfo &MRI)
static bool isLaneMaskFromSameBlock(Register Reg, MachineRegisterInfo &MRI, MachineBasicBlock *MBB)
static bool isExtractLoElt(MachineRegisterInfo &MRI, Register In, Register &Out)
static bool parseTexFail(uint64_t TexFailCtrl, bool &TFE, bool &LWE, bool &IsTexFail)
static void addZeroImm(MachineInstrBuilder &MIB)
static unsigned gwsIntrinToOpcode(unsigned IntrID)
static bool isConstant(const MachineInstr &MI)
static bool isSameBitWidth(Register Reg1, Register Reg2, const MachineRegisterInfo &MRI)
static Register buildRegSequence(SmallVectorImpl< Register > &Elts, MachineInstr *InsertPt, MachineRegisterInfo &MRI)
static Register buildRSRC(MachineIRBuilder &B, MachineRegisterInfo &MRI, uint32_t FormatLo, uint32_t FormatHi, Register BasePtr)
Return a resource descriptor for use with an arbitrary 64-bit pointer.
static bool isAsyncLDSDMA(Intrinsic::ID Intr)
static std::pair< Register, unsigned > computeIndirectRegIndex(MachineRegisterInfo &MRI, const SIRegisterInfo &TRI, const TargetRegisterClass *SuperRC, Register IdxReg, unsigned EltSize, GISelValueTracking &ValueTracking)
Return the register to use for the index value, and the subregister to use for the indirectly accesse...
static bool shouldUseAndMask(uint64_t Size, unsigned &Mask)
static unsigned getLogicalBitOpcode(unsigned Opc, bool Is64)
static std::pair< Register, SrcStatus > getLastSameOrNeg(Register Reg, const MachineRegisterInfo &MRI, SearchOptions SO, int MaxDepth=3)
static Register stripCopy(Register Reg, MachineRegisterInfo &MRI)
static std::optional< std::pair< Register, SrcStatus > > calcNextStatus(std::pair< Register, SrcStatus > Curr, const MachineRegisterInfo &MRI)
static Register stripBitCast(Register Reg, MachineRegisterInfo &MRI)
static std::optional< uint64_t > getConstantZext32Val(Register Reg, const MachineRegisterInfo &MRI)
Get an immediate that must be 32-bits, and treated as zero extended.
static bool isValidToPack(SrcStatus HiStat, SrcStatus LoStat, Register NewReg, Register RootReg, const SIInstrInfo &TII, const MachineRegisterInfo &MRI)
static SmallVector< std::pair< Register, SrcStatus > > getSrcStats(Register Reg, const MachineRegisterInfo &MRI, SearchOptions SO, int MaxDepth=3)
static bool isUnmergeHalf(const MachineInstr *MI, const MachineRegisterInfo &MRI)
Test function, if the MI is reg0:n, reg1:n = G_UNMERGE_VALUES reg2:2n
static SrcStatus getNegStatus(Register Reg, SrcStatus S, const MachineRegisterInfo &MRI)
static bool isVCmpResult(Register Reg, MachineRegisterInfo &MRI)
static Register buildAddr64RSrc(MachineIRBuilder &B, MachineRegisterInfo &MRI, const SIInstrInfo &TII, Register BasePtr)
static bool isLshrHalf(const MachineInstr *MI, const MachineRegisterInfo &MRI)
Test if the MI is logic shift right with half bits, such as reg0:2n =G_LSHR reg1:2n,...
static void selectWMMAModsNegAbs(unsigned ModOpcode, unsigned &Mods, SmallVectorImpl< Register > &Elts, Register &Src, MachineInstr *InsertPt, MachineRegisterInfo &MRI)
This file declares the targeting of the InstructionSelector class for AMDGPU.
AMDGPU Register Bank Select
This file declares the targeting of the RegisterBankInfo class for AMDGPU.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static bool isAllZeros(StringRef Arr)
Return true if the array is empty or all zeros.
Provides analysis for querying information about KnownBits during GISel passes.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
const HexagonInstrInfo * TII
Contains matchers for matching SSA Machine Instructions.
This file declares the MachineIRBuilder class.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
static std::vector< std::pair< int, unsigned > > Swizzle(std::vector< std::pair< int, unsigned > > Src, R600InstrInfo::BankSwizzle Swz)
MachineRegisterInfo & MRI
This is used to control valid status that current MI supports.
bool checkOptions(SrcStatus Stat) const
SearchOptions(Register Reg, const MachineRegisterInfo &MRI)
AMDGPUInstructionSelector(const GCNSubtarget &STI, const AMDGPURegisterBankInfo &RBI)
static const char * getName()
bool select(MachineInstr &I) override
Select the (possibly generic) instruction I to only use target-specific opcodes.
void setupMF(MachineFunction &MF, GISelValueTracking *VT, CodeGenCoverage *CoverageInfo, ProfileSummaryInfo *PSI, BlockFrequencyInfo *BFI) override
Setup per-MF executor state.
uint32_t getLDSSize() const
LLVM_READONLY int getExactLog2Abs() const
Class for arbitrary precision integers.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Constructs an APInt value that has the bottom loBitsSet bits set.
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
int64_t getSExtValue() const
Get sign extended value.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
@ ICMP_SLT
signed less than
@ ICMP_SLE
signed less or equal
@ FCMP_OLT
0 1 0 0 True if ordered and less than
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
@ ICMP_UGE
unsigned greater or equal
@ ICMP_UGT
unsigned greater than
@ ICMP_SGT
signed greater than
@ FCMP_ULT
1 1 0 0 True if unordered or less than
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
@ ICMP_ULT
unsigned less than
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
@ ICMP_SGE
signed greater or equal
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
@ ICMP_ULE
unsigned less or equal
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
DILocation * get() const
Get the underlying DILocation.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
void checkSubtargetFeatures(const Function &F) const
Diagnose inconsistent subtarget features before attempting to codegen function F.
std::optional< SmallVector< std::function< void(MachineInstrBuilder &)>, 4 > > ComplexRendererFns
virtual void setupMF(MachineFunction &mf, GISelValueTracking *vt, CodeGenCoverage *covinfo=nullptr, ProfileSummaryInfo *psi=nullptr, BlockFrequencyInfo *bfi=nullptr)
Setup per-MF executor state.
CodeGenCoverage * CoverageInfo
Register getSourceReg(unsigned I) const
Returns the I'th source register.
unsigned getNumSources() const
Returns the number of source registers.
Represents a G_UNMERGE_VALUES.
unsigned getNumDefs() const
Returns the number of def registers.
Register getSourceReg() const
Get the unmerge source register.
constexpr unsigned getScalarSizeInBits() const
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr bool isValid() const
constexpr uint16_t getNumElements() const
Returns the number of elements in a vector LLT.
constexpr bool isVector() const
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
constexpr unsigned getAddressSpace() const
static constexpr LLT fixed_vector(unsigned NumElements, unsigned ScalarSizeInBits)
Get a low-level fixed-width vector of some number of elements and element width.
constexpr bool isFixedVector() const
Returns true if the LLT is a fixed vector.
static LLT integer(unsigned SizeInBits)
LLT getElementType() const
Returns the vector's element type. Only valid for vector types.
LLVM_ABI void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
TypeSize getValue() const
int getOperandConstraint(unsigned OpNum, MCOI::OperandConstraint Constraint) const
Returns the value of the specified operand constraint if it is present.
bool hasSuperClassEq(const MCRegisterClass *RC) const
Returns true if RC is a super-class of or equal to this class.
unsigned getID() const
getID() - Return the register class ID number.
bool hasSubClassEq(const MCRegisterClass *RC) const
Returns true if RC is a sub-class of or equal to this class.
LLVM_ABI StringRef getString() const
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
void setReturnAddressIsTaken(bool s)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Helper class to build MachineInstr.
const MachineInstrBuilder & setMemRefs(ArrayRef< MachineMemOperand * > MMOs) const
const MachineInstrBuilder & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addUse(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register use operand.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addDef(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a virtual register definition operand.
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
bool getFlag(MIFlag Flag) const
Return whether an MI flag is set.
unsigned getNumOperands() const
Retuns the total number of operands.
LLVM_ABI void tieOperands(unsigned DefIdx, unsigned UseIdx)
Add a tie between the register operands at DefIdx and UseIdx.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LocationSize getSize() const
Return the size in bytes of the memory reference.
unsigned getAddrSpace() const
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
const MachinePointerInfo & getPointerInfo() const
Flags getFlags() const
Return the raw flags of the source value,.
const Value * getValue() const
Return the base address of the memory access.
Align getBaseAlign() const
Return the minimum known alignment in bytes of the base address, without the offset.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
const ConstantInt * getCImm() const
void setImm(int64_t immVal)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static MachineOperand CreateImm(int64_t Val)
bool isEarlyClobber() const
Register getReg() const
getReg - Returns the register number.
bool isInternalRead() const
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Analysis providing profile information.
const RegisterBank & getRegBank(unsigned ID)
Get the register bank identified by ID.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
static unsigned getMaxMUBUFImmOffset(const GCNSubtarget &ST)
static unsigned getDSShaderTypeValue(const MachineFunction &MF)
static unsigned getSubRegFromChannel(uint64_t Channel, uint64_t NumRegs=1)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
constexpr const char * data() const
Get a pointer to the start of the string (which may not be null terminated).
static bool isGenericOpcode(unsigned Opc)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
LLVM_ABI Value(Type *Ty, unsigned scid)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CONSTANT_ADDRESS_32BIT
Address space for 32-bit constant memory.
@ REGION_ADDRESS
Address space for region memory. (GDS)
@ LOCAL_ADDRESS
Address space for local memory.
@ GLOBAL_ADDRESS
Address space for global memory (RAT0, VTX0).
@ PRIVATE_ADDRESS
Address space for private memory.
@ BUFFER_RESOURCE
Address space for 128-bit buffer resources.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
LLVM_READONLY const MIMGG16MappingInfo * getMIMGG16MappingInfo(unsigned G)
std::optional< int64_t > getSMRDEncodedLiteralOffset32(const MCSubtargetInfo &ST, int64_t ByteOffset)
bool isGFX12Plus(const MCSubtargetInfo &STI)
constexpr int64_t getNullPointerValue(unsigned AS)
Get the null pointer value for the given address space.
LLVM_ABI IsaVersion getIsaVersion(StringRef GPU)
unsigned getRegBitWidth(unsigned RCID)
Get the size in bits of a register from the register class RC.
LLVM_READONLY bool hasNamedOperand(uint32_t Opcode, OpName NamedIdx)
int getMIMGOpcode(unsigned BaseOpcode, unsigned MIMGEncoding, unsigned VDataDwords, unsigned VAddrDwords, bool IndexedRsrc, bool IndexedSamp)
bool isInlinableLiteral32(int32_t Literal, bool HasInv2Pi)
bool hasSMRDSignedImmOffset(const MCSubtargetInfo &ST)
LLVM_READONLY int32_t getGlobalSaddrOp(uint32_t Opcode)
bool isGFX13Plus(const MCSubtargetInfo &STI)
bool isGFX11Plus(const MCSubtargetInfo &STI)
bool isGFX10Plus(const MCSubtargetInfo &STI)
std::optional< int64_t > getSMRDEncodedOffset(const MCSubtargetInfo &ST, int64_t ByteOffset, bool IsBuffer, bool HasSOffset)
LLVM_READONLY const MIMGDimInfo * getMIMGDimInfo(unsigned DimEnum)
unsigned getBarrierMemberCountBitMask(const IsaVersion &Version)
LLVM_READONLY const MIMGBaseOpcodeInfo * getMIMGBaseOpcodeInfo(unsigned BaseOpcode)
Intrinsic::ID getIntrinsicID(const MachineInstr &I)
Return the intrinsic ID for opcodes with the G_AMDGPU_INTRIN_ prefix.
std::pair< Register, unsigned > getBaseWithConstantOffset(MachineRegisterInfo &MRI, Register Reg, GISelValueTracking *ValueTracking=nullptr, bool CheckNUW=false)
Returns base register and constant offset.
const ImageDimIntrinsicInfo * getImageDimIntrinsicInfo(unsigned Intr)
IndexMode
ARM Index Modes.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
operand_type_match m_Reg()
SpecificConstantMatch m_SpecificICst(const APInt &RequestedValue)
Matches a constant equal to RequestedValue.
GInstrBind< GBuildVector > m_GBuildVector(GBuildVector *&Inst)
GCstAndRegMatch m_GCst(std::optional< ValueAndVReg > &ValReg)
UnaryOp_match< SrcTy, TargetOpcode::COPY > m_Copy(SrcTy &&Src)
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_XOR, true > m_GXor(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_SEXT > m_GSExt(const SrcTy &Src)
UnaryOp_match< SrcTy, TargetOpcode::G_FPEXT > m_GFPExt(const SrcTy &Src)
SpecificConstantMatch m_ZeroInt()
Convenience matchers for specific integer values.
ConstantMatch< APInt > m_ICst(APInt &Cst)
SpecificConstantMatch m_AllOnesInt()
BinaryOp_match< LHS, RHS, TargetOpcode::G_OR, true > m_GOr(const LHS &L, const RHS &R)
ICstOrSplatMatch< APInt > m_ICstOrSplat(APInt &Cst)
ImplicitDefMatch m_GImplicitDef()
GInstrBind< GConcatVectors > m_GConcatVectors(GConcatVectors *&Inst)
BinaryOp_match< SrcTy, SpecificConstantMatch, TargetOpcode::G_XOR, true > m_Not(const SrcTy &&Src)
Matches a register not-ed by a G_XOR.
GInstrBind< GUnmerge > m_GUnmerge(GUnmerge *&Inst)
Instruction binders for ops with no operand-form matcher (constant-immediate or variadic-source ops).
BinaryOp_match< LHS, RHS, TargetOpcode::G_SUB > m_GSub(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_ASHR, false > m_GAShr(const LHS &L, const RHS &R)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_PTR_ADD, false > m_GPtrAdd(const LHS &L, const RHS &R)
SpecificRegisterMatch m_SpecificReg(Register RequestedReg)
Matches a register only if it is equal to RequestedReg.
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
GFrameIndexMatch m_GFrameIndex(int &FI)
Or< Preds... > m_any_of(Preds &&... preds)
BinaryOp_match< LHS, RHS, TargetOpcode::G_AND, true > m_GAnd(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_BITCAST > m_GBitcast(const SrcTy &Src)
bind_ty< MachineInstr * > m_MInstr(MachineInstr *&MI)
UnaryOp_match< SrcTy, TargetOpcode::G_FNEG > m_GFNeg(const SrcTy &Src)
GFCstOrSplatGFCstMatch m_GFCstOrSplat(std::optional< FPValueAndVReg > &FPValReg)
UnaryOp_match< SrcTy, TargetOpcode::G_FABS > m_GFabs(const SrcTy &Src)
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_ANYEXT > m_GAnyExt(const SrcTy &Src)
ShuffleVectorMatch< Src1Ty, Src2Ty > m_GShuffleVector(const Src1Ty &Src1, const Src2Ty &Src2, ArrayRef< int > &Mask)
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
BinaryOp_match< LHS, RHS, TargetOpcode::G_MUL, true > m_GMul(const LHS &L, const RHS &R)
UnaryOp_match< SrcTy, TargetOpcode::G_TRUNC > m_GTrunc(const SrcTy &Src)
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
@ Lo16
Fixup[15:0] <- Target + Addend.
@ Hi16
Fixup[15:0] <- (Target + Addend + 0x8000) >> 16.
NodeAddr< DefNode * > Def
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI Register getFunctionLiveInPhysReg(MachineFunction &MF, const TargetInstrInfo &TII, MCRegister PhysReg, const TargetRegisterClass &RC, const DebugLoc &DL, LLT RegTy=LLT())
Return a virtual register corresponding to the incoming argument register PhysReg.
LLVM_ABI bool isBuildVectorAllZeros(const MachineInstr &MI, const MachineRegisterInfo &MRI, bool AllowUndef=false)
Return true if the specified instruction is a G_BUILD_VECTOR or G_BUILD_VECTOR_TRUNC where all of the...
LLVM_ABI Register constrainOperandRegClass(const MachineFunction &MF, const TargetRegisterInfo &TRI, MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const RegisterBankInfo &RBI, MachineInstr &InsertPt, const TargetRegisterClass &RegClass, MachineOperand &RegMO)
Constrain the Register operand OpIdx, so that it is now constrained to the TargetRegisterClass passed...
LLVM_ABI MachineInstr * getOpcodeDef(unsigned Opcode, Register Reg, const MachineRegisterInfo &MRI)
See if Reg is defined by an single def instruction that is Opcode.
PointerUnion< const TargetRegisterClass *, const RegisterBank * > RegClassOrRegBank
Convenient type to represent either a register class or a register bank.
LLVM_ABI const ConstantFP * getConstantFPVRegVal(Register VReg, const MachineRegisterInfo &MRI)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
@ Known
Known to have no common set bits.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
unsigned Log2_64_Ceil(uint64_t Value)
Return the ceil log base 2 of the specified value, 64 if the value is zero.
LLVM_ABI void constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
@ Load
The value being inserted comes from a load (InsertElement only).
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
LLVM_ABI MachineInstr * getDefIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, folding away any trivial copies.
constexpr int popcount(T Value) noexcept
Count the number of set bits in a value.
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI std::optional< int64_t > getIConstantVRegSExtVal(Register VReg, const MachineRegisterInfo &MRI)
If VReg is defined by a G_CONSTANT fits in int64_t returns it.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
constexpr uint32_t Hi_32(uint64_t Value)
Return the high 32 bits of a 64 bit value.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI std::optional< ValueAndVReg > getAnyConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true, bool LookThroughAnyExt=false)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT or G_FCONST...
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
constexpr uint32_t Lo_32(uint64_t Value)
Return the low 32 bits of a 64 bit value.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ Or
Bitwise or logical OR of integers.
@ Mul
Product of integers.
@ SMax
Signed integer max implemented in terms of select(cmp()).
@ And
Bitwise or logical AND of integers.
@ Sub
Subtraction of integers.
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI std::optional< ValueAndVReg > getIConstantVRegValWithLookThrough(Register VReg, const MachineRegisterInfo &MRI, bool LookThroughInstrs=true)
If VReg is defined by a statically evaluable chain of instructions rooted on a G_CONSTANT returns its...
LLVM_ABI std::optional< DefinitionAndSourceRegister > getDefSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the def instruction for Reg, and underlying value Register folding away any copies.
LLVM_ABI Register getSrcRegIgnoringCopies(Register Reg, const MachineRegisterInfo &MRI)
Find the source register for Reg, folding away any trivial copies.
constexpr T maskTrailingOnes(unsigned N)
Create a bitmask with the N right-most bits set to 1, and all other bits set to 0.
constexpr RegState getUndefRegState(bool B)
MCRegisterClass TargetRegisterClass
unsigned AtomicNoRetBaseOpcode
static KnownBits makeConstant(const APInt &C)
Create known bits from a known constant.
static KnownBits add(const KnownBits &LHS, const KnownBits &RHS, bool NSW=false, bool NUW=false, bool SelfAdd=false)
Compute knownbits resulting from addition of LHS and RHS.
int64_t Offset
Offset - This is an offset from the base Value*.
PointerUnion< const Value *, const PseudoSourceValue * > V
This is the IR pointer value for the access, or it is null if unknown.