From 96023bbaff939ca5fe957688a940f045201c55c1 Mon Sep 17 00:00:00 2001 From: Alex Velenko Date: Wed, 5 Nov 2014 11:22:28 +0000 Subject: [PATCH] simplify-rtx.c (simplify_binary_operation_1): Div check added. 2014-11-05 Alex Velenko gcc/ * simplify-rtx.c (simplify_binary_operation_1): Div check added. * rtl.h (SUBREG_P): New macro added. gcc/testsuite/ * gcc.dg/asr-div1.c: New testcase. From-SVN: r217118 --- gcc/ChangeLog | 5 +++ gcc/rtl.h | 3 ++ gcc/simplify-rtx.c | 38 ++++++++++++++++++++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/asr_div1.c | 56 +++++++++++++++++++++++++++++++++ 5 files changed, 106 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/asr_div1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 47bc8269f55..a9b456501c5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2014-11-05 Alex Velenko + + * simplify-rtx.c (simplify_binary_operation_1): Div check added. + * rtl.h (SUBREG_P): New macro added. + 2014-11-05 Tejas Belagod * config/aarch64/aarch64-builtins.c diff --git a/gcc/rtl.h b/gcc/rtl.h index fec9658ec29..09d20e2b544 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -789,6 +789,9 @@ struct GTY(()) rtvec_def { /* Predicate yielding nonzero iff X is a data for a jump table. */ #define JUMP_TABLE_DATA_P(INSN) (GET_CODE (INSN) == JUMP_TABLE_DATA) +/* Predicate yielding nonzero iff RTX is a subreg. */ +#define SUBREG_P(RTX) (GET_CODE (RTX) == SUBREG) + template <> template <> inline bool diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 1e4ba2369d5..8094c7584ac 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -3104,6 +3104,44 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, && UINTVAL (trueop0) == GET_MODE_MASK (mode) && ! side_effects_p (op1)) return op0; + /* 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 )) + ) + (const_int )) + to: + (subreg:M1 (ashiftrt:M2 (reg:M2) + (const_int )) + ). */ + if (!VECTOR_MODE_P (mode) + && SUBREG_P (op0) + && CONST_INT_P (op1) + && (GET_CODE (SUBREG_REG (op0)) == LSHIFTRT) + && !VECTOR_MODE_P (GET_MODE (SUBREG_REG (op0))) + && CONST_INT_P (XEXP (SUBREG_REG (op0), 1)) + && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) + > GET_MODE_BITSIZE (mode)) + && (INTVAL (XEXP (SUBREG_REG (op0), 1)) + == (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0))) + - GET_MODE_BITSIZE (mode))) + && subreg_lowpart_p (op0)) + { + 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, + GET_MODE (SUBREG_REG (op0)), + XEXP (SUBREG_REG (op0), 0), + tmp); + return simplify_gen_subreg (mode, tmp, inner_mode, + subreg_lowpart_offset (mode, + inner_mode)); + } canonicalize_shift: if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1)) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e10e99904b6..6e956b403a3 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2014-11-05 Alex Velenko + + * gcc.dg/asr-div1.c: New testcase. + 2014-11-04 Dominik Vogt * go.test/go-test.exp (go-set-goarch): Enable tests on s390[x]. diff --git a/gcc/testsuite/gcc.dg/asr_div1.c b/gcc/testsuite/gcc.dg/asr_div1.c new file mode 100644 index 00000000000..61430ca6a98 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asr_div1.c @@ -0,0 +1,56 @@ +/* Test division by const int generates only one shift. */ +/* { dg-do run } */ +/* { dg-options "-O2 -fdump-rtl-combine-all" } */ + +extern void abort (void); + +#define NOINLINE __attribute__((noinline)) + +static NOINLINE int +f1 (int n) +{ + return n / 33; +} + +static NOINLINE int +f2 (int n) +{ + return n / 77; +} + +int +main () +{ + int a = 0xaaaaaaaa; + int b = 0x55555555; + int c; + c = f1 (a); + if (c != 0xfd6a052c) + abort (); + c = f1 (b); + if (c != 0x295FAD4) + abort (); + c = f2 (a); + if (c != 0xfee44b5c) + abort (); + c = f2 (b); + if (c != 0x11bb4a4) + abort (); + return 0; +} + +/* Following replacement pattern of intger division by constant, GCC is expected + to generate MULT and (x)SHIFTRT. This test checks that considering division + by const 33, gcc generates a single ASHIFTRT by 35, instead of two - LSHIFTRT + by 32 and ASHIFTRT by 3. */ + +/* { dg-final { scan-rtl-dump "\\(set \\(subreg:DI \\(reg:SI" "combine" { target aarch64*-*-* } } } */ +/* { dg-final { scan-rtl-dump "\\(ashiftrt:DI \\(reg:DI" "combine" { target aarch64*-*-* } } } */ +/* { dg-final { scan-rtl-dump "\\(const_int 35 " "combine" { target aarch64*-*-* } } } */ + +/* Similarly, considering division by const 77, gcc generates a single ASHIFTRT + by 36, instead of two - LSHIFTRT by 32 and ASHIFTRT by 4. */ + +/* { dg-final { scan-rtl-dump "\\(const_int 36 " "combine" { target aarch64*-*-* } } } */ + +/* { dg-final { cleanup-rtl-dump "combine" } } */ -- 2.30.2