[llvm-dev] Where's the optimiser gone (part 9): bit twiddling not recognised
Craig Topper via llvm-dev
llvm-dev at lists.llvm.org
Mon Dec 17 23:41:10 PST 2018
I've filed a bugzilla for this https://bugs.llvm.org/show_bug.cgi?id=40058
~Craig
On Mon, Dec 17, 2018 at 3:48 PM Stefan Kanthak via llvm-dev <
llvm-dev at lists.llvm.org> wrote:
> Hi @ll,
>
> compile with -O3 -m32 -march=i686 (see <https://godbolt.org/z/fjjUl6>)
>
> unsigned long lreverse(unsigned long x) // swap all bits
> {
> x = ((x & 0xAAAAAAAAUL) >> 1)
> | ((x & ~0xAAAAAAAAUL) << 1);
> x = ((x & 0xCCCCCCCCUL) >> 2)
> | ((x & ~0xCCCCCCCCUL) << 2);
> x = ((x & 0xF0F0F0F0UL) >> 4)
> | ((x & ~0xF0F0F0F0UL) << 4);
> x = ((x & 0xFF00FF00UL) >> 8)
> | ((x & ~0xFF00FF00UL) << 8);
> x = ((x & 0xFFFF0000UL) >> 16)
> | ((x & ~0xFFFF0000UL) << 16);
>
> return x;
> }
>
> lreverse: # @lreverse
> mov eax, dword ptr [esp + 4]
> mov ecx, eax
> shr ecx, 1
> and ecx, 1431655765
> and eax, 1431655765
> lea eax, [ecx + 2*eax]
> mov ecx, eax
> shr ecx, 2
> and ecx, 858993459
> and eax, 858993459
> lea eax, [ecx + 4*eax]
> mov ecx, eax
> shr ecx, 4
> and ecx, 252645135
> shl eax, 4
> and eax, -252645136
> or eax, ecx
> #ifndef _OPTIMISER_GONE_FISHING // until here, almost perfect;
> bswap eax // the next 7 instructions but can
> #else // be replaced by a single BSWAP
> mov ecx, eax
> shr ecx, 8
> and ecx, 16711935
> shl eax, 8
> and eax, -16711936
> or eax, ecx
> rol eax, 16
> #endif
> ret
>
>
> unsigned long long llreverse(unsigned long long x)
> {
> #if 0
> x = ((x & 0xAAAAAAAAAAAAAAAAULL) >> 1)
> | ((x & ~0xAAAAAAAAAAAAAAAAULL) << 1);
> x = ((x & 0xCCCCCCCCCCCCCCCCULL) >> 2)
> | ((x & ~0xCCCCCCCCCCCCCCCCULL) << 2);
> x = ((x & 0xF0F0F0F0F0F0F0F0ULL) >> 4)
> | ((x & ~0xF0F0F0F0F0F0F0F0ULL) << 4);
> x = ((x & 0xFF00FF00FF00FF00ULL) >> 8)
> | ((x & ~0xFF00FF00FF00FF00ULL) << 8);
> x = ((x & 0xFFFF0000FFFF0000ULL) >> 16)
> | ((x & ~0xFFFF0000FFFF0000ULL) << 16);
> x = ((x & 0xFFFFFFFF00000000ULL) >> 32)
> | ((x & ~0xFFFFFFFF00000000ULL) << 32);
>
> return x;
> #else
> x = ((x >> 1) & ~0xAAAAAAAAAAAAAAAAULL)
> | ((x << 1) & 0xAAAAAAAAAAAAAAAAULL);
> x = ((x >> 2) & ~0xCCCCCCCCCCCCCCCCULL)
> | ((x << 2) & 0xCCCCCCCCCCCCCCCCULL);
> x = ((x >> 4) & ~0xF0F0F0F0F0F0F0F0ULL)
> | ((x << 4) & 0xF0F0F0F0F0F0F0F0ULL);
> x = ((x >> 8) & ~0xFF00FF00FF00FF00ULL)
> | ((x << 8) & 0xFF00FF00FF00FF00ULL);
> x = ((x >> 16) & ~0xFFFF0000FFFF0000ULL)
> | ((x << 16) & 0xFFFF0000FFFF0000ULL);
>
> return (x >> 32) | (x << 32);
> #endif
> }
>
> llreverse: # @llreverse
> push esi
> mov eax, dword ptr [esp + 8]
> mov ecx, dword ptr [esp + 12]
> mov edx, eax
> shr edx
> mov esi, ecx
> shr esi
>
> #ifdef OPTIMISER_GONE_FISHING
> and esi, 1431655765
> and edx, 1431655765
> and ecx, 1431655765
> and eax, 1431655765
> #else
> push ebx
> mov ebx, 1431655765
> and esi, ebx
> and edx, ebx
> and ecx, ebx
> and eax, ebx
> #endif
> lea edx, [edx + 2*eax]
> lea eax, [esi + 2*ecx]
> mov ecx, eax
> shr ecx, 2
> mov esi, edx
> shr esi, 2
> #ifdef OPTIMISER_GONE_FISHING
> and esi, 858993459
> and ecx, 858993459
> and edx, 858993459
> and eax, 858993459
>
> #else
> mov ebx, 858993459
> and esi, ebx
> and ecx, ebx
> and edx, ebx
> and eax, ebx
> #endif
> lea eax, [ecx + 4*eax]
> lea edx, [esi + 4*edx]
> mov ecx, edx
> shr ecx, 4
> mov esi, eax
> shr esi, 4
>
> #ifdef OPTIMISER_GONE_FISHING
> and esi, 252645135
> and ecx, 252645135
>
> #else
> mov ebx, 252645135
> and esi, ebx
> and ecx, ebx
> #endif
> shl edx, 4
> shl eax, 4
>
> #ifdef OPTIMISER_GONE_FISHING
> and eax, -252645136
> #else
> not ebx
> and eax, ebx
> #endif
> or eax, esi
>
> #ifdef OPTIMISER_GONE_FISHING
> and edx, -252645136
> #else
> and edx, ebx
> pop ebx
> #endif
> or edx, ecx
> #ifndef OPTIMISER_GONE_FISHING // until here, quite good;
> bswap eax // the next 14 instructions but can
> bswap edx // be replaced by a two BSWAPs
> #else
> mov ecx, eax
> shr ecx, 8
> mov esi, edx
> shr esi, 8
> and esi, 16711935
> and ecx, 16711935
> shl eax, 8
> shl edx, 8
> and edx, -16711936
> or edx, esi
> and eax, -16711936
> or eax, ecx
> rol edx, 16
> rol eax, 16
> #endif
> pop esi
> ret
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20181217/17eccae2/attachment.html>
More information about the llvm-dev
mailing list