mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-30 04:35:00 +00:00
SelectionDAG: Add KnownBits and SignBits computation for EXTRACT_ELEMENT
v2: use getZExtValue add missing break codestyle v3: add few more comments Signed-off-by: Jan Vesely <jan.vesely@rutgers.edu> Reviewed-by: Matt Arsenault <Matthew.Arsenault@amd.com> git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@226880 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
cd0d34f1a3
commit
3ff611bb38
@ -2344,6 +2344,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)) {
|
||||
@ -2543,6 +2558,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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user