aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd/arrayop.c
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2020-06-07 22:07:28 +0200
committerUros Bizjak <ubizjak@gmail.com>2020-06-07 22:09:49 +0200
commitf08995eefbf579acfe40f0204727d5ce388e3d0a (patch)
treeef2c088a1e449d8776e3721cef11cf1e0cc7690f /gcc/d/dmd/arrayop.c
parentfced594b313ddfb941913b2f59b10ce3514faaf6 (diff)
downloadgcc-f08995eefbf579acfe40f0204727d5ce388e3d0a.zip
gcc-f08995eefbf579acfe40f0204727d5ce388e3d0a.tar.gz
gcc-f08995eefbf579acfe40f0204727d5ce388e3d0a.tar.bz2
i386: Improve expansion of __builtin_parity
GCC currently hides the shift and xor reduction inside a backend specific UNSPEC PARITY, making it invisible to the RTL optimizers until very late during compilation. It is normally reasonable for the middle-end to maintain wider mode representations for as long as possible and split them later, but this only helps if the semantics are visible at the RTL-level (to combine and other passes), but UNSPECs are black boxes, so in this case splitting early (during RTL expansion) is a better strategy. It turns out that that popcount instruction on modern x86_64 processors has (almost) made the integer parity flag in the x86 ALU completely obsolete, especially as POPCOUNT's integer semantics are a much better fit to RTL. The one remaining case where these transistors are useful is where __builtin_parity is immediately tested by a conditional branch, and therefore the result is wanted in a flags register rather than as an integer. This case is captured by two peephole2 optimizations in the attached patch. 2020-06-07 Roger Sayle <roger@nextmovesoftware.com> gcc/ChangeLog: * config/i386/i386.md (paritydi2, paritysi2): Expand reduction via shift and xor to an USPEC PARITY matching a parityhi2_cmp. (paritydi2_cmp, paritysi2_cmp): Delete these define_insn_and_split. (parityhi2, parityqi2): New expanders. (parityhi2_cmp): Implement set parity flag with xorb insn. (parityqi2_cmp): Implement set parity flag with testb insn. New peephole2s to use these insns (UNSPEC PARITY) when appropriate. gcc/testsuite/ChangeLog: * gcc.target/i386/parity-3.c: New test. * gcc.target/i386/parity-4.c: Likewise. * gcc.target/i386/parity-5.c: Likewise. * gcc.target/i386/parity-6.c: Likewise. * gcc.target/i386/parity-7.c: Likewise. * gcc.target/i386/parity-8.c: Likewise. * gcc.target/i386/parity-9.c: Likewise.
Diffstat (limited to 'gcc/d/dmd/arrayop.c')
0 files changed, 0 insertions, 0 deletions