Skip to content

Commit 4848382

Browse files
author
v01dxyz
committed
[CodeGenPrepare] Do not despeculate count leading/trailing ones if promotion
For count leading/trailing ones, ie (CTLZ/CTTZ (XOR Op -1)), legalisation should be able to optimise this case when a promotion is necessary. Despeculation should not be applied in this case as it will separate XOR and CTLZ/CTTZ in two different basic blocks. This is particularly problematic with SelectionDAG.
1 parent 626c7ce commit 4848382

File tree

1 file changed

+20
-0
lines changed

1 file changed

+20
-0
lines changed

llvm/lib/CodeGen/CodeGenPrepare.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2310,6 +2310,26 @@ static bool despeculateCountZeros(IntrinsicInst *CountZeros,
23102310
if (Ty->isVectorTy() || SizeInBits > DL->getLargestLegalIntTypeSizeInBits())
23112311
return false;
23122312

2313+
// Do not despeculate if we have (ctlz/cttz (xor op -1)) if the operand is
2314+
// promoted as legalisation should be later able to transform it to:
2315+
//
2316+
// ctlz:
2317+
// (ctlz_zero_undef (lshift (xor (extend op) -1)
2318+
// lshiftamount))
2319+
//
2320+
// cttz:
2321+
// (cttz_zero_undef (xor (zeroextend op) -1))
2322+
//
2323+
// Despeculation is not only useless but also not wanted with SelectionDAG
2324+
// as XOR and CTLZ/CTTZ would be in different basic blocks.
2325+
EVT VTy = TLI->getValueType(*DL, Ty);
2326+
int ISDOpcode = IntrinsicID == Intrinsic::ctlz ? ISD::CTLZ : ISD::CTTZ;
2327+
if (match(CountZeros->getOperand(0), m_Not(m_Value())) &&
2328+
(TLI->getTypeAction(CountZeros->getContext(), VTy) ==
2329+
TargetLowering::TypePromoteInteger ||
2330+
TLI->getOperationAction(ISDOpcode, VTy) == TargetLowering::Promote))
2331+
return false;
2332+
23132333
// Bail if the value is never zero.
23142334
Use &Op = CountZeros->getOperandUse(0);
23152335
if (isKnownNonZero(Op, *DL))

0 commit comments

Comments
 (0)