Skip to content

Commit 8b1bb2f

Browse files
committed
[CodeGen] Add expandCTLZWithFP helper to TargetLowering supporting vXi32 types
1 parent 1f8d5d4 commit 8b1bb2f

File tree

2 files changed

+52
-0
lines changed

2 files changed

+52
-0
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5543,6 +5543,11 @@ class LLVM_ABI TargetLowering : public TargetLoweringBase {
55435543
/// \returns The expansion result or SDValue() if it fails.
55445544
SDValue expandVPCTLZ(SDNode *N, SelectionDAG &DAG) const;
55455545

5546+
/// Expands a CTLZ node into a sequence of floating point operations.
5547+
/// \param N Node to expand
5548+
/// \returns The expansion result or SDValue() if it fails.
5549+
SDValue expandCTLZWithFP(SDNode *N, SelectionDAG &DAG) const;
5550+
55465551
/// Expand CTTZ via Table Lookup.
55475552
/// \param N Node to expand
55485553
/// \returns The expansion result or SDValue() if it fails.

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9480,6 +9480,53 @@ SDValue TargetLowering::expandVPCTLZ(SDNode *Node, SelectionDAG &DAG) const {
94809480
return DAG.getNode(ISD::VP_CTPOP, dl, VT, Op, Mask, VL);
94819481
}
94829482

9483+
9484+
SDValue TargetLowering::expandCTLZWithFP(SDNode *Node, SelectionDAG &DAG) const {
9485+
SDLoc dl(Node);
9486+
SDValue Op = Node->getOperand(0);
9487+
EVT VT = Op.getValueType();
9488+
9489+
assert(VT.isVector() && "This expansion is intended for vectors");
9490+
9491+
EVT EltVT = VT.getVectorElementType();
9492+
EVT FloatVT, CmpVT;
9493+
unsigned BitWidth, MantissaBits, ExponentBias;
9494+
9495+
// Converting to float type
9496+
if (EltVT == MVT::i32) {
9497+
FloatVT = VT.changeVectorElementType(MVT::f32);
9498+
BitWidth = 32;
9499+
MantissaBits = 23;
9500+
ExponentBias = 127;
9501+
}
9502+
else {
9503+
return SDValue();
9504+
}
9505+
9506+
// Handling the case for when Op == 0 which is stored in ZeroRes
9507+
CmpVT = getSetCCResultType(DAG.getDataLayout(), *DAG.getContext(), VT);
9508+
SDValue Zero = DAG.getConstant(0, dl, VT);
9509+
SDValue IsZero = DAG.getSetCC(dl, CmpVT, Op, Zero, ISD::SETEQ);
9510+
SDValue ZeroRes = DAG.getConstant(BitWidth, dl, VT);
9511+
9512+
// Handling the case for Non-zero inputs using the algorithm mentioned below
9513+
SDValue Float = DAG.getNode(ISD::UINT_TO_FP, dl, FloatVT, Op);
9514+
SDValue FloatBits = DAG.getNode(ISD::BITCAST, dl, VT, Float);
9515+
SDValue Exp = DAG.getNode(ISD::SRL, dl, VT, FloatBits, DAG.getConstant(MantissaBits, dl, VT));
9516+
SDValue MSBIndex = DAG.getNode(ISD::SUB, dl, VT, Exp, DAG.getConstant(ExponentBias, dl, VT));
9517+
SDValue NonZeroRes = DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(BitWidth - 1, dl, VT), MSBIndex);
9518+
9519+
//Returns the respective DAG Node based on the input being zero or non-zero
9520+
return DAG.getNode(ISD::VSELECT, dl, VT, IsZero, ZeroRes, NonZeroRes);
9521+
9522+
// pseudocode :
9523+
// if(x==0) return 32;
9524+
// float f = (float) x;
9525+
// int i = bitcast<int>(f);
9526+
// int ilog2 = (i >> 23) - 127;
9527+
// return 31 - ilog2;
9528+
}
9529+
94839530
SDValue TargetLowering::CTTZTableLookup(SDNode *Node, SelectionDAG &DAG,
94849531
const SDLoc &DL, EVT VT, SDValue Op,
94859532
unsigned BitWidth) const {

0 commit comments

Comments
 (0)