From 6a813c9659aec29ba18173f5d070c846a0919d60 Mon Sep 17 00:00:00 2001 From: Dominik Vogt Date: Fri, 27 May 2016 11:38:59 +0000 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++ gcc/combine.c | 28 ++++++++++++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.dg/zero_bits_compound-1.c | 42 +++++++++++++++++++++ gcc/testsuite/gcc.dg/zero_bits_compound-2.c | 39 +++++++++++++++++++ 5 files changed, 119 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/zero_bits_compound-1.c create mode 100644 gcc/testsuite/gcc.dg/zero_bits_compound-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2d59cb5032b..59aa6d1f09a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2016-05-27 Dominik Vogt + + * combine.c (make_compound_operation): Take known zero bits into + account when checking for possible zero_extend. + 2016-05-27 Kyrylo Tkachov * config/aarch64/aarch64.md (ashl3, SHORT modes): diff --git a/gcc/combine.c b/gcc/combine.c index cd864ccb0d4..4db11b03df1 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a9593257eba..c209d98a547 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2016-05-27 Dominik Vogt + + * gcc.dg/zero_bits_compound-1.c: New test. + * gcc.dg/zero_bits_compound-2.c: New test. + 2016-05-27 Ilya Enkovich PR middle-end/71279 diff --git a/gcc/testsuite/gcc.dg/zero_bits_compound-1.c b/gcc/testsuite/gcc.dg/zero_bits_compound-1.c new file mode 100644 index 00000000000..d78dc43d0a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/zero_bits_compound-1.c @@ -0,0 +1,42 @@ +/* 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:" } } */ diff --git a/gcc/testsuite/gcc.dg/zero_bits_compound-2.c b/gcc/testsuite/gcc.dg/zero_bits_compound-2.c new file mode 100644 index 00000000000..80fd363d955 --- /dev/null +++ b/gcc/testsuite/gcc.dg/zero_bits_compound-2.c @@ -0,0 +1,39 @@ +/* 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 } } */ -- 2.30.2