mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-06 23:32:27 +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);
|
KnownZero = APInt::getHighBitsSet(BitWidth, Leaders);
|
||||||
break;
|
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::FrameIndex:
|
||||||
case ISD::TargetFrameIndex:
|
case ISD::TargetFrameIndex:
|
||||||
if (unsigned Align = InferPtrAlignment(Op)) {
|
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
|
// FIXME: it's tricky to do anything useful for this, but it is an important
|
||||||
// case for targets like X86.
|
// case for targets like X86.
|
||||||
break;
|
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.
|
// If we are looking at the loaded value of the SDNode.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user