diff options
author | Simon Pilgrim <llvm-dev@redking.me.uk> | 2024-02-02 16:18:43 +0000 |
---|---|---|
committer | Simon Pilgrim <llvm-dev@redking.me.uk> | 2024-02-02 18:03:20 +0000 |
commit | 3a758076f54d521d20e32856a62c7d24803ee9e8 (patch) | |
tree | 9f138eed0e7e9afcaa6a6a99069f508a8d2cdba4 /llvm/lib | |
parent | 7ecfb66c77ad77dabbb705cbb1f3b17a3d1391a4 (diff) | |
download | llvm-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.cpp | 14 |
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)); |