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