From cc5b8f3d568e95ce74e03d8d87ada71117a6c106 Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Tue, 2 May 2017 15:19:07 +0000 Subject: [PATCH] simplify-rtx.c (simplify_binary_operation_1): Add LSHIFTRT case. gcc/ 2017-04-27 Tamar Christina * simplify-rtx.c (simplify_binary_operation_1): Add LSHIFTRT case. gcc/testsuite/ 2017-04-27 Tamar Christina * gcc.dg/lsr-div1.c: New testcase. From-SVN: r247504 --- gcc/ChangeLog | 4 +++ gcc/simplify-rtx.c | 12 ++++--- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/lsr-div1.c | 57 +++++++++++++++++++++++++++++++++ 4 files changed, 72 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/lsr-div1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a3cb1573366..00f21e71c5d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2017-04-27 Tamar Christina + + * simplify-rtx.c (simplify_binary_operation_1): Add LSHIFTRT case. + 2017-05-02 Martin Liska PR lto/77954. diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index b4534197317..ac85a564b10 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -3345,19 +3345,21 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, && UINTVAL (trueop0) == GET_MODE_MASK (mode) && ! side_effects_p (op1)) return op0; + + canonicalize_shift: /* Given: scalar modes M1, M2 scalar constants c1, c2 size (M2) > size (M1) c1 == size (M2) - size (M1) optimize: - (ashiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int )) + ([a|l]shiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2) (const_int )) ) (const_int )) to: - (subreg:M1 (ashiftrt:M2 (reg:M2) (const_int )) + (subreg:M1 ([a|l]shiftrt:M2 (reg:M2) (const_int )) ). */ - if (code == ASHIFTRT + if ((code == ASHIFTRT || code == LSHIFTRT) && !VECTOR_MODE_P (mode) && SUBREG_P (op0) && CONST_INT_P (op1) @@ -3374,13 +3376,13 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, rtx tmp = GEN_INT (INTVAL (XEXP (SUBREG_REG (op0), 1)) + INTVAL (op1)); machine_mode inner_mode = GET_MODE (SUBREG_REG (op0)); - tmp = simplify_gen_binary (ASHIFTRT, + tmp = simplify_gen_binary (code, GET_MODE (SUBREG_REG (op0)), XEXP (SUBREG_REG (op0), 0), tmp); return lowpart_subreg (mode, tmp, inner_mode); } - canonicalize_shift: + if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1)) { val = INTVAL (op1) & (GET_MODE_PRECISION (mode) - 1); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d47aa91110f..759a6034898 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-04-27 Tamar Christina + + * gcc.dg/lsr-div1.c: New testcase. + 2017-05-02 Sebastian Peryt * gcc.target/i386/avx512f-vaddsd-1.c (_mm_mask_add_sd) diff --git a/gcc/testsuite/gcc.dg/lsr-div1.c b/gcc/testsuite/gcc.dg/lsr-div1.c new file mode 100644 index 00000000000..962054d34d9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lsr-div1.c @@ -0,0 +1,57 @@ +/* Test division by const int generates only one shift. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fdump-rtl-combine-all" } */ +/* { dg-options "-O2 -fdump-rtl-combine-all -mtune=cortex-a53" { target aarch64*-*-* } } */ +/* { dg-require-effective-target int32plus } */ + +extern void abort (void); + +#define NOINLINE __attribute__((noinline)) + +static NOINLINE int +f1 (unsigned int n) +{ + return n % 0x33; +} + +static NOINLINE int +f2 (unsigned int n) +{ + return n % 0x12; +} + +int +main () +{ + int a = 0xaaaaaaaa; + int b = 0x55555555; + int c; + c = f1 (a); + if (c != 0x11) + abort (); + c = f1 (b); + if (c != 0x22) + abort (); + c = f2 (a); + if (c != 0xE) + abort (); + c = f2 (b); + if (c != 0x7) + abort (); + return 0; +} + +/* Following replacement pattern of intger division by constant, GCC is expected + to generate UMULL and (x)SHIFTRT. This test checks that considering division + by const 0x33, gcc generates a single LSHIFTRT by 37, instead of + two - LSHIFTRT by 32 and LSHIFTRT by 5. */ + +/* { dg-final { scan-rtl-dump "\\(set \\(subreg:DI \\(reg:SI" "combine" { target aarch64*-*-* } } } */ +/* { dg-final { scan-rtl-dump "\\(lshiftrt:DI \\(reg:DI" "combine" { target aarch64*-*-* } } } */ +/* { dg-final { scan-rtl-dump "\\(const_int 37 " "combine" { target aarch64*-*-* } } } */ + +/* Similarly, considering division by const 0x12, gcc generates a + single LSHIFTRT by 34, instead of two - LSHIFTRT by 32 and LSHIFTRT by 2. */ + +/* { dg-final { scan-rtl-dump "\\(const_int 34 " "combine" { target aarch64*-*-* } } } */ + -- 2.30.2