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

Mehdi Amini mehdi.amini at apple.com
Thu Jan 22 13:26:34 PST 2015


Hi Jan,

Sorry, I haven’t seen your previous email. Do not hesitate to ping after 2 days without an answer.

Ok for me.

Mehdi



> On Jan 22, 2015, at 10:37 AM, Jan Vesely <jan.vesely at rutgers.edu> wrote:
> 
> 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>





More information about the llvm-commits mailing list