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