aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorWilco Dijkstra <wdijkstr@arm.com>2017-10-30 18:46:02 +0000
committerWilco Dijkstra <wilco@gcc.gnu.org>2017-10-30 18:46:02 +0000
commitb832b29f6578d3171e41d084b7a8432a24c5bf62 (patch)
treebc8021aa242ff8a5c91571f998c0664543be9467 /gcc
parent0d1cf53834bdcbe23c20c872036754c028caaa06 (diff)
downloadgcc-b832b29f6578d3171e41d084b7a8432a24c5bf62.zip
gcc-b832b29f6578d3171e41d084b7a8432a24c5bf62.tar.gz
gcc-b832b29f6578d3171e41d084b7a8432a24c5bf62.tar.bz2
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. (<shift>di3_neon): Likewise. From-SVN: r254237
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/arm/arm.c3
-rw-r--r--gcc/config/arm/arm.md54
-rw-r--r--gcc/config/arm/neon.md18
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 <wdijkstr@arm.com>
+
+ * 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.
+ (<shift>di3_neon): Likewise.
+
2017-10-30 Dominik Infuehr <dominik.infuehr@theobroma-systems.com>
* 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_<shift>di3_1bit (operands[0], operands[1]));
- else
- /* This clobbers CC (ASHIFTRT by register only). */
- arm_emit_coreregs_64bit_shift (<CODE>, operands[0], operands[1],
- operands[2], operands[3], operands[4]);
+ /* This clobbers CC (ASHIFTRT by register only). */
+ arm_emit_coreregs_64bit_shift (<CODE>, operands[0], operands[1],
+ operands[2], operands[3], operands[4]);
}
DONE;