middle-end: Support recognition of three-way max/min.
authorTamar Christina <tamar.christina@arm.com>
Wed, 3 Aug 2022 15:00:39 +0000 (16:00 +0100)
committerTamar Christina <tamar.christina@arm.com>
Wed, 3 Aug 2022 15:00:39 +0000 (16:00 +0100)
commit9bb19e143cfe8863e2e79d4176b5d7e997b08c5f
treefe1317a6184004d57927af006a7ea324529157e3
parentb6df113247b9f3f7c3db0e65c481dad5bcfddfb4
middle-end: Support recognition of three-way max/min.

This patch adds support for three-way min/max recognition in phi-opts.

Concretely for e.g.

#include <stdint.h>

uint8_t three_min (uint8_t xc, uint8_t xm, uint8_t xy) {
uint8_t  xk;
    if (xc < xm) {
        xk = (uint8_t) (xc < xy ? xc : xy);
    } else {
        xk = (uint8_t) (xm < xy ? xm : xy);
    }
    return xk;
}

we generate:

  <bb 2> [local count: 1073741824]:
  _5 = MIN_EXPR <xc_1(D), xy_3(D)>;
  _7 = MIN_EXPR <xm_2(D), _5>;
  return _7;

instead of

  <bb 2>:
  if (xc_2(D) < xm_3(D))
    goto <bb 3>;
  else
    goto <bb 4>;

  <bb 3>:
  xk_5 = MIN_EXPR <xc_2(D), xy_4(D)>;
  goto <bb 5>;

  <bb 4>:
  xk_6 = MIN_EXPR <xm_3(D), xy_4(D)>;

  <bb 5>:
  # xk_1 = PHI <xk_5(3), xk_6(4)>
  return xk_1;

The same function also immediately deals with turning a minimization problem
into a maximization one if the results are inverted.  We do this here since
doing it in match.pd would end up changing the shape of the BBs and adding
additional instructions which would prevent various optimizations from working.

gcc/ChangeLog:

* tree-ssa-phiopt.cc (minmax_replacement): Optionally search for the phi
sequence of a three-way conditional.
(replace_phi_edge_with_variable): Support diamonds.
(tree_ssa_phiopt_worker): Detect diamond phi structure for three-way
min/max.
(strip_bit_not, invert_minmax_code): New.

gcc/testsuite/ChangeLog:

* gcc.dg/tree-ssa/split-path-1.c: Disable phi-opts so we don't optimize
code away.
* gcc.dg/tree-ssa/minmax-10.c: New test.
* gcc.dg/tree-ssa/minmax-11.c: New test.
* gcc.dg/tree-ssa/minmax-12.c: New test.
* gcc.dg/tree-ssa/minmax-13.c: New test.
* gcc.dg/tree-ssa/minmax-14.c: New test.
* gcc.dg/tree-ssa/minmax-15.c: New test.
* gcc.dg/tree-ssa/minmax-16.c: New test.
* gcc.dg/tree-ssa/minmax-3.c: New test.
* gcc.dg/tree-ssa/minmax-4.c: New test.
* gcc.dg/tree-ssa/minmax-5.c: New test.
* gcc.dg/tree-ssa/minmax-6.c: New test.
* gcc.dg/tree-ssa/minmax-7.c: New test.
* gcc.dg/tree-ssa/minmax-8.c: New test.
* gcc.dg/tree-ssa/minmax-9.c: New test.
16 files changed:
gcc/testsuite/gcc.dg/tree-ssa/minmax-10.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-11.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-12.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-13.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-14.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-15.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-16.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-5.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-6.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-7.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-8.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/minmax-9.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/split-path-1.c
gcc/tree-ssa-phiopt.cc