On 2019/6/27 11:48 PM, Jeff Law wrote:
On 6/27/19 12:11 AM, Li Jia He wrote:
Hi,

According to the optimizable case described by Qi Feng on
issue 88784, we can combine the cases into the following:

1. x >  y  &&  x != XXX_MIN  -->   x > y
2. x >  y  &&  x == XXX_MIN  -->   false
3. x <= y  &&  x == XXX_MIN  -->   x == XXX_MIN

4. x <  y  &&  x != XXX_MAX  -->   x < y
5. x <  y  &&  x == XXX_MAX  -->   false
6. x >= y  &&  x == XXX_MAX  -->   x == XXX_MAX

7. x >  y  ||  x != XXX_MIN  -->   x != XXX_MIN
8. x <= y  ||  x != XXX_MIN  -->   true
9. x <= y  ||  x == XXX_MIN  -->   x <= y

10. x <  y  ||  x != XXX_MAX  -->   x != UXXX_MAX
11. x >= y  ||  x != XXX_MAX  -->   true
12. x >= y  ||  x == XXX_MAX  -->   x >= y

Note: XXX_MIN represents the minimum value of type x.
       XXX_MAX represents the maximum value of type x.

Here we don't need to care about whether the operation is
signed or unsigned.  For example, in the below equation:

'x >  y  &&  x != XXX_MIN  -->   x > y'

If the x type is signed int and XXX_MIN is INT_MIN, we can
optimize it to 'x > y'.  However, if the type of x is unsigned
int and XXX_MIN is 0, we can still optimize it to 'x > y'.

The regression testing for the patch was done on GCC mainline on

     powerpc64le-unknown-linux-gnu (Power 9 LE)

with no regressions.  Is it OK for trunk ?

Thanks,
Lijia He

gcc/ChangeLog

2019-06-27  Li Jia He  <heli...@linux.ibm.com>
            Qi Feng  <ffen...@linux.ibm.com>

        PR middle-end/88784
        * gimple-fold.c (and_comparisons_contain_equal_operands): New function.
        (and_comparisons_1): Use and_comparisons_contain_equal_operands.
        (or_comparisons_contain_equal_operands): New function.
        (or_comparisons_1): Use or_comparisons_contain_equal_operands.
Would this be better done via match.pd?  ISTM this transformation would
be well suited for that framework.

Hi, Jeff

I did this because of the following test case:
`
_Bool comp(unsigned x, unsigned y)
{
  return x > y && x != 0;
}
`
The gimple file dumped on the power platform is:
`
comp (unsigned int x, unsigned int y)
{
  _Bool D.2837;
  int iftmp.0;

  if (x > y) goto <D.2841>; else goto <D.2839>;
  <D.2841>:
  if (x != 0) goto <D.2842>; else goto <D.2839>;
  <D.2842>:
  iftmp.0 = 1;
  goto <D.2840>;
  <D.2839>:
  iftmp.0 = 0;
  <D.2840>:
  D.2837 = (_Bool) iftmp.0;
  return D.2837;
}
`
However, the gimple file dumped on x86 is
`
comp (unsigned int x, unsigned int y)
{
  _Bool D.2837;

  _1 = x > y;
  _2 = x != 0;
  _3 = _1 & _2;
  _4 = (int) _3;
  D.2837 = (_Bool) _4;
  return D.2837;
}
`

The reason for the inconsistency between these two behaviors is param
logical-op-non-short-circuit.  If we add the pattern to the match.pd
file, we can only optimize the situation in which the statement is in
the same basic block (logical-op-non-short-circuit=1, x86).  But for
a cross-basic block (logical-op-non-short-circuit=0, power), match.pd
can't handle this situation.

Another reason is that I found out maybe_fold_and_comparisons and
maybe_fold_or_comparisons are not only called by ifcombine pass but
also by reassoc pass. Using this method can basically unify param
logical-op-non-short-circuit=0 or 1.

Thanks,
Lijia He


jeff


Reply via email to