From b832b29f6578d3171e41d084b7a8432a24c5bf62 Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Mon, 30 Oct 2017 18:46:02 +0000 Subject: [PATCH] Remove DImode expansions for 1-bit shifts A left shift of 1 can always be done using an add, so slightly adjust rtx cost for DImode left shift by 1 so that adddi3 is preferred in all cases, and the arm_ashldi3_1bit is redundant. DImode right shifts of 1 are rarely used (6 in total in the GCC binary), so there is little benefit of the arm_ashrdi3_1bit and arm_lshrdi3_1bit patterns. The generated code is better and faster without these shifts as it allows early expansion, optimization and better register allocation. gcc/ * config/arm/arm.md (ashldi3): Remove shift by 1 expansion. (arm_ashldi3_1bit): Remove pattern. (ashrdi3): Remove shift by 1 expansion. (arm_ashrdi3_1bit): Remove pattern. (lshrdi3): Remove shift by 1 expansion. (arm_lshrdi3_1bit): Remove pattern. * config/arm/arm.c (arm_rtx_costs_internal): Slightly increase cost of ashldi3 by 1. * config/arm/neon.md (ashldi3_neon): Remove shift by 1 expansion. (di3_neon): Likewise. From-SVN: r254237 --- gcc/ChangeLog | 13 ++++++++++++ gcc/config/arm/arm.c | 3 +++ gcc/config/arm/arm.md | 54 -------------------------------------------------- gcc/config/arm/neon.md | 18 +++++------------ 4 files changed, 21 insertions(+), 67 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bfd68e9..a32a5ce 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,16 @@ +2017-10-30 Wilco Dijkstra + + * config/arm/arm.md (ashldi3): Remove shift by 1 expansion. + (arm_ashldi3_1bit): Remove pattern. + (ashrdi3): Remove shift by 1 expansion. + (arm_ashrdi3_1bit): Remove pattern. + (lshrdi3): Remove shift by 1 expansion. + (arm_lshrdi3_1bit): Remove pattern. + * config/arm/arm.c (arm_rtx_costs_internal): Slightly increase + cost of ashldi3 by 1. + * config/arm/neon.md (ashldi3_neon): Remove shift by 1 expansion. + (di3_neon): Likewise. + 2017-10-30 Dominik Infuehr * config/aarch64/aarch64-simd.md (*aarch64_simd_mov): Rename diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 22e1693..813d29af 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -9430,6 +9430,9 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, + rtx_cost (XEXP (x, 0), mode, code, 0, speed_p)); if (speed_p) *cost += 2 * extra_cost->alu.shift; + /* Slightly disparage left shift by 1 at so we prefer adddi3. */ + if (code == ASHIFT && XEXP (x, 1) == CONST1_RTX (SImode)) + *cost += 1; return true; } else if (mode == SImode) diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index f241f9d..ddb9d8f 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -4059,12 +4059,6 @@ { rtx scratch1, scratch2; - if (operands[2] == CONST1_RTX (SImode)) - { - emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1])); - DONE; - } - /* Ideally we should use iwmmxt here if we could know that operands[1] ends up already living in an iwmmxt register. Otherwise it's cheaper to have the alternate code being generated than moving @@ -4081,18 +4075,6 @@ " ) -(define_insn "arm_ashldi3_1bit" - [(set (match_operand:DI 0 "s_register_operand" "=r,&r") - (ashift:DI (match_operand:DI 1 "s_register_operand" "0,r") - (const_int 1))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "movs\\t%Q0, %Q1, asl #1\;adc\\t%R0, %R1, %R1" - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - (define_expand "ashlsi3" [(set (match_operand:SI 0 "s_register_operand" "") (ashift:SI (match_operand:SI 1 "s_register_operand" "") @@ -4128,12 +4110,6 @@ { rtx scratch1, scratch2; - if (operands[2] == CONST1_RTX (SImode)) - { - emit_insn (gen_arm_ashrdi3_1bit (operands[0], operands[1])); - DONE; - } - /* Ideally we should use iwmmxt here if we could know that operands[1] ends up already living in an iwmmxt register. Otherwise it's cheaper to have the alternate code being generated than moving @@ -4150,18 +4126,6 @@ " ) -(define_insn "arm_ashrdi3_1bit" - [(set (match_operand:DI 0 "s_register_operand" "=r,&r") - (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r") - (const_int 1))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "movs\\t%R0, %R1, asr #1\;mov\\t%Q0, %Q1, rrx" - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - (define_expand "ashrsi3" [(set (match_operand:SI 0 "s_register_operand" "") (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "") @@ -4194,12 +4158,6 @@ { rtx scratch1, scratch2; - if (operands[2] == CONST1_RTX (SImode)) - { - emit_insn (gen_arm_lshrdi3_1bit (operands[0], operands[1])); - DONE; - } - /* Ideally we should use iwmmxt here if we could know that operands[1] ends up already living in an iwmmxt register. Otherwise it's cheaper to have the alternate code being generated than moving @@ -4216,18 +4174,6 @@ " ) -(define_insn "arm_lshrdi3_1bit" - [(set (match_operand:DI 0 "s_register_operand" "=r,&r") - (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "0,r") - (const_int 1))) - (clobber (reg:CC CC_REGNUM))] - "TARGET_32BIT" - "movs\\t%R0, %R1, lsr #1\;mov\\t%Q0, %Q1, rrx" - [(set_attr "conds" "clob") - (set_attr "length" "8") - (set_attr "type" "multiple")] -) - (define_expand "lshrsi3" [(set (match_operand:SI 0 "s_register_operand" "") (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "") diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md index e715a5c..4452778 100644 --- a/gcc/config/arm/neon.md +++ b/gcc/config/arm/neon.md @@ -1221,12 +1221,8 @@ gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[1]) || REGNO (operands[0]) == REGNO (operands[1])); - if (operands[2] == CONST1_RTX (SImode)) - /* This clobbers CC. */ - emit_insn (gen_arm_ashldi3_1bit (operands[0], operands[1])); - else - arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1], - operands[2], operands[3], operands[4]); + arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1], + operands[2], operands[3], operands[4]); } DONE; }" @@ -1325,13 +1321,9 @@ gcc_assert (!reg_overlap_mentioned_p (operands[0], operands[1]) || REGNO (operands[0]) == REGNO (operands[1])); - if (operands[2] == CONST1_RTX (SImode)) - /* This clobbers CC. */ - emit_insn (gen_arm_di3_1bit (operands[0], operands[1])); - else - /* This clobbers CC (ASHIFTRT by register only). */ - arm_emit_coreregs_64bit_shift (, operands[0], operands[1], - operands[2], operands[3], operands[4]); + /* This clobbers CC (ASHIFTRT by register only). */ + arm_emit_coreregs_64bit_shift (, operands[0], operands[1], + operands[2], operands[3], operands[4]); } DONE; -- 2.7.4