[llvm] r195397 - Split SETCC if VSELECT requires splitting too.

Tom Stellard tom at stellard.net
Thu Nov 21 20:27:05 PST 2013


Hi Bill,

Could you merge this into the 3.4 branch.  This is first of the two
patches that Owen pre-approved for the 3.4 branch:

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20131118/196061.html

Thanks,
Tom

On Fri, Nov 22, 2013 at 12:39:24AM -0000, Tom Stellard wrote:
> Author: tstellar
> Date: Thu Nov 21 18:39:23 2013
> New Revision: 195397
> 
> URL: http://llvm.org/viewvc/llvm-project?rev=195397&view=rev
> Log:
> Split SETCC if VSELECT requires splitting too.
> 
> This patch is a rewrite of the original patch commited in r194542. Instead of
> relying on the type legalizer to do the splitting for us, we now peform the
> splitting ourselves in the DAG combiner. This is necessary for the case where
> the vector mask is a legal type after promotion and still wouldn't require
> splitting.
> 
> Patch by: Juergen Ributzka
> 
> NOTE: This is a candidate for the 3.4 branch.
> 
> Modified:
>     llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
>     llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
>     llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
> 
> Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=195397&r1=195396&r2=195397&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
> +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Thu Nov 21 18:39:23 2013
> @@ -1149,7 +1149,8 @@ public:
>  
>    /// SplitVectorOperand - Split the node's operand with EXTRACT_SUBVECTOR and
>    /// return the low/high part.
> -  std::pair<SDValue, SDValue> SplitVectorOperand(SDNode *N, unsigned OpNo) {
> +  std::pair<SDValue, SDValue> SplitVectorOperand(const SDNode *N, unsigned OpNo)
> +  {
>      return SplitVector(N->getOperand(OpNo), SDLoc(N));
>    }
>  
> 
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=195397&r1=195396&r2=195397&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Thu Nov 21 18:39:23 2013
> @@ -4327,6 +4327,23 @@ SDValue DAGCombiner::visitSELECT(SDNode
>    return SDValue();
>  }
>  
> +static
> +std::pair<SDValue, SDValue> SplitVSETCC(const SDNode *N, SelectionDAG &DAG) {
> +  SDLoc DL(N);
> +  EVT LoVT, HiVT;
> +  llvm::tie(LoVT, HiVT) = DAG.GetSplitDestVTs(N->getValueType(0));
> +
> +  // Split the inputs.
> +  SDValue Lo, Hi, LL, LH, RL, RH;
> +  llvm::tie(LL, LH) = DAG.SplitVectorOperand(N, 0);
> +  llvm::tie(RL, RH) = DAG.SplitVectorOperand(N, 1);
> +
> +  Lo = DAG.getNode(N->getOpcode(), DL, LoVT, LL, RL, N->getOperand(2));
> +  Hi = DAG.getNode(N->getOpcode(), DL, HiVT, LH, RH, N->getOperand(2));
> +
> +  return std::make_pair(Lo, Hi);
> +}
> +
>  SDValue DAGCombiner::visitVSELECT(SDNode *N) {
>    SDValue N0 = N->getOperand(0);
>    SDValue N1 = N->getOperand(1);
> @@ -4364,27 +4381,32 @@ SDValue DAGCombiner::visitVSELECT(SDNode
>      }
>    }
>  
> -  // Treat SETCC as a vector mask and promote the result type based on the
> -  // targets expected SETCC result type. This will ensure that SETCC and VSELECT
> -  // are both split by the type legalizer. This is done to prevent the type
> -  // legalizer from unrolling SETCC into scalar comparions.
> -  EVT SelectVT = N->getValueType(0);
> -  EVT MaskVT = getSetCCResultType(SelectVT);
> -  assert(MaskVT.isVector() && "Expected a vector type.");
> -  if (N0.getOpcode() == ISD::SETCC && N0.getValueType() != MaskVT) {
> -    SDLoc MaskDL(N0);
> -
> -    // Extend the mask to the desired value type.
> -    ISD::NodeType ExtendCode =
> -      TargetLowering::getExtendForContent(TLI.getBooleanContents(true));
> -    SDValue Mask = DAG.getNode(ExtendCode, MaskDL, MaskVT, N0);
> -
> -    AddToWorkList(Mask.getNode());
> +  // If the VSELECT result requires splitting and the mask is provided by a
> +  // SETCC, then split both nodes and its operands before legalization. This
> +  // prevents the type legalizer from unrolling SETCC into scalar comparisons
> +  // and enables future optimizations (e.g. min/max pattern matching on X86).
> +  if (N0.getOpcode() == ISD::SETCC) {
> +    EVT VT = N->getValueType(0);
>  
> -    SDValue LHS = N->getOperand(1);
> -    SDValue RHS = N->getOperand(2);
> +    // Check if any splitting is required.
> +    if (TLI.getTypeAction(*DAG.getContext(), VT) !=
> +        TargetLowering::TypeSplitVector)
> +      return SDValue();
> +
> +    SDValue Lo, Hi, CCLo, CCHi, LL, LH, RL, RH;
> +    llvm::tie(CCLo, CCHi) = SplitVSETCC(N0.getNode(), DAG);
> +    llvm::tie(LL, LH) = DAG.SplitVectorOperand(N, 1);
> +    llvm::tie(RL, RH) = DAG.SplitVectorOperand(N, 2);
> +
> +    Lo = DAG.getNode(N->getOpcode(), DL, LL.getValueType(), CCLo, LL, RL);
> +    Hi = DAG.getNode(N->getOpcode(), DL, LH.getValueType(), CCHi, LH, RH);
> +
> +    // Add the new VSELECT nodes to the work list in case they need to be split
> +    // again.
> +    AddToWorkList(Lo.getNode());
> +    AddToWorkList(Hi.getNode());
>  
> -    return DAG.getNode(ISD::VSELECT, DL, SelectVT, Mask, LHS, RHS);
> +    return DAG.getNode(ISD::CONCAT_VECTORS, DL, VT, Lo, Hi);
>    }
>  
>    return SDValue();
> 
> Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp?rev=195397&r1=195396&r2=195397&view=diff
> ==============================================================================
> --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp (original)
> +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp Thu Nov 21 18:39:23 2013
> @@ -488,11 +488,11 @@ void DAGTypeLegalizer::SplitRes_SELECT(S
>    SDValue Cond = N->getOperand(0);
>    CL = CH = Cond;
>    if (Cond.getValueType().isVector()) {
> -    if (Cond.getOpcode() == ISD::SETCC) {
> -      assert(Cond.getValueType() == getSetCCResultType(N->getValueType(0)) &&
> -             "Condition has not been prepared for split!");
> +    // Check if there are already splitted versions of the vector available and
> +    // use those instead of splitting the mask operand again.
> +    if (getTypeAction(Cond.getValueType()) == TargetLowering::TypeSplitVector)
>        GetSplitVector(Cond, CL, CH);
> -    } else
> +    else
>        llvm::tie(CL, CH) = DAG.SplitVector(Cond, dl);
>    }
>  
> 
> 
> _______________________________________________
> 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