45 virtual ~AMDGPUDAGToDAGISel();
48 const char *getPassName()
const override;
49 void PostprocessISelDAG()
override;
52 bool isInlineImmediate(
SDNode *
N)
const;
55 bool FoldOperands(
unsigned,
const R600InstrInfo *, std::vector<SDValue> &);
56 bool FoldDotOperands(
unsigned,
const R600InstrInfo *, std::vector<SDValue> &);
73 bool isConstantLoad(
const LoadSDNode *
N,
int cbID)
const;
84 bool SelectGlobalValueConstantOffset(
SDValue Addr,
SDValue& IntPtr);
85 bool SelectGlobalValueVariableOffset(
SDValue Addr,
SDValue &BaseReg,
89 bool isDSOffsetLegal(
const SDValue &Base,
unsigned Offset,
90 unsigned OffsetBits)
const;
129 uint32_t Offset, uint32_t Width);
134 #include "AMDGPUGenDAGISel.inc"
141 return new AMDGPUDAGToDAGISel(TM);
149 return SelectionDAGISel::runOnMachineFunction(MF);
152 AMDGPUDAGToDAGISel::~AMDGPUDAGToDAGISel() {
155 bool AMDGPUDAGToDAGISel::isInlineImmediate(
SDNode *
N)
const {
166 unsigned OpNo)
const {
181 return Subtarget->getRegisterInfo()->getRegClass(RegClass);
184 unsigned RCID = cast<ConstantSDNode>(N->
getOperand(0))->getZExtValue();
186 Subtarget->getRegisterInfo()->getRegClass(RCID);
189 unsigned SubRegIdx = cast<ConstantSDNode>(SubRegOp)->getZExtValue();
190 return Subtarget->getRegisterInfo()->getSubClassWithSubReg(SuperRC,
196 bool AMDGPUDAGToDAGISel::SelectADDRParam(
201 R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
202 R2 = CurDAG->getTargetConstant(0,
SDLoc(Addr), MVT::i32);
205 R2 = CurDAG->getTargetConstant(0,
SDLoc(Addr), MVT::i32);
212 R2 = CurDAG->getTargetConstant(0,
SDLoc(Addr), MVT::i32);
222 return SelectADDRParam(Addr, R1, R2);
234 R1 = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i64);
235 R2 = CurDAG->getTargetConstant(0,
SDLoc(Addr), MVT::i64);
238 R2 = CurDAG->getTargetConstant(0,
SDLoc(Addr), MVT::i64);
245 R2 = CurDAG->getTargetConstant(0,
SDLoc(Addr), MVT::i64);
250 SDNode *AMDGPUDAGToDAGISel::glueCopyToM0(
SDNode *N)
const {
251 if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS ||
252 !
checkType(cast<MemSDNode>(N)->getMemOperand()->getValue(),
262 CurDAG->getTargetConstant(-1,
SDLoc(N), MVT::i32));
283 if (isa<AtomicSDNode>(N))
294 Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS)
297 return SelectADD_SUB_I64(N);
307 assert(EltVT.
bitsEq(MVT::i32));
308 if (Subtarget->getGeneration() >= AMDGPUSubtarget::SOUTHERN_ISLANDS) {
312 if (!U->isMachineOpcode()) {
319 if (static_cast<const SIRegisterInfo *>(TRI)->isSGPRClass(RC)) {
323 switch(NumVectorElts) {
324 case 1: RegClassID = UseVReg ? AMDGPU::VGPR_32RegClassID :
325 AMDGPU::SReg_32RegClassID;
327 case 2: RegClassID = UseVReg ? AMDGPU::VReg_64RegClassID :
328 AMDGPU::SReg_64RegClassID;
330 case 4: RegClassID = UseVReg ? AMDGPU::VReg_128RegClassID :
331 AMDGPU::SReg_128RegClassID;
333 case 8: RegClassID = UseVReg ? AMDGPU::VReg_256RegClassID :
334 AMDGPU::SReg_256RegClassID;
336 case 16: RegClassID = UseVReg ? AMDGPU::VReg_512RegClassID :
337 AMDGPU::SReg_512RegClassID;
346 switch(NumVectorElts) {
347 case 2: RegClassID = AMDGPU::R600_Reg64RegClassID;
break;
350 RegClassID = AMDGPU::R600_Reg128VerticalRegClassID;
352 RegClassID = AMDGPU::R600_Reg128RegClassID;
359 SDValue RegClass = CurDAG->getTargetConstant(RegClassID, DL, MVT::i32);
361 if (NumVectorElts == 1) {
366 assert(NumVectorElts <= 16 &&
"Vectors with more than 16 elements not "
373 RegSeqArgs[0] = CurDAG->getTargetConstant(RegClassID, DL, MVT::i32);
374 bool IsRegSeq =
true;
376 for (
unsigned i = 0; i < NOps; i++) {
383 RegSeqArgs[1 + (2 * i) + 1] =
388 if (NOps != NumVectorElts) {
394 for (
unsigned i = NOps; i < NumVectorElts; ++i) {
395 RegSeqArgs[1 + (2 * i)] =
SDValue(ImpDef, 0);
396 RegSeqArgs[1 + (2 * i) + 1] =
408 if (Subtarget->getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS) {
413 RC = CurDAG->getTargetConstant(AMDGPU::SReg_128RegClassID, DL, MVT::i32);
414 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0_sub1, DL, MVT::i32);
415 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub2_sub3, DL, MVT::i32);
417 RC = CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32);
418 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32);
419 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32);
431 if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS ||
437 Imm = FP->getValueAPF().bitcastToAPInt().getZExtValue();
444 SDNode *
Lo = CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32,
445 CurDAG->getConstant(Imm & 0xFFFFFFFF, DL,
447 SDNode *
Hi = CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32,
448 CurDAG->getConstant(Imm >> 32, DL, MVT::i32));
450 CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32),
451 SDValue(Lo, 0), CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32),
452 SDValue(Hi, 0), CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32)
480 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(N, 0), BitCast);
498 CurDAG->ReplaceAllUsesOfValueWith(
SDValue(N, 0), NewStore);
502 return SelectCode(NewValue.
getNode());
515 if (Subtarget->getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS)
520 SelectADDRIndirect(N->
getOperand(1), Addr, Offset);
524 CurDAG->getTargetConstant(0, DL, MVT::i32),
527 return CurDAG->getMachineNode(AMDGPU::SI_RegisterLoad, DL,
528 CurDAG->getVTList(MVT::i32, MVT::i64,
533 if (Subtarget->getGeneration() <= AMDGPUSubtarget::NORTHERN_ISLANDS)
536 SelectADDRIndirect(N->
getOperand(2), Addr, Offset);
542 CurDAG->getTargetConstant(0, DL, MVT::i32),
545 return CurDAG->getMachineNode(AMDGPU::SI_RegisterStorePseudo, DL,
552 if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS)
576 return getS_BFE(Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32,
SDLoc(N),
581 return SelectDIV_SCALE(N);
590 return SelectAddrSpaceCast(N);
595 Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS)
598 return SelectS_BFE(N);
601 return SelectCode(N);
606 assert(AS != 0 &&
"Use checkPrivateAddress instead.");
623 bool AMDGPUDAGToDAGISel::isGlobalStore(
const StoreSDNode *N) {
627 bool AMDGPUDAGToDAGISel::isPrivateStore(
const StoreSDNode *N) {
634 bool AMDGPUDAGToDAGISel::isLocalStore(
const StoreSDNode *N) {
638 bool AMDGPUDAGToDAGISel::isFlatStore(
const StoreSDNode *N) {
642 bool AMDGPUDAGToDAGISel::isRegionStore(
const StoreSDNode *N) {
646 bool AMDGPUDAGToDAGISel::isConstantLoad(
const LoadSDNode *N,
int CbId)
const {
654 bool AMDGPUDAGToDAGISel::isGlobalLoad(
const LoadSDNode *N)
const {
656 if (Subtarget->getGeneration() < AMDGPUSubtarget::SOUTHERN_ISLANDS ||
663 bool AMDGPUDAGToDAGISel::isParamLoad(
const LoadSDNode *N)
const {
667 bool AMDGPUDAGToDAGISel::isLocalLoad(
const LoadSDNode *N)
const {
671 bool AMDGPUDAGToDAGISel::isFlatLoad(
const LoadSDNode *N)
const {
675 bool AMDGPUDAGToDAGISel::isRegionLoad(
const LoadSDNode *N)
const {
679 bool AMDGPUDAGToDAGISel::isCPLoad(
const LoadSDNode *N)
const {
684 if (PSV && PSV == PseudoSourceValue::getConstantPool()) {
692 bool AMDGPUDAGToDAGISel::isPrivateLoad(
const LoadSDNode *N)
const {
696 if (isCPLoad(N) || isConstantLoad(N, -1)) {
714 const char *AMDGPUDAGToDAGISel::getPassName()
const {
715 return "AMDGPU DAG->DAG Pattern Instruction Selection";
727 bool AMDGPUDAGToDAGISel::SelectGlobalValueConstantOffset(
SDValue Addr,
730 IntPtr = CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4,
SDLoc(Addr),
737 bool AMDGPUDAGToDAGISel::SelectGlobalValueVariableOffset(
SDValue Addr,
739 if (!isa<ConstantSDNode>(Addr)) {
741 Offset = CurDAG->getIntPtrConstant(0,
SDLoc(Addr),
true);
747 bool AMDGPUDAGToDAGISel::SelectADDRVTX_READ(
SDValue Addr,
SDValue &Base,
753 &&
isInt<16>(IMMOffset->getZExtValue())) {
756 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(),
SDLoc(Addr),
760 }
else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr))
761 &&
isInt<16>(IMMOffset->getZExtValue())) {
762 Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
763 SDLoc(CurDAG->getEntryNode()),
764 AMDGPU::ZERO, MVT::i32);
765 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(),
SDLoc(Addr),
772 Offset = CurDAG->getTargetConstant(0,
SDLoc(Addr), MVT::i32);
776 bool AMDGPUDAGToDAGISel::SelectADDRIndirect(
SDValue Addr,
SDValue &Base,
781 if ((C = dyn_cast<ConstantSDNode>(Addr))) {
782 Base = CurDAG->getRegister(AMDGPU::INDIRECT_BASE_ADDR, MVT::i32);
783 Offset = CurDAG->getTargetConstant(C->
getZExtValue(),
DL, MVT::i32);
785 (C = dyn_cast<ConstantSDNode>(Addr.
getOperand(1)))) {
787 Offset = CurDAG->getTargetConstant(C->
getZExtValue(),
DL, MVT::i32);
790 Offset = CurDAG->getTargetConstant(0, DL, MVT::i32);
796 SDNode *AMDGPUDAGToDAGISel::SelectADD_SUB_I64(
SDNode *N) {
803 SDValue Sub0 = CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32);
804 SDValue Sub1 = CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32);
807 DL, MVT::i32, LHS, Sub0);
809 DL, MVT::i32, LHS, Sub1);
812 DL, MVT::i32, RHS, Sub0);
814 DL, MVT::i32, RHS, Sub1);
816 SDVTList VTList = CurDAG->getVTList(MVT::i32, MVT::Glue);
820 unsigned Opc = IsAdd ? AMDGPU::S_ADD_U32 : AMDGPU::S_SUB_U32;
821 unsigned CarryOpc = IsAdd ? AMDGPU::S_ADDC_U32 : AMDGPU::S_SUBB_U32;
823 SDNode *AddLo = CurDAG->getMachineNode( Opc, DL, VTList, AddLoArgs);
826 = CurDAG->getMachineNode(CarryOpc, DL, MVT::i32,
830 CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32),
841 SDNode *AMDGPUDAGToDAGISel::SelectDIV_SCALE(
SDNode *N) {
845 assert(VT == MVT::f32 || VT == MVT::f64);
848 = (VT == MVT::f64) ? AMDGPU::V_DIV_SCALE_F64 : AMDGPU::V_DIV_SCALE_F32;
853 SelectVOP3Mods0(N->
getOperand(0), Ops[1], Ops[0], Ops[6], Ops[7]);
854 SelectVOP3Mods(N->
getOperand(1), Ops[3], Ops[2]);
855 SelectVOP3Mods(N->
getOperand(2), Ops[5], Ops[4]);
856 return CurDAG->SelectNodeTo(N, Opc, VT, MVT::i1, Ops);
859 bool AMDGPUDAGToDAGISel::isDSOffsetLegal(
const SDValue &Base,
unsigned Offset,
860 unsigned OffsetBits)
const {
861 if ((OffsetBits == 16 && !
isUInt<16>(Offset)) ||
865 if (Subtarget->getGeneration() >= AMDGPUSubtarget::SEA_ISLANDS ||
866 Subtarget->unsafeDSOffsetFoldingEnabled())
871 return CurDAG->SignBitIsZero(Base);
874 bool AMDGPUDAGToDAGISel::SelectDS1Addr1Offset(
SDValue Addr,
SDValue &Base,
876 if (CurDAG->isBaseWithConstantOffset(Addr)) {
894 if (
const ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) {
896 SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32);
897 MachineSDNode *MovZero = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32,
907 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16);
911 bool AMDGPUDAGToDAGISel::SelectDS64Bit4ByteAligned(
SDValue Addr,
SDValue &Base,
916 if (CurDAG->isBaseWithConstantOffset(Addr)) {
921 unsigned DWordOffset1 = DWordOffset0 + 1;
923 if (isDSOffsetLegal(N0, DWordOffset1, 8)) {
925 Offset0 = CurDAG->getTargetConstant(DWordOffset0, DL, MVT::i8);
926 Offset1 = CurDAG->getTargetConstant(DWordOffset1, DL, MVT::i8);
931 if (
const ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) {
932 unsigned DWordOffset0 = CAddr->getZExtValue() / 4;
933 unsigned DWordOffset1 = DWordOffset0 + 1;
934 assert(4 * DWordOffset0 == CAddr->getZExtValue());
937 SDValue Zero = CurDAG->getTargetConstant(0, DL, MVT::i32);
939 = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32,
942 Offset0 = CurDAG->getTargetConstant(DWordOffset0, DL, MVT::i8);
943 Offset1 = CurDAG->getTargetConstant(DWordOffset1, DL, MVT::i8);
950 Offset0 = CurDAG->getTargetConstant(0, DL, MVT::i8);
951 Offset1 = CurDAG->getTargetConstant(1, DL, MVT::i8);
967 GLC = CurDAG->getTargetConstant(0, DL, MVT::i1);
968 SLC = CurDAG->getTargetConstant(0, DL, MVT::i1);
969 TFE = CurDAG->getTargetConstant(0, DL, MVT::i1);
971 Idxen = CurDAG->getTargetConstant(0, DL, MVT::i1);
972 Offen = CurDAG->getTargetConstant(0, DL, MVT::i1);
973 Addr64 = CurDAG->getTargetConstant(0, DL, MVT::i1);
974 SOffset = CurDAG->getTargetConstant(0, DL, MVT::i32);
976 if (CurDAG->isBaseWithConstantOffset(Addr)) {
985 Addr64 = CurDAG->getTargetConstant(1, DL, MVT::i1);
991 VAddr = CurDAG->getTargetConstant(0, DL, MVT::i32);
996 Offset = CurDAG->getTargetConstant(C1->
getZExtValue(),
DL, MVT::i16);
1000 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16);
1001 SOffset =
SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32,
1012 Addr64 = CurDAG->getTargetConstant(1, DL, MVT::i1);
1015 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16);
1020 VAddr = CurDAG->getTargetConstant(0, DL, MVT::i32);
1022 Offset = CurDAG->getTargetConstant(0, DL, MVT::i16);
1026 bool AMDGPUDAGToDAGISel::SelectMUBUFAddr64(
SDValue Addr,
SDValue &SRsrc,
1030 SDValue Ptr, Offen, Idxen, Addr64;
1033 if (Subtarget->getGeneration() >= AMDGPUSubtarget::VOLCANIC_ISLANDS)
1036 SelectMUBUF(Addr, Ptr, VAddr, SOffset, Offset, Offen, Idxen, Addr64,
1053 bool AMDGPUDAGToDAGISel::SelectMUBUFAddr64(
SDValue Addr,
SDValue &SRsrc,
1057 SLC = CurDAG->getTargetConstant(0,
SDLoc(Addr), MVT::i1);
1060 return SelectMUBUFAddr64(Addr, SRsrc, VAddr, SOffset, Offset, GLC, SLC, TFE);
1063 bool AMDGPUDAGToDAGISel::SelectMUBUFScratch(
SDValue Addr,
SDValue &Rsrc,
1070 static_cast<const SIRegisterInfo *
>(Subtarget->getRegisterInfo());
1075 unsigned ScratchOffsetReg =
1078 ScratchOffsetReg, MVT::i32);
1079 SDValue Sym0 = CurDAG->getExternalSymbol(
"SCRATCH_RSRC_DWORD0", MVT::i32);
1081 SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, Sym0), 0);
1083 SDValue Sym1 = CurDAG->getExternalSymbol(
"SCRATCH_RSRC_DWORD1", MVT::i32);
1085 SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32, Sym1), 0);
1088 CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL, MVT::i32),
1090 CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32),
1092 CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32),
1095 MVT::v2i32, RsrcOps), 0);
1097 SOffset = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
DL,
1101 if (CurDAG->isBaseWithConstantOffset(Addr)) {
1105 if (CurDAG->SignBitIsZero(N0)) {
1109 ImmOffset = CurDAG->getTargetConstant(C1->
getZExtValue(),
DL, MVT::i16);
1117 ImmOffset = CurDAG->getTargetConstant(0, DL, MVT::i16);
1121 bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(
SDValue Addr,
SDValue &SRsrc,
1125 SDValue Ptr, VAddr, Offen, Idxen, Addr64;
1127 static_cast<const SIInstrInfo *
>(Subtarget->getInstrInfo());
1129 SelectMUBUF(Addr, Ptr, VAddr, SOffset, Offset, Offen, Idxen, Addr64,
1132 if (!cast<ConstantSDNode>(Offen)->getSExtValue() &&
1133 !cast<ConstantSDNode>(Idxen)->getSExtValue() &&
1134 !cast<ConstantSDNode>(Addr64)->getSExtValue()) {
1136 APInt::getAllOnesValue(32).getZExtValue();
1148 bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(
SDValue Addr,
SDValue &SRsrc,
1153 return SelectMUBUFOffset(Addr, SRsrc, Soffset, Offset, GLC, SLC, TFE);
1157 SDNode *AMDGPUDAGToDAGISel::SelectAddrSpaceCast(
SDNode *N) {
1161 assert(Subtarget->hasFlatAddressSpace() &&
1162 "addrspacecast only supported with flat address space!");
1166 "Cannot cast address space to / from constant address!");
1170 "Can only cast to / from flat address space!");
1183 if (SrcSize > DestSize) {
1184 assert(SrcSize == 64 && DestSize == 32);
1185 return CurDAG->getMachineNode(
1190 CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32));
1194 if (DestSize > SrcSize) {
1195 assert(SrcSize == 32 && DestSize == 64);
1199 SDValue RC = CurDAG->getTargetConstant(AMDGPU::VS_64RegClassID, DL,
1205 CurDAG->getTargetConstant(AMDGPU::sub0, DL, MVT::i32),
1206 SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL, MVT::i32,
1207 CurDAG->getConstant(0, DL, MVT::i32)), 0),
1208 CurDAG->getTargetConstant(AMDGPU::sub1, DL, MVT::i32)
1215 assert(SrcSize == 64 && DestSize == 64);
1216 return CurDAG->getNode(
ISD::BITCAST, DL, DestVT, Src).getNode();
1220 uint32_t Offset, uint32_t Width) {
1224 uint32_t PackedVal = Offset | (Width << 16);
1225 SDValue PackedConst = CurDAG->getTargetConstant(PackedVal, DL, MVT::i32);
1227 return CurDAG->getMachineNode(Opcode, DL, MVT::i32, Val, PackedConst);
1230 SDNode *AMDGPUDAGToDAGISel::SelectS_BFEFromShifts(
SDNode *N) {
1241 uint32_t CVal = C->getZExtValue();
1243 if (0 < BVal && BVal <= CVal && CVal < 32) {
1245 unsigned Opcode = Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32;
1248 CVal - BVal, 32 - CVal);
1251 return SelectCode(N);
1264 if (Shift && Mask) {
1266 uint32_t MaskVal = Mask->getZExtValue();
1272 ShiftVal, WidthVal);
1285 if (Shift && Mask) {
1287 uint32_t MaskVal = Mask->getZExtValue() >> ShiftVal;
1293 ShiftVal, WidthVal);
1297 return SelectS_BFEFromShifts(N);
1301 return SelectS_BFEFromShifts(N);
1305 return SelectCode(N);
1325 SrcMods = CurDAG->getTargetConstant(Mods,
SDLoc(In), MVT::i32);
1330 bool AMDGPUDAGToDAGISel::SelectVOP3NoMods(
SDValue In,
SDValue &Src,
1332 bool Res = SelectVOP3Mods(In, Src, SrcMods);
1333 return Res && cast<ConstantSDNode>(SrcMods)->isNullValue();
1336 bool AMDGPUDAGToDAGISel::SelectVOP3Mods0(
SDValue In,
SDValue &Src,
1341 Clamp = CurDAG->getTargetConstant(0, DL, MVT::i32);
1342 Omod = CurDAG->getTargetConstant(0, DL, MVT::i32);
1344 return SelectVOP3Mods(In, Src, SrcMods);
1347 bool AMDGPUDAGToDAGISel::SelectVOP3NoMods0(
SDValue In,
SDValue &Src,
1350 bool Res = SelectVOP3Mods0(In, Src, SrcMods, Clamp, Omod);
1352 return Res && cast<ConstantSDNode>(SrcMods)->isNullValue() &&
1353 cast<ConstantSDNode>(Clamp)->isNullValue() &&
1354 cast<ConstantSDNode>(Omod)->isNullValue();
1357 bool AMDGPUDAGToDAGISel::SelectVOP3Mods0Clamp(
SDValue In,
SDValue &Src,
1361 Omod = CurDAG->getTargetConstant(0,
SDLoc(In), MVT::i32);
1363 return SelectVOP3Mods(In, Src, SrcMods);
1366 bool AMDGPUDAGToDAGISel::SelectVOP3Mods0Clamp0OMod(
SDValue In,
SDValue &Src,
1370 Clamp = Omod = CurDAG->getTargetConstant(0,
SDLoc(In), MVT::i32);
1371 return SelectVOP3Mods(In, Src, SrcMods);
1374 void AMDGPUDAGToDAGISel::PostprocessISelDAG() {
1377 bool IsModified =
false;
1381 for (
SDNode &Node : CurDAG->allnodes()) {
1387 if (ResNode != &Node) {
1388 ReplaceUses(&Node, ResNode);
1392 CurDAG->RemoveDeadNodes();
1393 }
while (IsModified);
bool isUInt< 8 >(uint64_t x)
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
void push_back(const T &Elt)
SDValue getValue(unsigned R) const
AMDGPU specific subclass of TargetSubtarget.
void legalizeTargetIndependentNode(SDNode *Node, SelectionDAG &DAG) const
Legalize target independent instructions (e.g.
Interface definition for R600InstrInfo.
unsigned getDestAddressSpace() const
SDVTList getVTList() const
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Describe properties that are true of each instruction in the target description file.
unsigned getSrcAddressSpace() const
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or anything else with this node...
unsigned getNumOperands() const
Return the number of values used by this operation.
const SDValue & getOperand(unsigned Num) const
Address space for local memory.
void setNodeId(int Id)
Set unique node id.
unsigned getPointerAddressSpace() const
Get the address space of this pointer or pointer vector type.
const SDValue & getBasePtr() const
virtual SDNode * PostISelFolding(MachineSDNode *N, SelectionDAG &DAG) const
bool bitsLT(EVT VT) const
bitsLT - Return true if this has less bits than VT.
MachineSDNode * buildScratchRSRC(SelectionDAG &DAG, SDLoc DL, SDValue Ptr) const
static Type * checkType(Type *Ty)
MachineMemOperand - A description of a memory reference used in the backend.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
const HexagonInstrInfo * TII
MachineSDNode * buildRSRC(SelectionDAG &DAG, SDLoc DL, SDValue Ptr, uint32_t RsrcDword1, uint64_t RsrcDword2And3) const
Return a resource descriptor with the 'Add TID' bit enabled The TID (Thread ID) is multipled by the s...
Shift and rotation operations.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
int32_t analyzeImmediate(const SDNode *N) const
Analyze the possible immediate value Op.
CopyToReg - This node has three operands: a chain, a register number to set to this value...
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
EVT getVectorElementType() const
getVectorElementType - Given a vector type, return the type of each element.
TargetRegisterInfo interface that is implemented by all hw codegen targets.
const SDValue & getBasePtr() const
EVT getMemoryVT() const
Return the type of the in-memory value.
PointerType - Class to represent pointers.
This class is used to represent ISD::STORE nodes.
Address space for region memory.
This node is for VLIW targets and it is used to represent a vector that is stored in consecutive regi...
BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the specified, possibly variable...
static bool isLegalMUBUFImmOffset(const ConstantSDNode *Imm)
SDNode * getNode() const
get the SDNode which holds the desired result
IMPLICIT_DEF - This is the MachineInstr-level equivalent of undef.
SDValue CreateLiveInRegister(SelectionDAG &DAG, const TargetRegisterClass *RC, unsigned Reg, EVT VT) const override
Helper function that adds Reg to the LiveIn list of the DAG's MachineFunction.
const SDValue & getOperand(unsigned i) const
Address space for constant memory.
Address space for private memory.
FunctionPass * createAMDGPUISelDag(TargetMachine &tm)
This pass converts a legalized DAG into a AMDGPU-specific.
unsigned getSubRegFromChannel(unsigned Channel) const
unsigned getLiveInVirtReg(unsigned PReg) const
getLiveInVirtReg - If PReg is a live-in physical register, return the corresponding live-in physical ...
MachineSDNode * wrapAddr64Rsrc(SelectionDAG &DAG, SDLoc DL, SDValue Ptr) const
unsigned getPreloadedValue(const MachineFunction &MF, enum PreloadedValue Value) const
Returns the physical register that Value is stored in.
SI DAG Lowering interface definition.
This class provides iterator support for SDUse operands that use a specific SDNode.
unsigned getOpcode() const
FunctionPass class - This class is used to implement most global optimizations.
uint64_t getDefaultRsrcDataFormat() const
const PseudoSourceValue * getPseudoValue() const
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
Address space for flat memory.
const SDValue & getValue() const
EVT - Extended Value Type.
bool bitsEq(EVT VT) const
bitsEq - Return true if this has the same number of bits as VT.
static bool FoldOperand(SDNode *ParentNode, unsigned SrcIdx, SDValue &Src, SDValue &Neg, SDValue &Abs, SDValue &Sel, SDValue &Imm, SelectionDAG &DAG)
REG_SEQUENCE - This variadic instruction is used to form a register that represents a consecutive seq...
EXTRACT_SUBREG - This instruction takes two operands: a register that has subregisters, and a subregister index.
unsigned countPopulation(T Value)
Count the number of set bits in a value.
shadow stack gc Shadow Stack GC Lowering
Interface definition of the TargetLowering class that is common to all AMD GPUs.
ADDRSPACECAST - This operator converts between pointers of different address spaces.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Type * getType() const
All values are typed, get the type of this value.
An SDNode that represents everything that will be needed to construct a MachineInstr.
const SDValue & getChain() const
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
ISD::LoadExtType getExtensionType() const
Return whether this is a plain node, or one of the varieties of value-extending loads.
const Value * getValue() const
getValue - Return the base address of the memory access.
bool isUInt< 32 >(uint64_t x)
PseudoSourceValue - Special value supplied for machine level alias analysis.
int64_t getSExtValue() const
bool isMask_32(uint32_t Value)
isMask_32 - This function returns true if the argument is a non-empty sequence of ones starting at th...
LLVM_ATTRIBUTE_UNUSED_RESULT std::enable_if< !is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
APInt And(const APInt &LHS, const APInt &RHS)
Bitwise AND function for APInt.
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
unsigned getAddressSpace() const
Return the address space for the associated pointer.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Address space for indirect addressible parameter memory (VTX1)
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
unsigned getSizeInBits() const
getSizeInBits - Return the size of the specified value type in bits.
COPY_TO_REGCLASS - This instruction is a placeholder for a plain register-to-register copy into a spe...
bool isInt< 16 >(int64_t x)
Address space for direct addressible parameter memory (CONST0)
EVT getValueType() const
Return the ValueType of the referenced return value.
LLVM Value Representation.
bool isTruncatingStore() const
Return true if the op does a truncation before store.
SDValue copyToM0(SelectionDAG &DAG, SDValue Chain, SDLoc DL, SDValue V) const
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const MCOperandInfo * OpInfo
bool isUInt< 16 >(uint64_t x)
Primary interface to the complete machine description for the target machine.
C - The default llvm calling convention, compatible with C.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW, FLOG, FLOG2, FLOG10, FEXP, FEXP2, FCEIL, FTRUNC, FRINT, FNEARBYINT, FROUND, FFLOOR - Perform various unary floating point operations.
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
Address space for global memory (RAT0, VTX0).
uint64_t getZExtValue() const
unsigned getVectorNumElements() const
getVectorNumElements - Given a vector type, return the number of elements it contains.
This class is used to represent ISD::LOAD nodes.