diff options
Diffstat (limited to 'llvm/lib/Target/AMDGPU/SIISelLowering.cpp')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/SIISelLowering.cpp | 116 |
1 files changed, 103 insertions, 13 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp index 6957510c054..d8ed325d098 100644 --- a/llvm/lib/Target/AMDGPU/SIISelLowering.cpp +++ b/llvm/lib/Target/AMDGPU/SIISelLowering.cpp @@ -78,8 +78,10 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM, addRegisterClass(MVT::v16i32, &AMDGPU::SReg_512RegClass); addRegisterClass(MVT::v16f32, &AMDGPU::VReg_512RegClass); - if (Subtarget->has16BitInsts()) + if (Subtarget->has16BitInsts()) { addRegisterClass(MVT::i16, &AMDGPU::SReg_32RegClass); + addRegisterClass(MVT::f16, &AMDGPU::SReg_32RegClass); + } computeRegisterProperties(STI.getRegisterInfo()); @@ -263,20 +265,38 @@ SITargetLowering::SITargetLowering(const TargetMachine &TM, setTruncStoreAction(MVT::i64, MVT::i16, Expand); - setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote); - AddPromotedToType(ISD::UINT_TO_FP, MVT::i16, MVT::i32); - setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); - AddPromotedToType(ISD::SINT_TO_FP, MVT::i16, MVT::i32); setOperationAction(ISD::FP16_TO_FP, MVT::i16, Promote); AddPromotedToType(ISD::FP16_TO_FP, MVT::i16, MVT::i32); setOperationAction(ISD::FP_TO_FP16, MVT::i16, Promote); AddPromotedToType(ISD::FP_TO_FP16, MVT::i16, MVT::i32); - setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote); - AddPromotedToType(ISD::FP_TO_SINT, MVT::i16, MVT::i32); + setOperationAction(ISD::FP_TO_SINT, MVT::i16, Custom); + setOperationAction(ISD::FP_TO_UINT, MVT::i16, Custom); + setOperationAction(ISD::SINT_TO_FP, MVT::i16, Custom); + setOperationAction(ISD::UINT_TO_FP, MVT::i16, Custom); + + // F16 - Constant Actions. + setOperationAction(ISD::ConstantFP, MVT::f16, Custom); + + // F16 - Load/Store Actions. + setOperationAction(ISD::LOAD, MVT::f16, Promote); + AddPromotedToType(ISD::LOAD, MVT::f16, MVT::i16); + setOperationAction(ISD::STORE, MVT::f16, Promote); + AddPromotedToType(ISD::STORE, MVT::f16, MVT::i16); - setOperationAction(ISD::FP_TO_UINT, MVT::i16, Promote); - AddPromotedToType(ISD::FP_TO_UINT, MVT::i16, MVT::i32); + // F16 - VOP1 Actions. + setOperationAction(ISD::FCOS, MVT::f16, Promote); + setOperationAction(ISD::FSIN, MVT::f16, Promote); + + // F16 - VOP2 Actions. + setOperationAction(ISD::FMAXNUM, MVT::f16, Legal); + setOperationAction(ISD::FMINNUM, MVT::f16, Legal); + setOperationAction(ISD::FDIV, MVT::f16, Promote); + + // F16 - VOP3 Actions. + setOperationAction(ISD::FMA, MVT::f16, Legal); + if (!Subtarget->hasFP16Denormals()) + setOperationAction(ISD::FMAD, MVT::f16, Legal); } setTargetDAGCombine(ISD::FADD); @@ -641,6 +661,7 @@ SDValue SITargetLowering::LowerParameterPtr(SelectionDAG &DAG, return DAG.getNode(ISD::ADD, SL, PtrVT, BasePtr, DAG.getConstant(Offset, SL, PtrVT)); } + SDValue SITargetLowering::LowerParameter(SelectionDAG &DAG, EVT VT, EVT MemVT, const SDLoc &SL, SDValue Chain, unsigned Offset, bool Signed) const { @@ -659,7 +680,7 @@ SDValue SITargetLowering::LowerParameter(SelectionDAG &DAG, EVT VT, EVT MemVT, SDValue Val; if (MemVT.isFloatingPoint()) - Val = DAG.getNode(ISD::FP_EXTEND, SL, VT, Load); + Val = getFPExtOrFPTrunc(DAG, Load, SL, VT); else if (Signed) Val = DAG.getSExtOrTrunc(Load, SL, VT); else @@ -1802,6 +1823,15 @@ SDValue SITargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::INTRINSIC_VOID: return LowerINTRINSIC_VOID(Op, DAG); case ISD::ADDRSPACECAST: return lowerADDRSPACECAST(Op, DAG); case ISD::TRAP: return lowerTRAP(Op, DAG); + + case ISD::ConstantFP: + return lowerConstantFP(Op, DAG); + case ISD::FP_TO_SINT: + case ISD::FP_TO_UINT: + return lowerFpToInt(Op, DAG); + case ISD::SINT_TO_FP: + case ISD::UINT_TO_FP: + return lowerIntToFp(Op, DAG); } return SDValue(); } @@ -1995,6 +2025,66 @@ SDValue SITargetLowering::LowerBRCOND(SDValue BRCOND, return Chain; } +SDValue SITargetLowering::getFPExtOrFPTrunc(SelectionDAG &DAG, + SDValue Op, + const SDLoc &DL, + EVT VT) const { + return Op.getValueType().bitsLE(VT) ? + DAG.getNode(ISD::FP_EXTEND, DL, VT, Op) : + DAG.getNode(ISD::FTRUNC, DL, VT, Op); +} + +SDValue SITargetLowering::lowerConstantFP(SDValue Op, SelectionDAG &DAG) const { + if (ConstantFPSDNode *FP = dyn_cast<ConstantFPSDNode>(Op)) { + return DAG.getConstant(FP->getValueAPF().bitcastToAPInt().getZExtValue(), + SDLoc(Op), MVT::i32); + } + + return SDValue(); +} + +SDValue SITargetLowering::lowerFpToInt(SDValue Op, SelectionDAG &DAG) const { + EVT DstVT = Op.getValueType(); + EVT SrcVT = Op.getOperand(0).getValueType(); + if (DstVT == MVT::i64) { + return Op.getOpcode() == ISD::FP_TO_SINT ? + AMDGPUTargetLowering::LowerFP_TO_SINT(Op, DAG) : + AMDGPUTargetLowering::LowerFP_TO_UINT(Op, DAG); + } + + if (SrcVT == MVT::f16) + return Op; + + SDLoc DL(Op); + SDValue OrigSrc = Op.getOperand(0); + SDValue FPRoundFlag = DAG.getIntPtrConstant(0, DL); + SDValue FPRoundSrc = + DAG.getNode(ISD::FP_ROUND, DL, MVT::f16, OrigSrc, FPRoundFlag); + + return DAG.getNode(Op.getOpcode(), DL, DstVT, FPRoundSrc); +} + +SDValue SITargetLowering::lowerIntToFp(SDValue Op, SelectionDAG &DAG) const { + EVT DstVT = Op.getValueType(); + EVT SrcVT = Op.getOperand(0).getValueType(); + if (SrcVT == MVT::i64) { + return Op.getOpcode() == ISD::SINT_TO_FP ? + AMDGPUTargetLowering::LowerSINT_TO_FP(Op, DAG) : + AMDGPUTargetLowering::LowerUINT_TO_FP(Op, DAG); + } + + if (DstVT == MVT::f16) + return Op; + + SDLoc DL(Op); + SDValue OrigSrc = Op.getOperand(0); + SDValue SExtOrZExtOrTruncSrc = Op.getOpcode() == ISD::SINT_TO_FP ? + DAG.getSExtOrTrunc(OrigSrc, DL, MVT::i32) : + DAG.getZExtOrTrunc(OrigSrc, DL, MVT::i32); + + return DAG.getNode(Op.getOpcode(), DL, DstVT, SExtOrZExtOrTruncSrc); +} + SDValue SITargetLowering::getSegmentAperture(unsigned AS, SelectionDAG &DAG) const { SDLoc SL; @@ -3562,7 +3652,8 @@ SDValue SITargetLowering::performSetCCCombine(SDNode *N, SDValue RHS = N->getOperand(1); EVT VT = LHS.getValueType(); - if (VT != MVT::f32 && VT != MVT::f64) + if (VT != MVT::f32 && VT != MVT::f64 && (Subtarget->has16BitInsts() && + VT != MVT::f16)) return SDValue(); // Match isinf pattern @@ -3706,8 +3797,7 @@ SDValue SITargetLowering::PerformDAGCombine(SDNode *N, // // Only do this if we are not trying to support denormals. v_mad_f32 does // not support denormals ever. - if (VT == MVT::f32 && - !Subtarget->hasFP32Denormals()) { + if (VT == MVT::f32 && !Subtarget->hasFP32Denormals()) { SDValue LHS = N->getOperand(0); SDValue RHS = N->getOperand(1); if (LHS.getOpcode() == ISD::FADD) { |

