75 bool EnableLateStructurizeCFG;
83 ~AMDGPUDAGToDAGISel()
override =
default;
95 void PostprocessISelDAG()
override;
98 void SelectBuildVector(
SDNode *
N,
unsigned RegClassID);
101 std::pair<SDValue, SDValue> foldFrameIndex(
SDValue N)
const;
103 bool isInlineImmediate(
const SDNode *
N)
const;
104 bool isVGPRImm(
const SDNode *
N)
const;
105 bool isUniformLoad(
const SDNode *
N)
const;
106 bool isUniformBr(
const SDNode *
N)
const;
116 unsigned OffsetBits)
const;
130 bool SelectMUBUFScratchOffen(
SDNode *Parent,
133 bool SelectMUBUFScratchOffset(
SDNode *Parent,
150 template <
bool IsSigned>
193 bool SelectVOP3PMadMixModsImpl(
SDValue In,
SDValue &Src,
unsigned &Mods)
const;
198 void SelectADD_SUB_I64(
SDNode *
N);
199 void SelectUADDO_USUBO(
SDNode *
N);
200 void SelectDIV_SCALE(
SDNode *
N);
201 void SelectMAD_64_32(
SDNode *
N);
202 void SelectFMA_W_CHAIN(
SDNode *
N);
203 void SelectFMUL_W_CHAIN(
SDNode *
N);
207 void SelectS_BFEFromShifts(
SDNode *
N);
209 bool isCBranchSCC(
const SDNode *
N)
const;
211 void SelectFMAD_FMA(
SDNode *
N);
212 void SelectATOMIC_CMP_SWAP(
SDNode *
N);
216 #include "AMDGPUGenDAGISel.inc" 219 class R600DAGToDAGISel :
public AMDGPUDAGToDAGISel {
222 bool isConstantLoad(
const MemSDNode *
N,
int cbID)
const;
223 bool SelectGlobalValueConstantOffset(
SDValue Addr,
SDValue& IntPtr);
224 bool SelectGlobalValueVariableOffset(
SDValue Addr,
SDValue &BaseReg,
228 AMDGPUDAGToDAGISel(TM, OptLevel) {}
240 #include "R600GenDAGISel.inc" 246 "AMDGPU DAG->DAG Pattern Instruction Selection",
false,
false)
256 CodeGenOpt::
Level OptLevel) {
257 return new AMDGPUDAGToDAGISel(TM, OptLevel);
264 return new R600DAGToDAGISel(TM, OptLevel);
272 bool AMDGPUDAGToDAGISel::isNoNanSrc(
SDValue N)
const {
273 if (
TM.Options.NoNaNsFPMath)
280 return CurDAG->isKnownNeverNaN(N);
283 bool AMDGPUDAGToDAGISel::isInlineImmediate(
const SDNode *N)
const {
300 unsigned OpNo)
const {
328 return Subtarget->getRegisterInfo()->getRegClass(RegClass);
330 case AMDGPU::REG_SEQUENCE: {
331 unsigned RCID = cast<ConstantSDNode>(N->
getOperand(0))->getZExtValue();
333 Subtarget->getRegisterInfo()->getRegClass(RCID);
336 unsigned SubRegIdx = cast<ConstantSDNode>(SubRegOp)->getZExtValue();
337 return Subtarget->getRegisterInfo()->getSubClassWithSubReg(SuperRC,
343 SDNode *AMDGPUDAGToDAGISel::glueCopyToM0(
SDNode *N)
const {
345 !Subtarget->ldsRequiresM0Init())
368 SDNode *
Lo = CurDAG->getMachineNode(
370 CurDAG->getConstant(Imm & 0xFFFFFFFF, DL,
MVT::i32));
372 CurDAG->getMachineNode(AMDGPU::S_MOV_B32, DL,
MVT::i32,
373 CurDAG->getConstant(Imm >> 32, DL,
MVT::i32));
375 CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL,
MVT::i32),
377 SDValue(Hi, 0), CurDAG->getTargetConstant(AMDGPU::sub1, DL,
MVT::i32)};
379 return CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, VT, Ops);
383 switch (NumVectorElts) {
385 return AMDGPU::SReg_32_XM0RegClassID;
387 return AMDGPU::SReg_64RegClassID;
389 return AMDGPU::SReg_128RegClassID;
391 return AMDGPU::SReg_256RegClassID;
393 return AMDGPU::SReg_512RegClassID;
401 Out =
C->getAPIntValue().getZExtValue();
406 Out =
C->getValueAPF().bitcastToAPInt().getZExtValue();
413 void AMDGPUDAGToDAGISel::SelectBuildVector(
SDNode *N,
unsigned RegClassID) {
418 SDValue RegClass = CurDAG->getTargetConstant(RegClassID, DL,
MVT::i32);
420 if (NumVectorElts == 1) {
421 CurDAG->SelectNodeTo(N, AMDGPU::COPY_TO_REGCLASS, EltVT, N->
getOperand(0),
426 assert(NumVectorElts <= 16 &&
"Vectors with more than 16 elements not " 433 RegSeqArgs[0] = CurDAG->getTargetConstant(RegClassID, DL,
MVT::i32);
434 bool IsRegSeq =
true;
436 for (
unsigned i = 0; i < NOps; i++) {
444 RegSeqArgs[1 + (2 * i) + 1] = CurDAG->getTargetConstant(Sub, DL,
MVT::i32);
446 if (NOps != NumVectorElts) {
449 MachineSDNode *ImpDef = CurDAG->getMachineNode(TargetOpcode::IMPLICIT_DEF,
451 for (
unsigned i = NOps; i < NumVectorElts; ++i) {
453 RegSeqArgs[1 + (2 * i)] =
SDValue(ImpDef, 0);
454 RegSeqArgs[1 + (2 * i) + 1] =
455 CurDAG->getTargetConstant(Sub, DL,
MVT::i32);
461 CurDAG->SelectNodeTo(N, AMDGPU::REG_SEQUENCE, N->
getVTList(), RegSeqArgs);
471 if (isa<AtomicSDNode>(N) ||
491 SelectADD_SUB_I64(N);
496 SelectUADDO_USUBO(N);
500 SelectFMUL_W_CHAIN(N);
504 SelectFMA_W_CHAIN(N);
517 uint32_t K = LHSVal | (RHSVal << 16);
518 CurDAG->SelectNodeTo(N, AMDGPU::S_MOV_B32, VT,
529 SelectBuildVector(N, RegClassID);
536 RC = CurDAG->getTargetConstant(AMDGPU::SReg_128RegClassID, DL,
MVT::i32);
537 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0_sub1, DL,
MVT::i32);
538 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub2_sub3, DL,
MVT::i32);
540 RC = CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL,
MVT::i32);
541 SubReg0 = CurDAG->getTargetConstant(AMDGPU::sub0, DL,
MVT::i32);
542 SubReg1 = CurDAG->getTargetConstant(AMDGPU::sub1, DL,
MVT::i32);
548 ReplaceNode(N, CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL,
560 Imm =
FP->getValueAPF().bitcastToAPInt().getZExtValue();
567 ReplaceNode(N, buildSMovImm64(DL, Imm, N->
getValueType(0)));
601 ReplaceNode(N, getS_BFE(Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32,
637 SelectATOMIC_CMP_SWAP(N);
647 N = CurDAG->MorphNodeTo(N, N->
getOpcode(), CurDAG->getVTList(NewVT),
658 bool AMDGPUDAGToDAGISel::isUniformBr(
const SDNode *N)
const {
659 const BasicBlock *BB = FuncInfo->MBB->getBasicBlock();
665 StringRef AMDGPUDAGToDAGISel::getPassName()
const {
666 return "AMDGPU DAG->DAG Pattern Instruction Selection";
678 bool AMDGPUDAGToDAGISel::SelectADDRIndirect(
SDValue Addr,
SDValue &Base,
683 if ((C = dyn_cast<ConstantSDNode>(Addr))) {
684 Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR,
MVT::i32);
687 (C = dyn_cast<ConstantSDNode>(Addr.
getOperand(0)))) {
688 Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR,
MVT::i32);
691 (C = dyn_cast<ConstantSDNode>(Addr.
getOperand(1)))) {
696 Offset = CurDAG->getTargetConstant(0, DL,
MVT::i32);
703 void AMDGPUDAGToDAGISel::SelectADD_SUB_I64(
SDNode *N) {
717 SDNode *Lo0 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
719 SDNode *Hi0 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
722 SDNode *Lo1 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
724 SDNode *Hi1 = CurDAG->getMachineNode(TargetOpcode::EXTRACT_SUBREG,
729 unsigned Opc = IsAdd ? AMDGPU::S_ADD_U32 : AMDGPU::S_SUB_U32;
730 unsigned CarryOpc = IsAdd ? AMDGPU::S_ADDC_U32 : AMDGPU::S_SUBB_U32;
735 AddLo = CurDAG->getMachineNode(Opc, DL, VTList, Args);
738 AddLo = CurDAG->getMachineNode(CarryOpc, DL, VTList, Args);
745 SDNode *AddHi = CurDAG->getMachineNode(CarryOpc, DL, VTList, AddHiArgs);
748 CurDAG->getTargetConstant(AMDGPU::SReg_64RegClassID, DL,
MVT::i32),
763 ReplaceNode(N, RegSequence);
766 void AMDGPUDAGToDAGISel::SelectUADDO_USUBO(
SDNode *N) {
771 AMDGPU::V_ADD_I32_e64 : AMDGPU::V_SUB_I32_e64;
773 CurDAG->SelectNodeTo(N, Opc, N->
getVTList(),
777 void AMDGPUDAGToDAGISel::SelectFMA_W_CHAIN(
SDNode *N) {
782 SelectVOP3Mods0(N->
getOperand(1), Ops[1], Ops[0], Ops[6], Ops[7]);
783 SelectVOP3Mods(N->
getOperand(2), Ops[3], Ops[2]);
784 SelectVOP3Mods(N->
getOperand(3), Ops[5], Ops[4]);
788 CurDAG->SelectNodeTo(N, AMDGPU::V_FMA_F32, N->
getVTList(), Ops);
791 void AMDGPUDAGToDAGISel::SelectFMUL_W_CHAIN(
SDNode *N) {
796 SelectVOP3Mods0(N->
getOperand(1), Ops[1], Ops[0], Ops[4], Ops[5]);
797 SelectVOP3Mods(N->
getOperand(2), Ops[3], Ops[2]);
801 CurDAG->SelectNodeTo(N, AMDGPU::V_MUL_F32_e64, N->
getVTList(), Ops);
806 void AMDGPUDAGToDAGISel::SelectDIV_SCALE(
SDNode *N) {
813 = (VT ==
MVT::f64) ? AMDGPU::V_DIV_SCALE_F64 : AMDGPU::V_DIV_SCALE_F32;
816 CurDAG->SelectNodeTo(N, Opc, N->
getVTList(), Ops);
821 void AMDGPUDAGToDAGISel::SelectMAD_64_32(
SDNode *N) {
824 unsigned Opc = Signed ? AMDGPU::V_MAD_I64_I32 : AMDGPU::V_MAD_U64_U32;
829 CurDAG->SelectNodeTo(N, Opc, N->
getVTList(), Ops);
832 bool AMDGPUDAGToDAGISel::isDSOffsetLegal(
const SDValue &Base,
unsigned Offset,
833 unsigned OffsetBits)
const {
834 if ((OffsetBits == 16 && !
isUInt<16>(Offset)) ||
839 Subtarget->unsafeDSOffsetFoldingEnabled())
844 return CurDAG->SignBitIsZero(Base);
847 bool AMDGPUDAGToDAGISel::SelectDS1Addr1Offset(
SDValue Addr,
SDValue &Base,
850 if (CurDAG->isBaseWithConstantOffset(Addr)) {
863 int64_t ByteOffset =
C->getSExtValue();
873 if (isDSOffsetLegal(Sub, ByteOffset, 16)) {
875 unsigned SubOp = Subtarget->hasAddNoCarry() ?
876 AMDGPU::V_SUB_U32_e64 : AMDGPU::V_SUB_I32_e32;
879 = CurDAG->getMachineNode(SubOp, DL,
MVT::i32,
883 Offset = CurDAG->getTargetConstant(ByteOffset, DL,
MVT::i16);
888 }
else if (
const ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) {
898 MachineSDNode *MovZero = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32,
901 Offset = CurDAG->getTargetConstant(CAddr->getZExtValue(), DL,
MVT::i16);
908 Offset = CurDAG->getTargetConstant(0,
SDLoc(Addr),
MVT::i16);
913 bool AMDGPUDAGToDAGISel::SelectDS64Bit4ByteAligned(
SDValue Addr,
SDValue &Base,
918 if (CurDAG->isBaseWithConstantOffset(Addr)) {
923 unsigned DWordOffset1 = DWordOffset0 + 1;
925 if (isDSOffsetLegal(N0, DWordOffset1, 8)) {
927 Offset0 = CurDAG->getTargetConstant(DWordOffset0, DL,
MVT::i8);
928 Offset1 = CurDAG->getTargetConstant(DWordOffset1, DL,
MVT::i8);
934 unsigned DWordOffset0 =
C->getZExtValue() / 4;
935 unsigned DWordOffset1 = DWordOffset0 + 1;
947 if (isDSOffsetLegal(Sub, DWordOffset1, 8)) {
948 unsigned SubOp = Subtarget->hasAddNoCarry() ?
949 AMDGPU::V_SUB_U32_e64 : AMDGPU::V_SUB_I32_e32;
952 = CurDAG->getMachineNode(SubOp, DL,
MVT::i32,
956 Offset0 = CurDAG->getTargetConstant(DWordOffset0, DL,
MVT::i8);
957 Offset1 = CurDAG->getTargetConstant(DWordOffset1, DL,
MVT::i8);
962 }
else if (
const ConstantSDNode *CAddr = dyn_cast<ConstantSDNode>(Addr)) {
963 unsigned DWordOffset0 = CAddr->getZExtValue() / 4;
964 unsigned DWordOffset1 = DWordOffset0 + 1;
965 assert(4 * DWordOffset0 == CAddr->getZExtValue());
970 = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32,
973 Offset0 = CurDAG->getTargetConstant(DWordOffset0, DL,
MVT::i8);
974 Offset1 = CurDAG->getTargetConstant(DWordOffset1, DL,
MVT::i8);
982 Offset0 = CurDAG->getTargetConstant(0, DL,
MVT::i8);
983 Offset1 = CurDAG->getTargetConstant(1, DL,
MVT::i8);
994 if (Subtarget->useFlatForGlobal())
1000 GLC = CurDAG->getTargetConstant(0, DL,
MVT::i1);
1002 SLC = CurDAG->getTargetConstant(0, DL,
MVT::i1);
1003 TFE = CurDAG->getTargetConstant(0, DL,
MVT::i1);
1005 Idxen = CurDAG->getTargetConstant(0, DL,
MVT::i1);
1006 Offen = CurDAG->getTargetConstant(0, DL,
MVT::i1);
1007 Addr64 = CurDAG->getTargetConstant(0, DL,
MVT::i1);
1008 SOffset = CurDAG->getTargetConstant(0, DL,
MVT::i32);
1012 if (CurDAG->isBaseWithConstantOffset(Addr)) {
1013 C1 = cast<ConstantSDNode>(Addr.
getOperand(1));
1025 Addr64 = CurDAG->getTargetConstant(1, DL,
MVT::i1);
1043 Offset = CurDAG->getTargetConstant(0, DL,
MVT::i16);
1049 Addr64 = CurDAG->getTargetConstant(1, DL,
MVT::i1);
1053 VAddr = CurDAG->getTargetConstant(0, DL,
MVT::i32);
1059 Offset = CurDAG->getTargetConstant(0, DL,
MVT::i16);
1070 Offset = CurDAG->getTargetConstant(0, DL,
MVT::i16);
1072 SDValue(CurDAG->getMachineNode(
1079 bool AMDGPUDAGToDAGISel::SelectMUBUFAddr64(
SDValue Addr,
SDValue &SRsrc,
1083 SDValue Ptr, Offen, Idxen, Addr64;
1089 if (!SelectMUBUF(Addr, Ptr, VAddr, SOffset, Offset, Offen, Idxen, Addr64,
1107 bool AMDGPUDAGToDAGISel::SelectMUBUFAddr64(
SDValue Addr,
SDValue &SRsrc,
1111 SLC = CurDAG->getTargetConstant(0,
SDLoc(Addr),
MVT::i1);
1114 return SelectMUBUFAddr64(Addr, SRsrc, VAddr, SOffset, Offset, GLC, SLC, TFE);
1122 std::pair<SDValue, SDValue> AMDGPUDAGToDAGISel::foldFrameIndex(
SDValue N)
const {
1126 if (
auto FI = dyn_cast<FrameIndexSDNode>(N)) {
1127 SDValue TFI = CurDAG->getTargetFrameIndex(FI->getIndex(),
1128 FI->getValueType(0));
1142 bool AMDGPUDAGToDAGISel::SelectMUBUFScratchOffen(
SDNode *Parent,
1154 unsigned Imm = CAddr->getZExtValue();
1156 SDValue HighBits = CurDAG->getTargetConstant(Imm & ~4095, DL,
MVT::i32);
1157 MachineSDNode *MovHighBits = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32,
1159 VAddr =
SDValue(MovHighBits, 0);
1167 SOffset = CurDAG->getRegister(SOffsetReg,
MVT::i32);
1168 ImmOffset = CurDAG->getTargetConstant(Imm & 4095, DL,
MVT::i16);
1172 if (CurDAG->isBaseWithConstantOffset(Addr)) {
1195 (!Subtarget->privateMemoryResourceIsRangeChecked() ||
1196 CurDAG->SignBitIsZero(N0))) {
1197 std::tie(VAddr, SOffset) = foldFrameIndex(N0);
1204 std::tie(VAddr, SOffset) = foldFrameIndex(Addr);
1205 ImmOffset = CurDAG->getTargetConstant(0, DL,
MVT::i16);
1209 bool AMDGPUDAGToDAGISel::SelectMUBUFScratchOffset(
SDNode *Parent,
1230 SOffset = CurDAG->getRegister(SOffsetReg,
MVT::i32);
1236 bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(
SDValue Addr,
SDValue &SRsrc,
1240 SDValue Ptr, VAddr, Offen, Idxen, Addr64;
1242 static_cast<const SIInstrInfo *
>(Subtarget->getInstrInfo());
1244 if (!SelectMUBUF(Addr, Ptr, VAddr, SOffset, Offset, Offen, Idxen, Addr64,
1248 if (!cast<ConstantSDNode>(Offen)->getSExtValue() &&
1249 !cast<ConstantSDNode>(Idxen)->getSExtValue() &&
1250 !cast<ConstantSDNode>(Addr64)->getSExtValue()) {
1264 bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(
SDValue Addr,
SDValue &SRsrc,
1269 return SelectMUBUFOffset(Addr, SRsrc, Soffset, Offset, GLC, SLC, TFE);
1271 bool AMDGPUDAGToDAGISel::SelectMUBUFOffset(
SDValue Addr,
SDValue &SRsrc,
1276 return SelectMUBUFOffset(Addr, SRsrc, Soffset, Offset, GLC, SLC, TFE);
1279 template <
bool IsSigned>
1280 bool AMDGPUDAGToDAGISel::SelectFlatOffset(
SDValue Addr,
1284 int64_t OffsetVal = 0;
1286 if (Subtarget->hasFlatInstOffsets() &&
1287 CurDAG->isBaseWithConstantOffset(Addr)) {
1290 int64_t COffsetVal = cast<ConstantSDNode>(N1)->getSExtValue();
1292 if ((IsSigned && isInt<13>(COffsetVal)) ||
1293 (!IsSigned && isUInt<12>(COffsetVal))) {
1295 OffsetVal = COffsetVal;
1300 Offset = CurDAG->getTargetConstant(OffsetVal,
SDLoc(),
MVT::i16);
1306 bool AMDGPUDAGToDAGISel::SelectFlatAtomic(
SDValue Addr,
1310 return SelectFlatOffset<false>(Addr, VAddr,
Offset, SLC);
1313 bool AMDGPUDAGToDAGISel::SelectFlatAtomicSigned(
SDValue Addr,
1317 return SelectFlatOffset<true>(Addr, VAddr,
Offset, SLC);
1320 bool AMDGPUDAGToDAGISel::SelectSMRDOffset(
SDValue ByteOffsetNode,
1321 SDValue &Offset,
bool &Imm)
const {
1328 SDLoc SL(ByteOffsetNode);
1334 Offset = CurDAG->getTargetConstant(EncodedOffset, SL,
MVT::i32);
1344 Offset = CurDAG->getTargetConstant(EncodedOffset, SL,
MVT::i32);
1347 Offset =
SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, SL,
MVT::i32,
1354 SDValue AMDGPUDAGToDAGISel::Expand32BitAddress(
SDValue Addr)
const {
1367 CurDAG->getTargetConstant(AMDGPU::SReg_64_XEXECRegClassID, SL,
MVT::i32),
1369 CurDAG->getTargetConstant(AMDGPU::sub0, SL,
MVT::i32),
1370 SDValue(CurDAG->getMachineNode(AMDGPU::S_MOV_B32, SL,
MVT::i32, AddrHi),
1372 CurDAG->getTargetConstant(AMDGPU::sub1, SL,
MVT::i32),
1375 return SDValue(CurDAG->getMachineNode(AMDGPU::REG_SEQUENCE, SL,
MVT::i64,
1379 bool AMDGPUDAGToDAGISel::SelectSMRD(
SDValue Addr,
SDValue &SBase,
1380 SDValue &Offset,
bool &Imm)
const {
1387 CurDAG->isBaseWithConstantOffset(Addr)) {
1391 if (SelectSMRDOffset(N1, Offset, Imm)) {
1392 SBase = Expand32BitAddress(N0);
1396 SBase = Expand32BitAddress(Addr);
1397 Offset = CurDAG->getTargetConstant(0, SL,
MVT::i32);
1402 bool AMDGPUDAGToDAGISel::SelectSMRDImm(
SDValue Addr,
SDValue &SBase,
1405 return SelectSMRD(Addr, SBase, Offset, Imm) && Imm;
1408 bool AMDGPUDAGToDAGISel::SelectSMRDImm32(
SDValue Addr,
SDValue &SBase,
1415 if (!SelectSMRD(Addr, SBase, Offset, Imm))
1418 return !Imm && isa<ConstantSDNode>(
Offset);
1421 bool AMDGPUDAGToDAGISel::SelectSMRDSgpr(
SDValue Addr,
SDValue &SBase,
1424 return SelectSMRD(Addr, SBase, Offset, Imm) && !Imm &&
1425 !isa<ConstantSDNode>(
Offset);
1428 bool AMDGPUDAGToDAGISel::SelectSMRDBufferImm(
SDValue Addr,
1431 return SelectSMRDOffset(Addr, Offset, Imm) && Imm;
1434 bool AMDGPUDAGToDAGISel::SelectSMRDBufferImm32(
SDValue Addr,
1440 if (!SelectSMRDOffset(Addr, Offset, Imm))
1443 return !Imm && isa<ConstantSDNode>(
Offset);
1446 bool AMDGPUDAGToDAGISel::SelectMOVRELOffset(
SDValue Index,
1451 if (CurDAG->isBaseWithConstantOffset(Index)) {
1459 if (C1->
getSExtValue() <= 0 || CurDAG->SignBitIsZero(N0)) {
1466 if (isa<ConstantSDNode>(Index))
1470 Offset = CurDAG->getTargetConstant(0, DL,
MVT::i32);
1474 SDNode *AMDGPUDAGToDAGISel::getS_BFE(
unsigned Opcode,
const SDLoc &DL,
1480 uint32_t PackedVal = Offset | (Width << 16);
1481 SDValue PackedConst = CurDAG->getTargetConstant(PackedVal, DL,
MVT::i32);
1483 return CurDAG->getMachineNode(Opcode, DL,
MVT::i32, Val, PackedConst);
1486 void AMDGPUDAGToDAGISel::SelectS_BFEFromShifts(
SDNode *N) {
1499 if (0 < BVal && BVal <= CVal && CVal < 32) {
1501 unsigned Opcode = Signed ? AMDGPU::S_BFE_I32 : AMDGPU::S_BFE_U32;
1503 ReplaceNode(N, getS_BFE(Opcode,
SDLoc(N), Shl.
getOperand(0), CVal - BVal,
1511 void AMDGPUDAGToDAGISel::SelectS_BFE(
SDNode *N) {
1521 if (Shift && Mask) {
1523 uint32_t MaskVal = Mask->getZExtValue();
1528 ReplaceNode(N, getS_BFE(AMDGPU::S_BFE_U32,
SDLoc(N),
1543 if (Shift && Mask) {
1545 uint32_t MaskVal = Mask->getZExtValue() >> ShiftVal;
1550 ReplaceNode(N, getS_BFE(AMDGPU::S_BFE_U32,
SDLoc(N),
1556 SelectS_BFEFromShifts(N);
1562 SelectS_BFEFromShifts(N);
1577 unsigned Width = cast<VTSDNode>(N->
getOperand(1))->getVT().getSizeInBits();
1578 ReplaceNode(N, getS_BFE(AMDGPU::S_BFE_I32,
SDLoc(N), Src.
getOperand(0),
1587 bool AMDGPUDAGToDAGISel::isCBranchSCC(
const SDNode *N)
const {
1604 auto ST =
static_cast<const GCNSubtarget *
>(Subtarget);
1613 void AMDGPUDAGToDAGISel::SelectBRCOND(
SDNode *N) {
1617 CurDAG->SelectNodeTo(N, AMDGPU::SI_BR_UNDEF,
MVT::Other,
1622 bool UseSCCBr = isCBranchSCC(N) && isUniformBr(N);
1623 unsigned BrOp = UseSCCBr ? AMDGPU::S_CBRANCH_SCC1 : AMDGPU::S_CBRANCH_VCCNZ;
1624 unsigned CondReg = UseSCCBr ? AMDGPU::SCC : AMDGPU::VCC;
1641 Cond =
SDValue(CurDAG->getMachineNode(AMDGPU::S_AND_B64, SL,
MVT::i1,
1642 CurDAG->getRegister(AMDGPU::EXEC,
MVT::i1),
1653 void AMDGPUDAGToDAGISel::SelectFMAD_FMA(
SDNode *N) {
1656 if (VT !=
MVT::f32 || (!Subtarget->hasMadMixInsts() &&
1657 !Subtarget->hasFmaMixInsts()) ||
1658 ((IsFMA && Subtarget->hasMadMixInsts()) ||
1659 (!IsFMA && Subtarget->hasFmaMixInsts()))) {
1667 unsigned Src0Mods, Src1Mods, Src2Mods;
1671 bool Sel0 = SelectVOP3PMadMixModsImpl(Src0, Src0, Src0Mods);
1672 bool Sel1 = SelectVOP3PMadMixModsImpl(Src1, Src1, Src1Mods);
1673 bool Sel2 = SelectVOP3PMadMixModsImpl(Src2, Src2, Src2Mods);
1675 assert((IsFMA || !Subtarget->hasFP32Denormals()) &&
1676 "fmad selected with denormals enabled");
1680 if (Sel0 || Sel1 || Sel2) {
1684 CurDAG->getTargetConstant(Src0Mods,
SDLoc(),
MVT::i32), Src0,
1685 CurDAG->getTargetConstant(Src1Mods,
SDLoc(),
MVT::i32), Src1,
1686 CurDAG->getTargetConstant(Src2Mods,
SDLoc(),
MVT::i32), Src2,
1691 CurDAG->SelectNodeTo(N,
1692 IsFMA ? AMDGPU::V_FMA_MIX_F32 : AMDGPU::V_MAD_MIX_F32,
1701 void AMDGPUDAGToDAGISel::SelectATOMIC_CMP_SWAP(
SDNode *N) {
1714 if (Subtarget->hasAddr64()) {
1717 if (SelectMUBUFAddr64(Mem->
getBasePtr(), SRsrc, VAddr, SOffset,
Offset, SLC)) {
1718 unsigned Opcode = Is32 ? AMDGPU::BUFFER_ATOMIC_CMPSWAP_ADDR64_RTN :
1719 AMDGPU::BUFFER_ATOMIC_CMPSWAP_X2_ADDR64_RTN;
1728 CmpSwap = CurDAG->getMachineNode(Opcode, SL, Mem->
getVTList(), Ops);
1735 unsigned Opcode = Is32 ? AMDGPU::BUFFER_ATOMIC_CMPSWAP_OFFSET_RTN :
1736 AMDGPU::BUFFER_ATOMIC_CMPSWAP_X2_OFFSET_RTN;
1743 CmpSwap = CurDAG->getMachineNode(Opcode, SL, Mem->
getVTList(), Ops);
1753 CurDAG->setNodeMemRefs(CmpSwap, {MMO});
1755 unsigned SubReg = Is32 ? AMDGPU::sub0 : AMDGPU::sub0_sub1;
1757 = CurDAG->getTargetExtractSubreg(SubReg, SL, VT,
SDValue(CmpSwap, 0));
1759 ReplaceUses(
SDValue(N, 0), Extract);
1761 CurDAG->RemoveDeadNode(N);
1765 unsigned &Mods)
const {
1782 bool AMDGPUDAGToDAGISel::SelectVOP3Mods(
SDValue In,
SDValue &Src,
1785 if (SelectVOP3ModsImpl(In, Src, Mods)) {
1786 SrcMods = CurDAG->getTargetConstant(Mods,
SDLoc(In),
MVT::i32);
1793 bool AMDGPUDAGToDAGISel::SelectVOP3Mods_NNaN(
SDValue In,
SDValue &Src,
1795 SelectVOP3Mods(In, Src, SrcMods);
1796 return isNoNanSrc(Src);
1799 bool AMDGPUDAGToDAGISel::SelectVOP3NoMods(
SDValue In,
SDValue &Src)
const {
1807 bool AMDGPUDAGToDAGISel::SelectVOP3Mods0(
SDValue In,
SDValue &Src,
1811 Clamp = CurDAG->getTargetConstant(0, DL,
MVT::i1);
1812 Omod = CurDAG->getTargetConstant(0, DL,
MVT::i1);
1814 return SelectVOP3Mods(In, Src, SrcMods);
1817 bool AMDGPUDAGToDAGISel::SelectVOP3Mods0Clamp0OMod(
SDValue In,
SDValue &Src,
1821 Clamp = Omod = CurDAG->getTargetConstant(0,
SDLoc(In),
MVT::i32);
1822 return SelectVOP3Mods(In, Src, SrcMods);
1825 bool AMDGPUDAGToDAGISel::SelectVOP3OMods(
SDValue In,
SDValue &Src,
1830 Clamp = CurDAG->getTargetConstant(0, DL,
MVT::i1);
1831 Omod = CurDAG->getTargetConstant(0, DL,
MVT::i1);
1849 if (ShiftAmt->getZExtValue() == 16) {
1871 bool AMDGPUDAGToDAGISel::SelectVOP3PMods(
SDValue In,
SDValue &Src,
1882 unsigned VecMods = Mods;
1906 if (Lo == Hi && !isInlineImmediate(Lo.
getNode())) {
1911 SrcMods = CurDAG->getTargetConstant(Mods,
SDLoc(In),
MVT::i32);
1921 SrcMods = CurDAG->getTargetConstant(Mods,
SDLoc(In),
MVT::i32);
1925 bool AMDGPUDAGToDAGISel::SelectVOP3PMods0(
SDValue In,
SDValue &Src,
1931 Clamp = CurDAG->getTargetConstant(0, SL,
MVT::i32);
1933 return SelectVOP3PMods(In, Src, SrcMods);
1936 bool AMDGPUDAGToDAGISel::SelectVOP3OpSel(
SDValue In,
SDValue &Src,
1940 SrcMods = CurDAG->getTargetConstant(0,
SDLoc(In),
MVT::i32);
1944 bool AMDGPUDAGToDAGISel::SelectVOP3OpSel0(
SDValue In,
SDValue &Src,
1950 Clamp = CurDAG->getTargetConstant(0, SL,
MVT::i32);
1952 return SelectVOP3OpSel(In, Src, SrcMods);
1955 bool AMDGPUDAGToDAGISel::SelectVOP3OpSelMods(
SDValue In,
SDValue &Src,
1958 return SelectVOP3Mods(In, Src, SrcMods);
1961 bool AMDGPUDAGToDAGISel::SelectVOP3OpSelMods0(
SDValue In,
SDValue &Src,
1967 Clamp = CurDAG->getTargetConstant(0, SL,
MVT::i32);
1969 return SelectVOP3OpSelMods(In, Src, SrcMods);
1974 bool AMDGPUDAGToDAGISel::SelectVOP3PMadMixModsImpl(
SDValue In,
SDValue &Src,
1975 unsigned &Mods)
const {
1977 SelectVOP3ModsImpl(In, Src, Mods);
1988 SelectVOP3ModsImpl(Src, Src, ModsTmp);
1993 if ((ModsTmp & SISrcMods::ABS) != 0)
2015 bool AMDGPUDAGToDAGISel::SelectVOP3PMadMixMods(
SDValue In,
SDValue &Src,
2018 SelectVOP3PMadMixModsImpl(In, Src, Mods);
2019 SrcMods = CurDAG->getTargetConstant(Mods,
SDLoc(In),
MVT::i32);
2024 bool AMDGPUDAGToDAGISel::SelectHi16Elt(
SDValue In,
SDValue &Src)
const {
2032 SDValue K = CurDAG->getTargetConstant(
C->getZExtValue() << 16, SL,
MVT::i32);
2033 MachineSDNode *MovK = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32,
2041 SDValue K = CurDAG->getTargetConstant(
2042 C->getValueAPF().bitcastToAPInt().getZExtValue() << 16, SL,
MVT::i32);
2043 MachineSDNode *MovK = CurDAG->getMachineNode(AMDGPU::V_MOV_B32_e32,
2052 bool AMDGPUDAGToDAGISel::isVGPRImm(
const SDNode * N)
const {
2057 static_cast<const SIRegisterInfo *
>(Subtarget->getRegisterInfo());
2059 static_cast<const SIInstrInfo *
>(Subtarget->getInstrInfo());
2062 bool AllUsesAcceptSReg =
true;
2064 Limit < 10 && U !=
E; ++U, ++Limit) {
2073 if (RC != &AMDGPU::VS_32RegClass) {
2074 AllUsesAcceptSReg =
false;
2080 unsigned OpIdx = Desc.
getNumDefs() + U.getOperandNo();
2083 unsigned CommutedOpNo = CommuteIdx1 - Desc.
getNumDefs();
2085 if (CommutedRC == &AMDGPU::VS_32RegClass)
2086 AllUsesAcceptSReg =
true;
2094 if (!AllUsesAcceptSReg)
2098 return !AllUsesAcceptSReg && (Limit < 10);
2101 bool AMDGPUDAGToDAGISel::isUniformLoad(
const SDNode * N)
const {
2102 auto Ld = cast<LoadSDNode>(
N);
2104 return Ld->getAlignment() >= 4 &&
2116 Subtarget->getScalarizeGlobalBehavior() &&
2118 !Ld->isVolatile() &&
2121 getTargetLowering())->isMemOpHasNoClobberedMemOperand(N)
2126 void AMDGPUDAGToDAGISel::PostprocessISelDAG() {
2129 bool IsModified =
false;
2135 while (Position != CurDAG->allnodes_end()) {
2136 SDNode *Node = &*Position++;
2142 if (ResNode != Node) {
2144 ReplaceUses(Node, ResNode);
2148 CurDAG->RemoveDeadNodes();
2149 }
while (IsModified);
2157 bool R600DAGToDAGISel::isConstantLoad(
const MemSDNode *N,
int CbId)
const {
2167 bool R600DAGToDAGISel::SelectGlobalValueConstantOffset(
SDValue Addr,
2170 IntPtr = CurDAG->getIntPtrConstant(Cst->getZExtValue() / 4,
SDLoc(Addr),
2177 bool R600DAGToDAGISel::SelectGlobalValueVariableOffset(
SDValue Addr,
2179 if (!isa<ConstantSDNode>(Addr)) {
2181 Offset = CurDAG->getIntPtrConstant(0,
SDLoc(Addr),
true);
2201 unsigned RegClassID;
2206 switch(NumVectorElts) {
2207 case 2: RegClassID = R600::R600_Reg64RegClassID;
break;
2210 RegClassID = R600::R600_Reg128VerticalRegClassID;
2212 RegClassID = R600::R600_Reg128RegClassID;
2216 SelectBuildVector(N, RegClassID);
2224 bool R600DAGToDAGISel::SelectADDRIndirect(
SDValue Addr,
SDValue &Base,
2229 if ((C = dyn_cast<ConstantSDNode>(Addr))) {
2230 Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR,
MVT::i32);
2233 (C = dyn_cast<ConstantSDNode>(Addr.
getOperand(0)))) {
2234 Base = CurDAG->getRegister(R600::INDIRECT_BASE_ADDR,
MVT::i32);
2237 (C = dyn_cast<ConstantSDNode>(Addr.
getOperand(1)))) {
2242 Offset = CurDAG->getTargetConstant(0, DL,
MVT::i32);
2248 bool R600DAGToDAGISel::SelectADDRVTX_READ(
SDValue Addr,
SDValue &Base,
2254 &&
isInt<16>(IMMOffset->getZExtValue())) {
2257 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(),
SDLoc(Addr),
2261 }
else if ((IMMOffset = dyn_cast<ConstantSDNode>(Addr))
2262 &&
isInt<16>(IMMOffset->getZExtValue())) {
2263 Base = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
2264 SDLoc(CurDAG->getEntryNode()),
2266 Offset = CurDAG->getTargetConstant(IMMOffset->getZExtValue(),
SDLoc(Addr),
2273 Offset = CurDAG->getTargetConstant(0,
SDLoc(Addr),
MVT::i32);
unsigned getFrameOffsetReg() const
unsigned getScratchWaveOffsetReg() const
BITCAST - This operator converts between integer, vector and FP values, as if the value was stored to...
constexpr bool isUInt< 32 >(uint64_t x)
static bool isExtractHiElt(SDValue In, SDValue &Out)
EVT getValueType() const
Return the ValueType of the referenced return value.
Interface definition for SIRegisterInfo.
static unsigned getSubRegFromChannel(unsigned Channel)
uint64_t getZExtValue() const
Get zero extended value.
INITIALIZE_PASS_BEGIN(AMDGPUDAGToDAGISel, "amdgpu-isel", "AMDGPU DAG->DAG Pattern Instruction Selection", false, false) INITIALIZE_PASS_END(AMDGPUDAGToDAGISel
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
unsigned getOpcode() const
Return the SelectionDAG opcode value for this node.
AMDGPU specific subclass of TargetSubtarget.
const TargetRegisterClass * getRegClass(unsigned Reg) const
Return the register class of the specified virtual register.
This class represents lattice values for constants.
uint64_t getDefaultRsrcDataFormat() const
FunctionPass * createR600ISelDag(TargetMachine *TM, CodeGenOpt::Level OptLevel)
This pass converts a legalized DAG into a R600-specific.
unsigned getStackPtrOffsetReg() const
bool isCommutable() const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z, ..."), which produces the same result if Y and Z are exchanged.
SDValue copyToM0(SelectionDAG &DAG, SDValue Chain, const SDLoc &DL, SDValue V) const
Carry-setting nodes for multiple precision addition and subtraction.
EVT getValueType(unsigned ResNo) const
Return the type of a specified result.
void push_back(const T &Elt)
Describe properties that are true of each instruction in the target description file.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
SDVTList getVTList() const
Address space for 32-bit constant memory.
const SDValue & getChain() const
virtual SDNode * PostISelFolding(MachineSDNode *N, SelectionDAG &DAG) const =0
static bool getConstantValue(SDValue N, uint32_t &Out)
SDNode * legalizeTargetIndependentNode(SDNode *Node, SelectionDAG &DAG) const
Legalize target independent instructions (e.g.
constexpr bool isInt< 16 >(int64_t x)
unsigned const TargetRegisterInfo * TRI
MVT getSimpleValueType(unsigned ResNo) const
Return the type of a specified result as a simple type.
const SDNodeFlags getFlags() const
void setNodeId(int Id)
Set unique node id.
SDNode * getNode() const
get the SDNode which holds the desired result
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
MachineMemOperand * getMemOperand() const
Return a MachineMemOperand object describing the memory reference performed by operation.
bool isInlineConstant(const APInt &Imm) const
constexpr bool isMask_32(uint32_t Value)
Return true if the argument is a non-empty sequence of ones starting at the least significant bit wit...
bool hasOneUse() const
Return true if there is exactly one node using value ResNo of Node.
unsigned getAddressSpace() const
Return the address space for the associated pointer.
MachineSDNode * wrapAddr64Rsrc(SelectionDAG &DAG, const SDLoc &DL, SDValue Ptr) const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool hasOneUse() const
Return true if there is exactly one use of this node.
A description of a memory reference used in the backend.
Address space for constant memory (VTX2)
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
const HexagonInstrInfo * TII
Shift and rotation operations.
unsigned get32BitAddressHighBits() const
static bool EnableLateStructurizeCFG
BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways.
CopyToReg - This node has three operands: a chain, a register number to set to this value...
Position
Position to insert a new instruction relative to an existing instruction.
bool isSGPRClass(const TargetRegisterClass *RC) const
This file implements a class to represent arbitrary precision integral constant values and operations...
This represents a list of ValueType's that has been intern'd by a SelectionDAG.
TargetRegisterInfo interface that is implemented by all hw codegen targets.
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
int64_t getSExtValue() const
unsigned getScalarSizeInBits() const
unsigned getSizeInBits() const
Return the size of the specified value type in bits.
Simple integer binary arithmetic operators.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
CondCode
ISD::CondCode enum - These are ordered carefully to make the bitfields below work out...
Analysis containing CSE Info
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...
MVT getSimpleValueType() const
Return the simple ValueType of the referenced return value.
static const unsigned CommuteAnyOperandIndex
FunctionPass * createAMDGPUISelDag(TargetMachine *TM=nullptr, CodeGenOpt::Level OptLevel=CodeGenOpt::Default)
This pass converts a legalized DAG into a AMDGPU-specific.
int64_t getSMRDEncodedOffset(const MCSubtargetInfo &ST, int64_t ByteOffset)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
constexpr bool isUInt< 8 >(uint64_t x)
unsigned const MachineRegisterInfo * MRI
use_iterator use_begin() const
Provide iteration support to walk over all uses of an SDNode.
LLVM Basic Block Representation.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
unsigned getVectorNumElements() const
Given a vector type, return the number of elements it contains.
Address space for flat memory.
PointerUnion< const Value *, const PseudoSourceValue * > V
This is the IR pointer value for the access, or it is null if unknown.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const SDValue & getOperand(unsigned Num) const
Carry-using nodes for multiple precision addition and subtraction.
SI DAG Lowering interface definition.
Represent the analysis usage information of a pass.
This class provides iterator support for SDUse operands that use a specific SDNode.
Address space for local memory.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
FunctionPass class - This class is used to implement most global optimizations.
const R600RegisterInfo & getRegisterInfo() const
bool isDefined() const
Returns true if the flags are in a defined state.
The AMDGPU TargetMachine interface definition for hw codgen targets.
X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
bool isLegalSMRDImmOffset(const MCSubtargetInfo &ST, int64_t ByteOffset)
T dyn_cast() const
Returns the current pointer if it is of the specified pointer type, otherwises returns null...
Address space for global memory (RAT0, VTX0).
This class contains a discriminated union of information about pointers in memory operands...
bool isMachineOpcode() const
Test if this node has a post-isel opcode, directly corresponding to a MachineInstr opcode...
unsigned getNumOperands() const
Return the number of values used by this operation.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static unsigned selectSGPRVectorRegClassID(unsigned NumVectorElts)
MachineSDNode * buildRSRC(SelectionDAG &DAG, const 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 multiplied by the ...
Iterator for intrusive lists based on ilist_node.
unsigned countPopulation(T Value)
Count the number of set bits in a value.
EVT getVectorElementType() const
Given a vector type, return the type of each element.
Interface definition of the TargetLowering class that is common to all AMD GPUs.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
unsigned getScratchRSrcReg() const
Returns the physical register reserved for use as the resource descriptor for scratch accesses...
BRCOND - Conditional branch.
An SDNode that represents everything that will be needed to construct a MachineInstr.
This is an abstract virtual class for memory operations.
Wrapper class for IR location info (IR ordering and DebugLoc) to be passed into SDNode creation funct...
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
Represents one node in the SelectionDAG.
SelectionDAGISel - This is the common base class used for SelectionDAG-based pattern-matching instruc...
Special value supplied for machine level alias analysis.
static unsigned getReg(const void *D, unsigned RC, unsigned RegNo)
static bool isStackPtrRelative(const MachinePointerInfo &PtrInfo)
amdgpu AMDGPU DAG DAG Pattern Instruction Selection
static SDValue stripExtractLoElt(SDValue In)
static use_iterator use_end()
Contains the definition of a TargetInstrInfo class that is common to all AMD GPUs.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Provides AMDGPU specific target descriptions.
This class keeps track of the SPI_SP_INPUT_ADDR config register, which tells the hardware which inter...
Interface definition for SIInstrInfo.
Bitwise operators - logical and, logical or, logical xor.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to sign extend a small value in ...
LOAD and STORE have token chains as their first operand, then the same operands as an LLVM load/store...
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
unsigned getOpcode() const
SDValue getValue(unsigned R) const
constexpr bool isUInt< 16 >(uint64_t x)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static bool isLegalMUBUFImmOffset(unsigned Imm)
FMA - Perform a * b + c with no intermediate rounding step.
unsigned getMachineOpcode() const
This may only be called if isMachineOpcode returns true.
const TargetRegisterClass * getPhysRegClass(unsigned Reg) const
Return the 'base' register class for this register.
bool hasNoUnsignedWrap() const
const MCOperandInfo * OpInfo
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Primary interface to the complete machine description for the target machine.
static SDValue stripBitcast(SDValue Val)
StringRef - Represent a constant reference to a string, i.e.
FMAD - Perform a * b + c, while getting the same result as the separately rounded operations...
SetCC operator - This evaluates to a true value iff the condition is true.
bool bitsEq(EVT VT) const
Return true if this has the same number of bits as VT.
const SDValue & getOperand(unsigned i) const
OUTCHAIN = ATOMIC_STORE(INCHAIN, ptr, val) This corresponds to "store atomic" instruction.
uint64_t getZExtValue() const
TRUNCATE - Completely drop the high bits.
Unlike LLVM values, Selection DAG nodes may return multiple values as the result of a computation...
Perform various unary floating-point operations inspired by libm.
Analyzes if a function potentially memory bound and if a kernel kernel may benefit from limiting numb...
Val, OUTCHAIN = ATOMIC_LOAD(INCHAIN, ptr) This corresponds to "load atomic" instruction.
const SDValue & getBasePtr() const
SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a scalar value into element 0 of the...
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
bool findCommutedOpIndices(MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const override