This patch resolves PR target/43892 (suboptimal add with carry) by
adding four new define_insn_and_split to the rs6000 backend, that all
recognize pairs of instructions where the first instruction sets the
carry flag and the second one consumes it.  It also adds a commutative
variant of add<mode>3_carry_in_0 (aka "addze") to catch cases, not
caught by recog's insn canonicalization, where CA_REG appears first.

For the add32carry function in the original PR:

unsigned int add32carry(unsigned int sum, unsigned int x)
{
  unsigned int z = sum + x;
  if (sum + x < x)
    z++;
  return z;
}

previously "-O2 -m32" would generate:

add32carry:
        add 3,3,4
        subfc 4,4,3
        subfe 9,9,9
        subf 3,9,3
        blr

with this patch we now generate:

add32carry:
        addc 3,3,4
        addze 3,3
        blr

And for the related examples in the new test case,

unsigned long add_leu(unsigned long a, unsigned long b, unsigned long c) {
  return a + (b <= c);
}

unsigned long add_geu(unsigned long a, unsigned long b, unsigned long c) {
  return a + (b >= c);
}

On powerpc64 with -O2 we'd previously generate:

add_leu:
        subfc 4,4,5
        subfe 9,9,9
        addi 9,9,1
        add 3,9,3
        blr
add_geu:
        subfc 5,5,4
        subfe 9,9,9
        addi 9,9,1
        add 3,9,3
        blr

but with this patch we now generate:

add_leu:
        subfc 4,4,5
        addze 3,3
        blr
add_geu:
        subfc 5,5,4
        addze 3,3
        blr

This patch has been tested on powerpc64-unknown-linux-gnu (many thanks
to gcc203.fsffrance.org on the GCC compile farm) with a make bootstrap
and make -k check with now new failures.

Ok for mainline?


2021-12-02  Roger Sayle  <ro...@nextmovesoftware.com>

gcc/ChangeLog
        PR target/43892
        * config/rs6000/rs6000.md (*add<mode>3_carry_in_0_2): New
        define_insn to recognize commutative form of add<mode>3_carry_in_0.
        (*add<mode>3_geu, *add<mode>3_leu, *subf<mode>3_carry_in_xx_subf,
        *add<mode>3_carry_in_addc): New define_insn_and_split patterns.

gcc/testsuite/ChangeLog
        PR target/43892
        * gcc.target/powerpc/addcmp.c: New test case.
        * gcc.target/powerpc/pr43892.c: New test case.


Many thanks in advance.
Roger
--


Reply via email to