Closed Quuxplusone closed 3 years ago
Bugzilla Link | PR1983 |
Status | RESOLVED FIXED |
Importance | P enhancement |
Reported by | Eli Friedman (efriedma@quicinc.com) |
Reported on | 2008-02-04 22:30:54 -0800 |
Last modified on | 2020-10-10 12:12:53 -0700 |
Version | trunk |
Hardware | PC Linux |
CC | baldrick@free.fr, craig.topper@gmail.com, gonzalo.gadeschi@gmail.com, i@maskray.me, llvm-bugs@lists.llvm.org, llvm-dev@redking.me.uk, spatel+llvm@rotateright.com, stoklund@2pi.dk |
Fixed by commit(s) | |
Attachments | |
Blocks | |
Blocked by | |
See also | PR46954 |
llvm-gcc 2.2 does support __builtin_parity: it turns it into popcnt(x)&1 at the LLVM level, which is a reasonable thing to canonicalize it into. I don't know if there are any real-world uses of parity.
FWIW, the code we're generating for __builtin_parity on x86 is truly awful. We
should generate the optimized x86 code from Eli's suggestion, or, if not that,
a call to __paritysi2 and friends.
It would be good to have the target-independent expander turn parity into
something like this:
int parity(unsigned x) {
x ^= x >> 1;
x ^= x >> 2;
return ((x & 0x11111111) * 0x88888888) >> 31;
}
or equivalent, which compiles into relatively decent code. Right now on x86 we
get this, which is very awful:
_par2:
pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax
movl %eax, %ecx
andl $1431655765, %ecx
shrl %eax
andl $1431655765, %eax
addl %eax, %ecx
movl %ecx, %eax
andl $858993459, %eax
shrl $2, %ecx
andl $858993459, %ecx
addl %ecx, %eax
movl %eax, %ecx
andl $252645135, %ecx
shrl $4, %eax
andl $252645135, %eax
addl %eax, %ecx
movl %ecx, %eax
andl $16711935, %eax
shrl $8, %ecx
andl $16711935, %ecx
addl %ecx, %eax
movl %eax, %ecx
shrl $16, %ecx
andl $65535, %eax
addl %ecx, %eax
andl $1, %eax
popl %ebp
ret
The parity function is useful when working with polynomials and vector spaces over GF(2).
This comes up in communication theory (scramblers and error correcting codes) as well as cryptography (mostly older military ciphers, but also A5/1 used in current GSM systems and E0 used in Bluetooth).
I suppose the CRC is the only thing that escaped the world of telecom.
Any improvements on this or any chance of providing a __builtin_parity
intrinsic just like GCC does?
Current codegen on x86:
https://godbolt.org/z/j8Ga63
mov ecx, edi
shr ecx, 16
xor ecx, edi
xor eax, eax
xor cl, ch
setnp al
Or:
popcnt eax, edi
and eax, 1
It's been 12+ years since popcnt was added to mainstream x86 (Nehalem,
Barcelona) - as old as this bug. :)
Either way, I think we're optimal on x86 now. Resolve as fixed?