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.

Reply via email to