diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUISelDAGToDAG.cpp | 84 |
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() && |
