aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib
diff options
context:
space:
mode:
authorSimon Pilgrim <llvm-dev@redking.me.uk>2024-02-02 16:18:43 +0000
committerSimon Pilgrim <llvm-dev@redking.me.uk>2024-02-02 18:03:20 +0000
commit3a758076f54d521d20e32856a62c7d24803ee9e8 (patch)
tree9f138eed0e7e9afcaa6a6a99069f508a8d2cdba4 /llvm/lib
parent7ecfb66c77ad77dabbb705cbb1f3b17a3d1391a4 (diff)
downloadllvm-3a758076f54d521d20e32856a62c7d24803ee9e8.zip
llvm-3a758076f54d521d20e32856a62c7d24803ee9e8.tar.gz
llvm-3a758076f54d521d20e32856a62c7d24803ee9e8.tar.bz2
[X86] Allow i8 CTPOP expansion to work with a 'shifted' active bits value of 8 bits or less
Shift down the value so the active bits are at the lsb
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index b6468a9..35613e6 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -31037,12 +31037,22 @@ static SDValue LowerCTPOP(SDValue N, const X86Subtarget &Subtarget,
SDLoc DL(N);
if (VT.isScalarInteger()) {
+ // Compute the lower/upper bounds of the active bits of the value,
+ // allowing us to shift the active bits down if necessary to fit into the
+ // special cases below.
KnownBits Known = DAG.computeKnownBits(Op);
- unsigned ActiveBits = Known.countMaxActiveBits();
+ unsigned LZ = Known.countMinLeadingZeros();
+ unsigned TZ = Known.countMinTrailingZeros();
+ assert((LZ + TZ) < Known.getBitWidth() && "Illegal shifted mask");
+ unsigned ActiveBits = Known.getBitWidth() - LZ;
+ unsigned ShiftedActiveBits = Known.getBitWidth() - (LZ + TZ);
// i8 CTPOP - with efficient i32 MUL, then attempt multiply-mask-multiply.
- if (ActiveBits <= 8) {
+ if (ShiftedActiveBits <= 8) {
SDValue Mask11 = DAG.getConstant(0x11111111U, DL, MVT::i32);
+ if (ActiveBits > 8)
+ Op = DAG.getNode(ISD::SRL, DL, VT, Op,
+ DAG.getShiftAmountConstant(TZ, VT, DL));
Op = DAG.getZExtOrTrunc(Op, DL, MVT::i32);
Op = DAG.getNode(ISD::MUL, DL, MVT::i32, Op,
DAG.getConstant(0x08040201U, DL, MVT::i32));