On Wed, Apr 27, 2016 at 10:24:21PM -0600, Jeff Law wrote:
> On 04/27/2016 02:20 AM, Dominik Vogt wrote:
> >The attached patch is a result of discussing an S/390 issue with
> >"and with complement" in some cases.
> >
> >  https://gcc.gnu.org/ml/gcc/2016-03/msg00163.html
> >  https://gcc.gnu.org/ml/gcc-patches/2016-04/msg01586.html
> >
> >Combine would merge a ZERO_EXTEND and a SET taking the known zero
> >bits into account, resulting in an AND.  Later on,
> >make_compound_operation() fails to replace that with a ZERO_EXTEND
> >which we get for free on S/390 but leaves the AND, eventually
> >resulting in two consecutive AND instructions.
> >
> >The current code in make_compound_operation() that detects
> >opportunities for ZERO_EXTEND does not work here because it does
> >not take the known zero bits into account:
> >
> >      /* If the constant is one less than a power of two, this might be
> >      representable by an extraction even if no shift is present.
> >      If it doesn't end up being a ZERO_EXTEND, we will ignore it unless
> >      we are in a COMPARE.  */
> >      else if ((i = exact_log2 (UINTVAL (XEXP (x, 1)) + 1)) >= 0)
> >     new_rtx = make_extraction (mode,
> >                            make_compound_operation (XEXP (x, 0),
> >                                                     next_code),
> >                            0, NULL_RTX, i, 1, 0, in_code == COMPARE);
> >
> >An attempt to use the zero bits in the above conditions resulted
> >in many situations that generated worse code, so the patch tries
> >to fix this in a more conservative way.  While the effect is
> >completely positive on S/390, this will very likely have
> >unforeseeable consequences on other targets.

> >     * combine.c (make_compound_operation): Take known zero bits into
> >     account when checking for possible zero_extend.
> I'd strongly recommend writing some tests for this.

This turns out to be quite difficult.  A small test function
effectively just returns the argument:

  unsigned long bar (unsigned long in) 
  { 
    if ((in & 1) == 0) 
      in = (in & ~(unsigned long)1); 
 
    return in; 
  }

However, Gcc does not notice that the AND is a no-op.  As far as I
understand, zero bit tracking is only done in "combine", so when
folding the assignment statement the information that the lowest
bit is zero is not available and therefore the no-op is not
detected?

(I've been trying to trigger the code from the patch with a
function bases on the above construct.)

Ciao

Dominik ^_^  ^_^

-- 

Dominik Vogt
IBM Germany

Reply via email to