[PATCH v2 2/3] R600: Use LowerSDIVREM for i64 node replace
Matt Arsenault
arsenm2 at gmail.com
Sun Jun 22 14:21:02 PDT 2014
On Jun 22, 2014, at 12:58 PM, Jan Vesely <jan.vesely at rutgers.edu> wrote:
> v2: move div/rem node replacement to R600ISelLowering
> make lowerSDIVREM protected
>
> Signed-off-by: Jan Vesely <jan.vesely at rutgers.edu>
> ---
> lib/Target/R600/AMDGPUISelLowering.cpp | 90 -------------------------
> lib/Target/R600/AMDGPUISelLowering.h | 2 +-
> lib/Target/R600/R600ISelLowering.cpp | 120 ++++++++++++++++++++++++++++++++-
LGTM
> 3 files changed, 120 insertions(+), 92 deletions(-)
>
> diff --git a/lib/Target/R600/AMDGPUISelLowering.cpp b/lib/Target/R600/AMDGPUISelLowering.cpp
> index caf701b..968f9f4 100644
> --- a/lib/Target/R600/AMDGPUISelLowering.cpp
> +++ b/lib/Target/R600/AMDGPUISelLowering.cpp
> @@ -536,96 +536,6 @@ void AMDGPUTargetLowering::ReplaceNodeResults(SDNode *N,
> // ReplaceNodeResults to sext_in_reg to an illegal type, so we'll just do
> // nothing here and let the illegal result integer be handled normally.
> return;
> - case ISD::UDIV: {
> - SDValue Op = SDValue(N, 0);
> - SDLoc DL(Op);
> - EVT VT = Op.getValueType();
> - SDValue UDIVREM = DAG.getNode(ISD::UDIVREM, DL, DAG.getVTList(VT, VT),
> - N->getOperand(0), N->getOperand(1));
> - Results.push_back(UDIVREM);
> - break;
> - }
> - case ISD::UREM: {
> - SDValue Op = SDValue(N, 0);
> - SDLoc DL(Op);
> - EVT VT = Op.getValueType();
> - SDValue UDIVREM = DAG.getNode(ISD::UDIVREM, DL, DAG.getVTList(VT, VT),
> - N->getOperand(0), N->getOperand(1));
> - Results.push_back(UDIVREM.getValue(1));
> - break;
> - }
> - case ISD::UDIVREM: {
> - SDValue Op = SDValue(N, 0);
> - SDLoc DL(Op);
> - EVT VT = Op.getValueType();
> - EVT HalfVT = VT.getHalfSizedIntegerVT(*DAG.getContext());
> -
> - SDValue one = DAG.getConstant(1, HalfVT);
> - SDValue zero = DAG.getConstant(0, HalfVT);
> -
> - //HiLo split
> - SDValue LHS = N->getOperand(0);
> - SDValue LHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, LHS, zero);
> - SDValue LHS_Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, LHS, one);
> -
> - SDValue RHS = N->getOperand(1);
> - SDValue RHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, RHS, zero);
> - SDValue RHS_Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, RHS, one);
> -
> - // Get Speculative values
> - SDValue DIV_Part = DAG.getNode(ISD::UDIV, DL, HalfVT, LHS_Hi, RHS_Lo);
> - SDValue REM_Part = DAG.getNode(ISD::UREM, DL, HalfVT, LHS_Hi, RHS_Lo);
> -
> - SDValue REM_Hi = zero;
> - SDValue REM_Lo = DAG.getSelectCC(DL, RHS_Hi, zero, REM_Part, LHS_Hi, ISD::SETEQ);
> -
> - SDValue DIV_Hi = DAG.getSelectCC(DL, RHS_Hi, zero, DIV_Part, zero, ISD::SETEQ);
> - SDValue DIV_Lo = zero;
> -
> - const unsigned halfBitWidth = HalfVT.getSizeInBits();
> -
> - for (unsigned i = 0; i < halfBitWidth; ++i) {
> - SDValue POS = DAG.getConstant(halfBitWidth - i - 1, HalfVT);
> - // Get Value of high bit
> - SDValue HBit;
> - if (halfBitWidth == 32 && Subtarget->hasBFE()) {
> - HBit = DAG.getNode(AMDGPUISD::BFE_U32, DL, HalfVT, LHS_Lo, POS, one);
> - } else {
> - HBit = DAG.getNode(ISD::SRL, DL, HalfVT, LHS_Lo, POS);
> - HBit = DAG.getNode(ISD::AND, DL, HalfVT, HBit, one);
> - }
> -
> - SDValue Carry = DAG.getNode(ISD::SRL, DL, HalfVT, REM_Lo,
> - DAG.getConstant(halfBitWidth - 1, HalfVT));
> - REM_Hi = DAG.getNode(ISD::SHL, DL, HalfVT, REM_Hi, one);
> - REM_Hi = DAG.getNode(ISD::OR, DL, HalfVT, REM_Hi, Carry);
> -
> - REM_Lo = DAG.getNode(ISD::SHL, DL, HalfVT, REM_Lo, one);
> - REM_Lo = DAG.getNode(ISD::OR, DL, HalfVT, REM_Lo, HBit);
> -
> -
> - SDValue REM = DAG.getNode(ISD::BUILD_PAIR, DL, VT, REM_Lo, REM_Hi);
> -
> - SDValue BIT = DAG.getConstant(1 << (halfBitWidth - i - 1), HalfVT);
> - SDValue realBIT = DAG.getSelectCC(DL, REM, RHS, BIT, zero, ISD::SETGE);
> -
> - DIV_Lo = DAG.getNode(ISD::OR, DL, HalfVT, DIV_Lo, realBIT);
> -
> - // Update REM
> -
> - SDValue REM_sub = DAG.getNode(ISD::SUB, DL, VT, REM, RHS);
> -
> - REM = DAG.getSelectCC(DL, REM, RHS, REM_sub, REM, ISD::SETGE);
> - REM_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, REM, zero);
> - REM_Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, REM, one);
> - }
> -
> - SDValue REM = DAG.getNode(ISD::BUILD_PAIR, DL, VT, REM_Lo, REM_Hi);
> - SDValue DIV = DAG.getNode(ISD::BUILD_PAIR, DL, VT, DIV_Lo, DIV_Hi);
> - Results.push_back(DIV);
> - Results.push_back(REM);
> - break;
> - }
> default:
> return;
> }
> diff --git a/lib/Target/R600/AMDGPUISelLowering.h b/lib/Target/R600/AMDGPUISelLowering.h
> index 0db89ecb..cffa6bc 100644
> --- a/lib/Target/R600/AMDGPUISelLowering.h
> +++ b/lib/Target/R600/AMDGPUISelLowering.h
> @@ -50,7 +50,6 @@ private:
> SDValue LowerSREM(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerSREM32(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerSREM64(SDValue Op, SelectionDAG &DAG) const;
> - SDValue LowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerUDIVREM(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerFCEIL(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerFTRUNC(SDValue Op, SelectionDAG &DAG) const;
> @@ -83,6 +82,7 @@ protected:
> SDValue SplitVectorStore(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
> SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
> + SDValue LowerSDIVREM(SDValue Op, SelectionDAG &DAG) const;
> bool isHWTrueValue(SDValue Op) const;
> bool isHWFalseValue(SDValue Op) const;
>
> diff --git a/lib/Target/R600/R600ISelLowering.cpp b/lib/Target/R600/R600ISelLowering.cpp
> index f0e13e5..222c3d7 100644
> --- a/lib/Target/R600/R600ISelLowering.cpp
> +++ b/lib/Target/R600/R600ISelLowering.cpp
> @@ -156,6 +156,8 @@ R600TargetLowering::R600TargetLowering(TargetMachine &TM) :
> // during Type Legalization
> setOperationAction(ISD::UDIV, MVT::i64, Custom);
> setOperationAction(ISD::UREM, MVT::i64, Custom);
> + setOperationAction(ISD::SDIV, MVT::i64, Custom);
> + setOperationAction(ISD::SREM, MVT::i64, Custom);
>
> // We don't have 64-bit shifts. Thus we need either SHX i64 or SHX_PARTS i32
> // to be Legal/Custom in order to avoid library calls.
> @@ -826,11 +828,127 @@ void R600TargetLowering::ReplaceNodeResults(SDNode *N,
> DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), SDValue(Node, 1));
> return;
> }
> - case ISD::STORE:
> + case ISD::STORE: {
> SDNode *Node = LowerSTORE(SDValue(N, 0), DAG).getNode();
> Results.push_back(SDValue(Node, 0));
> return;
> }
> + case ISD::UDIV: {
> + SDValue Op = SDValue(N, 0);
> + SDLoc DL(Op);
> + EVT VT = Op.getValueType();
> + SDValue UDIVREM = DAG.getNode(ISD::UDIVREM, DL, DAG.getVTList(VT, VT),
> + N->getOperand(0), N->getOperand(1));
> + Results.push_back(UDIVREM);
> + break;
> + }
> + case ISD::UREM: {
> + SDValue Op = SDValue(N, 0);
> + SDLoc DL(Op);
> + EVT VT = Op.getValueType();
> + SDValue UDIVREM = DAG.getNode(ISD::UDIVREM, DL, DAG.getVTList(VT, VT),
> + N->getOperand(0), N->getOperand(1));
> + Results.push_back(UDIVREM.getValue(1));
> + break;
> + }
> + case ISD::SDIV: {
> + SDValue Op = SDValue(N, 0);
> + SDLoc DL(Op);
> + EVT VT = Op.getValueType();
> + SDValue SDIVREM = DAG.getNode(ISD::SDIVREM, DL, DAG.getVTList(VT, VT),
> + N->getOperand(0), N->getOperand(1));
> + Results.push_back(SDIVREM);
> + break;
> + }
> + case ISD::SREM: {
> + SDValue Op = SDValue(N, 0);
> + SDLoc DL(Op);
> + EVT VT = Op.getValueType();
> + SDValue SDIVREM = DAG.getNode(ISD::SDIVREM, DL, DAG.getVTList(VT, VT),
> + N->getOperand(0), N->getOperand(1));
> + Results.push_back(SDIVREM.getValue(1));
> + break;
> + }
> + case ISD::SDIVREM: {
> + SDValue Op = SDValue(N, 1);
> + SDValue RES = LowerSDIVREM(Op, DAG);
> + Results.push_back(RES);
> + Results.push_back(RES.getValue(1));
> + break;
> + }
> + case ISD::UDIVREM: {
> + SDValue Op = SDValue(N, 0);
> + SDLoc DL(Op);
> + EVT VT = Op.getValueType();
> + EVT HalfVT = VT.getHalfSizedIntegerVT(*DAG.getContext());
> +
> + SDValue one = DAG.getConstant(1, HalfVT);
> + SDValue zero = DAG.getConstant(0, HalfVT);
> +
> + //HiLo split
> + SDValue LHS = N->getOperand(0);
> + SDValue LHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, LHS, zero);
> + SDValue LHS_Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, LHS, one);
> +
> + SDValue RHS = N->getOperand(1);
> + SDValue RHS_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, RHS, zero);
> + SDValue RHS_Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, RHS, one);
> +
> + // Get Speculative values
> + SDValue DIV_Part = DAG.getNode(ISD::UDIV, DL, HalfVT, LHS_Hi, RHS_Lo);
> + SDValue REM_Part = DAG.getNode(ISD::UREM, DL, HalfVT, LHS_Hi, RHS_Lo);
> +
> + SDValue REM_Hi = zero;
> + SDValue REM_Lo = DAG.getSelectCC(DL, RHS_Hi, zero, REM_Part, LHS_Hi, ISD::SETEQ);
> +
> + SDValue DIV_Hi = DAG.getSelectCC(DL, RHS_Hi, zero, DIV_Part, zero, ISD::SETEQ);
> + SDValue DIV_Lo = zero;
> +
> + const unsigned halfBitWidth = HalfVT.getSizeInBits();
> +
> + for (unsigned i = 0; i < halfBitWidth; ++i) {
> + SDValue POS = DAG.getConstant(halfBitWidth - i - 1, HalfVT);
> + // Get Value of high bit
> + SDValue HBit;
> + if (halfBitWidth == 32 && Subtarget->hasBFE()) {
> + HBit = DAG.getNode(AMDGPUISD::BFE_U32, DL, HalfVT, LHS_Lo, POS, one);
> + } else {
> + HBit = DAG.getNode(ISD::SRL, DL, HalfVT, LHS_Lo, POS);
> + HBit = DAG.getNode(ISD::AND, DL, HalfVT, HBit, one);
> + }
> +
> + SDValue Carry = DAG.getNode(ISD::SRL, DL, HalfVT, REM_Lo,
> + DAG.getConstant(halfBitWidth - 1, HalfVT));
> + REM_Hi = DAG.getNode(ISD::SHL, DL, HalfVT, REM_Hi, one);
> + REM_Hi = DAG.getNode(ISD::OR, DL, HalfVT, REM_Hi, Carry);
> +
> + REM_Lo = DAG.getNode(ISD::SHL, DL, HalfVT, REM_Lo, one);
> + REM_Lo = DAG.getNode(ISD::OR, DL, HalfVT, REM_Lo, HBit);
> +
> +
> + SDValue REM = DAG.getNode(ISD::BUILD_PAIR, DL, VT, REM_Lo, REM_Hi);
> +
> + SDValue BIT = DAG.getConstant(1 << (halfBitWidth - i - 1), HalfVT);
> + SDValue realBIT = DAG.getSelectCC(DL, REM, RHS, BIT, zero, ISD::SETGE);
> +
> + DIV_Lo = DAG.getNode(ISD::OR, DL, HalfVT, DIV_Lo, realBIT);
> +
> + // Update REM
> +
> + SDValue REM_sub = DAG.getNode(ISD::SUB, DL, VT, REM, RHS);
> +
> + REM = DAG.getSelectCC(DL, REM, RHS, REM_sub, REM, ISD::SETGE);
> + REM_Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, REM, zero);
> + REM_Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, DL, HalfVT, REM, one);
> + }
> +
> + SDValue REM = DAG.getNode(ISD::BUILD_PAIR, DL, VT, REM_Lo, REM_Hi);
> + SDValue DIV = DAG.getNode(ISD::BUILD_PAIR, DL, VT, DIV_Lo, DIV_Hi);
> + Results.push_back(DIV);
> + Results.push_back(REM);
> + break;
> + }
> + }
> }
>
> SDValue R600TargetLowering::vectorToVerticalVector(SelectionDAG &DAG,
> --
> 1.9.3
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list