Hello Roger and nice to hear from you after a loong time! > Alas there is a mismatch between RTL's definition of PARITY operation > which has an integer mode result, and the x86's parity flag. So when > Uros addressed PR target/44481 in 2010, by introducing UNSPEC PARITY, > we lost some of the optimization opportunities of his original patch. > https://gcc.gnu.org/legacy-ml/gcc-patches/2010-06/msg01259.html > The early splitting approach in this patch safely restores the 2007-2010 > optimization opportunities.
Yes, I agree that in this case it is better to start early with an expanded sequence. > 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. [...] > Alas I'm very out of practice contributing patches (but my paperwork should > still be valid), so if a friendly i386/x86_64 backend maintainer could take > care of things from here, that would be very much appreciated. I'll take care of the patch. There is a small fix needed (see below), so I'll re-bootstrap the patch and commit it after a successful regression test. 2020-06-05 Roger Sayle <ro...@nextmovesoftware.com> * 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. 2020-06-05 Roger Sayle <ro...@nextmovesoftware.com> * gcc.target/i386/parity-[3-9].c: New tests. So, OK for mainline with a small fix. +(define_insn "parityqi2_cmp" + [(set (reg:CC FLAGS_REG) + (unspec:CC [(match_operand:QI 0 "register_operand")] + UNSPEC_PARITY))] + "" + "test{b}\t%b0, %b0" + [(set_attr "mode" "QI")]) This is an instruction pattern, so it needs "q" register constraint. "q" is a superset of "Q", so there should be no problem converting HImode parityhi2_cmp to parityqi2_cmp. Also, there is no need for the "b" operand modifier, since the operand is already in QImode. Thanks, Uros.