Commit 6a813c96 by Dominik Vogt Committed by Andreas Krebbel

combine: Take known zero bits into account when checking extraction.

gcc/ChangeLog:

	* combine.c (make_compound_operation): Take known zero bits into
	account when checking for possible zero_extend.

gcc/testsuite/ChangeLog:

	* gcc.dg/zero_bits_compound-1.c: New test.
	* gcc.dg/zero_bits_compound-2.c: New test.

From-SVN: r236813
parent 4bc72f35
2016-05-27 Dominik Vogt <vogt@linux.vnet.ibm.com>
* combine.c (make_compound_operation): Take known zero bits into
account when checking for possible zero_extend.
2016-05-27 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/aarch64/aarch64.md (ashl<mode>3, SHORT modes):
......
......@@ -7988,6 +7988,34 @@ make_compound_operation (rtx x, enum rtx_code in_code)
next_code),
i, NULL_RTX, 1, 1, 0, 1);
/* If the one operand is a paradoxical subreg of a register or memory and
the constant (limited to the smaller mode) has only zero bits where
the sub expression has known zero bits, this can be expressed as
a zero_extend. */
else if (GET_CODE (XEXP (x, 0)) == SUBREG)
{
rtx sub;
sub = XEXP (XEXP (x, 0), 0);
machine_mode sub_mode = GET_MODE (sub);
if ((REG_P (sub) || MEM_P (sub))
&& GET_MODE_PRECISION (sub_mode) < mode_width)
{
unsigned HOST_WIDE_INT mode_mask = GET_MODE_MASK (sub_mode);
unsigned HOST_WIDE_INT mask;
/* original AND constant with all the known zero bits set */
mask = UINTVAL (XEXP (x, 1)) | (~nonzero_bits (sub, sub_mode));
if ((mask & mode_mask) == mode_mask)
{
new_rtx = make_compound_operation (sub, next_code);
new_rtx = make_extraction (mode, new_rtx, 0, 0,
GET_MODE_PRECISION (sub_mode),
1, 0, in_code == COMPARE);
}
}
}
break;
case LSHIFTRT:
......
2016-05-27 Dominik Vogt <vogt@linux.vnet.ibm.com>
* gcc.dg/zero_bits_compound-1.c: New test.
* gcc.dg/zero_bits_compound-2.c: New test.
2016-05-27 Ilya Enkovich <ilya.enkovich@intel.com>
PR middle-end/71279
......
/* Test whether an AND mask or'ed with the know zero bits that equals a mode
mask is a candidate for zero extendion. */
/* Note: This test requires that char, int and long have different sizes and the
target has a way to do 32 -> 64 bit zero extension other than AND. */
/* { dg-do compile { target x86_64-*-* s390*-*-* } } */
/* { dg-require-effective-target lp64 } */
/* { dg-options "-O3 -dP" } */
unsigned long foo (unsigned char c)
{
unsigned long l;
unsigned int i;
i = ((unsigned int)c) << 8;
i |= ((unsigned int)c) << 20;
asm volatile ("":::);
i = i & 0x0ff0ff00;
asm volatile ("":::);
l = (unsigned long)i;
return l;
}
unsigned long bar (unsigned char c)
{
unsigned long l;
unsigned int i;
i = ((unsigned int)c) << 8;
i |= ((unsigned int)c) << 20;
asm volatile ("":::);
i = i & 0x0ffffff0;
asm volatile ("":::);
l = (unsigned long)i;
return l;
}
/* Check that no pattern containing an AND expression was used. */
/* { dg-final { scan-assembler-not "\\(and:" } } */
/* Test whether an AND mask or'ed with the know zero bits that equals a mode
mask is a candidate for zero extendion. */
/* { dg-do compile { target x86_64-*-* s390*-*-* } } */
/* { dg-require-effective-target lp64 } */
/* { dg-options "-O3 -dP" } */
unsigned long foo (unsigned char c)
{
unsigned long l;
unsigned int i;
i = ((unsigned int)c) << 8;
i |= ((unsigned int)c) << 20;
asm volatile ("":::);
i = i & 0x0fe0fe00;
asm volatile ("":::);
l = (unsigned long)i;
return l;
}
unsigned long bar (unsigned char c)
{
unsigned long l;
unsigned int i;
i = ((unsigned int)c) << 8;
i |= ((unsigned int)c) << 20;
asm volatile ("":::);
i = i & 0x07f007f0;
asm volatile ("":::);
l = (unsigned long)i;
return l;
}
/* Check that an AND expression was used. */
/* { dg-final { scan-assembler-times "\\(and:" 2 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment