[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