aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp84
1 files changed, 63 insertions, 21 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
index 8e90754103ff..620eac428c08 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp
@@ -447,6 +447,35 @@ void AMDGPUDAGToDAGISel::SelectBuildVector(SDNode *N, unsigned RegClassID) {
return;
}
+ bool IsGCN = CurDAG->getSubtarget().getTargetTriple().isAMDGCN();
+ if (IsGCN && Subtarget->has64BitLiterals() && VT.getSizeInBits() == 64 &&
+ CurDAG->isConstantValueOfAnyType(SDValue(N, 0))) {
+ uint64_t C = 0;
+ bool AllConst = true;
+ unsigned EltSize = EltVT.getSizeInBits();
+ for (unsigned I = 0; I < NumVectorElts; ++I) {
+ SDValue Op = N->getOperand(I);
+ if (Op.isUndef()) {
+ AllConst = false;
+ break;
+ }
+ uint64_t Val;
+ if (ConstantFPSDNode *CF = dyn_cast<ConstantFPSDNode>(Op)) {
+ Val = CF->getValueAPF().bitcastToAPInt().getZExtValue();
+ } else
+ Val = cast<ConstantSDNode>(Op)->getZExtValue();
+ C |= Val << (EltSize * I);
+ }
+ if (AllConst) {
+ SDValue CV = CurDAG->getTargetConstant(C, DL, MVT::i64);
+ MachineSDNode *Copy =
+ CurDAG->getMachineNode(AMDGPU::S_MOV_B64_IMM_PSEUDO, DL, VT, CV);
+ CurDAG->SelectNodeTo(N, AMDGPU::COPY_TO_REGCLASS, VT, SDValue(Copy, 0),
+ RegClass);
+ return;
+ }
+ }
+
assert(NumVectorElts <= 32 && "Vectors with more than 32 elements not "
"supported yet");
// 32 = Max Num Vector Elements
@@ -454,8 +483,6 @@ void AMDGPUDAGToDAGISel::SelectBuildVector(SDNode *N, unsigned RegClassID) {
// 1 = Vector Register Class
SmallVector<SDValue, 32 * 2 + 1> RegSeqArgs(NumVectorElts * 2 + 1);
- bool IsGCN = CurDAG->getSubtarget().getTargetTriple().getArch() ==
- Triple::amdgcn;
RegSeqArgs[0] = CurDAG->getTargetConstant(RegClassID, DL, MVT::i32);
bool IsRegSeq = true;
unsigned NOps = N->getNumOperands();
@@ -677,7 +704,8 @@ void AMDGPUDAGToDAGISel::Select(SDNode *N) {
case ISD::Constant:
case ISD::ConstantFP: {
- if (N->getValueType(0).getSizeInBits() != 64 || isInlineImmediate(N))
+ if (N->getValueType(0).getSizeInBits() != 64 || isInlineImmediate(N) ||
+ Subtarget->has64BitLiterals())
break;
uint64_t Imm;
@@ -998,7 +1026,6 @@ void AMDGPUDAGToDAGISel::SelectADD_SUB_I64(SDNode *N) {
}
void AMDGPUDAGToDAGISel::SelectAddcSubb(SDNode *N) {
- SDLoc DL(N);
SDValue LHS = N->getOperand(0);
SDValue RHS = N->getOperand(1);
SDValue CI = N->getOperand(2);
@@ -1051,7 +1078,6 @@ void AMDGPUDAGToDAGISel::SelectUADDO_USUBO(SDNode *N) {
}
void AMDGPUDAGToDAGISel::SelectFMA_W_CHAIN(SDNode *N) {
- SDLoc SL(N);
// src0_modifiers, src0, src1_modifiers, src1, src2_modifiers, src2, clamp, omod
SDValue Ops[10];
@@ -1072,7 +1098,6 @@ void AMDGPUDAGToDAGISel::SelectFMA_W_CHAIN(SDNode *N) {
}
void AMDGPUDAGToDAGISel::SelectFMUL_W_CHAIN(SDNode *N) {
- SDLoc SL(N);
// src0_modifiers, src0, src1_modifiers, src1, clamp, omod
SDValue Ops[8];
@@ -1087,7 +1112,6 @@ void AMDGPUDAGToDAGISel::SelectFMUL_W_CHAIN(SDNode *N) {
// We need to handle this here because tablegen doesn't support matching
// instructions with multiple outputs.
void AMDGPUDAGToDAGISel::SelectDIV_SCALE(SDNode *N) {
- SDLoc SL(N);
EVT VT = N->getValueType(0);
assert(VT == MVT::f32 || VT == MVT::f64);
@@ -1637,8 +1661,7 @@ bool AMDGPUDAGToDAGISel::SelectMUBUFScratchOffset(SDNode *Parent,
SDValue &SRsrc,
SDValue &SOffset,
SDValue &Offset) const {
- const SIRegisterInfo *TRI =
- static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo());
+ const SIRegisterInfo *TRI = Subtarget->getRegisterInfo();
const SIInstrInfo *TII = Subtarget->getInstrInfo();
MachineFunction &MF = CurDAG->getMachineFunction();
const SIMachineFunctionInfo *Info = MF.getInfo<SIMachineFunctionInfo>();
@@ -2037,7 +2060,8 @@ bool AMDGPUDAGToDAGISel::SelectScratchSVAddr(SDNode *N, SDValue Addr,
int64_t COffsetVal = cast<ConstantSDNode>(RHS)->getSExtValue();
const SIInstrInfo *TII = Subtarget->getInstrInfo();
- if (TII->isLegalFLATOffset(COffsetVal, AMDGPUAS::PRIVATE_ADDRESS, true)) {
+ if (TII->isLegalFLATOffset(COffsetVal, AMDGPUAS::PRIVATE_ADDRESS,
+ SIInstrFlags::FlatScratch)) {
Addr = LHS;
ImmOffset = COffsetVal;
} else if (!LHS->isDivergent() && COffsetVal > 0) {
@@ -2045,8 +2069,8 @@ bool AMDGPUDAGToDAGISel::SelectScratchSVAddr(SDNode *N, SDValue Addr,
// saddr + large_offset -> saddr + (vaddr = large_offset & ~MaxOffset) +
// (large_offset & MaxOffset);
int64_t SplitImmOffset, RemainderOffset;
- std::tie(SplitImmOffset, RemainderOffset)
- = TII->splitFlatOffset(COffsetVal, AMDGPUAS::PRIVATE_ADDRESS, true);
+ std::tie(SplitImmOffset, RemainderOffset) = TII->splitFlatOffset(
+ COffsetVal, AMDGPUAS::PRIVATE_ADDRESS, SIInstrFlags::FlatScratch);
if (isUInt<32>(RemainderOffset)) {
SDNode *VMov = CurDAG->getMachineNode(
@@ -2665,8 +2689,20 @@ void AMDGPUDAGToDAGISel::SelectDSAppendConsume(SDNode *N, unsigned IntrID) {
// We need to handle this here because tablegen doesn't support matching
// instructions with multiple outputs.
-void AMDGPUDAGToDAGISel::SelectDSBvhStackIntrinsic(SDNode *N) {
- unsigned Opc = AMDGPU::DS_BVH_STACK_RTN_B32;
+void AMDGPUDAGToDAGISel::SelectDSBvhStackIntrinsic(SDNode *N, unsigned IntrID) {
+ unsigned Opc;
+ switch (IntrID) {
+ case Intrinsic::amdgcn_ds_bvh_stack_rtn:
+ case Intrinsic::amdgcn_ds_bvh_stack_push4_pop1_rtn:
+ Opc = AMDGPU::DS_BVH_STACK_RTN_B32;
+ break;
+ case Intrinsic::amdgcn_ds_bvh_stack_push8_pop1_rtn:
+ Opc = AMDGPU::DS_BVH_STACK_PUSH8_POP1_RTN_B32;
+ break;
+ case Intrinsic::amdgcn_ds_bvh_stack_push8_pop2_rtn:
+ Opc = AMDGPU::DS_BVH_STACK_PUSH8_POP2_RTN_B64;
+ break;
+ }
SDValue Ops[] = {N->getOperand(2), N->getOperand(3), N->getOperand(4),
N->getOperand(5), N->getOperand(0)};
@@ -2830,7 +2866,10 @@ void AMDGPUDAGToDAGISel::SelectINTRINSIC_W_CHAIN(SDNode *N) {
return;
}
case Intrinsic::amdgcn_ds_bvh_stack_rtn:
- SelectDSBvhStackIntrinsic(N);
+ case Intrinsic::amdgcn_ds_bvh_stack_push4_pop1_rtn:
+ case Intrinsic::amdgcn_ds_bvh_stack_push8_pop1_rtn:
+ case Intrinsic::amdgcn_ds_bvh_stack_push8_pop2_rtn:
+ SelectDSBvhStackIntrinsic(N, IntrID);
return;
case Intrinsic::amdgcn_init_whole_wave:
CurDAG->getMachineFunction()
@@ -3651,6 +3690,11 @@ bool AMDGPUDAGToDAGISel::SelectVOP3PMadMixModsImpl(SDValue In, SDValue &Src,
// TODO: Should we try to look for neg/abs here?
}
+ // Prevent unnecessary subreg COPY to VGPR_16
+ if (Src.getOpcode() == ISD::TRUNCATE &&
+ Src.getOperand(0).getValueType() == MVT::i32) {
+ Src = Src.getOperand(0);
+ }
return true;
}
@@ -3867,12 +3911,10 @@ SDValue AMDGPUDAGToDAGISel::getHi16Elt(SDValue In) const {
}
bool AMDGPUDAGToDAGISel::isVGPRImm(const SDNode * N) const {
- assert(CurDAG->getTarget().getTargetTriple().getArch() == Triple::amdgcn);
+ assert(CurDAG->getTarget().getTargetTriple().isAMDGCN());
- const SIRegisterInfo *SIRI =
- static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo());
- const SIInstrInfo * SII =
- static_cast<const SIInstrInfo *>(Subtarget->getInstrInfo());
+ const SIRegisterInfo *SIRI = Subtarget->getRegisterInfo();
+ const SIInstrInfo *SII = Subtarget->getInstrInfo();
unsigned Limit = 0;
bool AllUsesAcceptSReg = true;
@@ -3921,7 +3963,7 @@ bool AMDGPUDAGToDAGISel::isUniformLoad(const SDNode *N) const {
const auto *Ld = cast<LoadSDNode>(N);
const MachineMemOperand *MMO = Ld->getMemOperand();
- if (N->isDivergent() && !AMDGPUInstrInfo::isUniformMMO(MMO))
+ if (N->isDivergent() && !AMDGPU::isUniformMMO(MMO))
return false;
return MMO->getSize().hasValue() &&