[PATCH 2/3] SelectionDAG: Add KnownBits and SignBits computation for EXTRACT_ELEMENT

Jan Vesely jan.vesely at rutgers.edu
Thu Jan 22 10:37:30 PST 2015


ping.

Mehdi, is this version OK with you?

jan

On Wed, 2015-01-14 at 15:11 -0500, Jan Vesely wrote:
> v2: use getZExtValue
>     add missing break
>     codestyle
> 
> v3: add few more comments
> 
> Signed-off-by: Jan Vesely <jan.vesely at rutgers.edu>
> ---
> 
> Hi Mehdi,
> 
> I was not sure what kind of comments you had in mind, so I added few that are
> in line with the rest of the code in those functions.
> 
> jan
> 
>  lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
> 
> diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> index c819516..673fbf3 100644
> --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
> @@ -2323,6 +2323,21 @@ void SelectionDAG::computeKnownBits(SDValue Op, APInt &KnownZero,
>      KnownZero = APInt::getHighBitsSet(BitWidth, Leaders);
>      break;
>    }
> +  case ISD::EXTRACT_ELEMENT: {
> +    computeKnownBits(Op.getOperand(0), KnownZero, KnownOne, Depth+1);
> +    const unsigned Index =
> +      cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
> +    const unsigned BitWidth = Op.getValueType().getSizeInBits();
> +
> +    // Remove low part of known bits mask
> +    KnownZero = KnownZero.getHiBits(KnownZero.getBitWidth() - Index * BitWidth);
> +    KnownOne = KnownOne.getHiBits(KnownOne.getBitWidth() - Index * BitWidth);
> +
> +    // Remove high part of known bit mask
> +    KnownZero = KnownZero.trunc(BitWidth);
> +    KnownOne = KnownOne.trunc(BitWidth);
> +    break;
> +  }
>    case ISD::FrameIndex:
>    case ISD::TargetFrameIndex:
>      if (unsigned Align = InferPtrAlignment(Op)) {
> @@ -2522,6 +2537,21 @@ unsigned SelectionDAG::ComputeNumSignBits(SDValue Op, unsigned Depth) const{
>      // FIXME: it's tricky to do anything useful for this, but it is an important
>      // case for targets like X86.
>      break;
> +  case ISD::EXTRACT_ELEMENT: {
> +    const int KnownSign = ComputeNumSignBits(Op.getOperand(0), Depth+1);
> +    const int BitWidth = Op.getValueType().getSizeInBits();
> +    const int Items =
> +      Op.getOperand(0).getValueType().getSizeInBits() / BitWidth;
> +
> +    // Get reverse index (starting from 1), Op1 value indexes elements from
> +    // little end. Sign starts at big end.
> +    const int rIndex = Items - 1 -
> +      cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
> +
> +    // If the sign portion ends in our element the substraction gives correct
> +    // result. Otherwise it gives either negative or > bitwidth result
> +    return std::max(std::min(KnownSign - rIndex * BitWidth, BitWidth), 0);
> +  }
>    }
>  
>    // If we are looking at the loaded value of the SDNode.

-- 
Jan Vesely <jan.vesely at rutgers.edu>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150122/b8405a86/attachment.sig>


More information about the llvm-commits mailing list