From 37b68a4389bd452e9b5aa03870f6b81e4f26b71c Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Fri, 9 Jun 2017 13:22:39 +0000 Subject: [PATCH] arm.c (arm_rtx_costs_internal): Make sdiv more expensive than udiv. 2017-06-09 Tamar Christina * config/arm/arm.c (arm_rtx_costs_internal): Make sdiv more expensive than udiv. gcc/testsuite/ 2017-06-09 Tamar Christina * gcc.target/arm/sdiv_costs_1.c: New. From-SVN: r249062 --- gcc/ChangeLog | 4 +++ gcc/config/arm/arm.c | 8 ++++- gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.target/arm/sdiv_costs_1.c | 38 +++++++++++++++++++++ 4 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/arm/sdiv_costs_1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c61cba39f95..d4d2c11617c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2017-06-09 Tamar Christina + + * config/arm/arm.c (arm_rtx_costs_internal): Make sdiv more expensive than udiv. + 2017-06-09 Tom de Vries PR target/80855 diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 2604102c202..259597d8890 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -9315,6 +9315,10 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, *cost += COSTS_N_INSNS (speed_p ? extra_cost->mult[0].idiv : 0); else *cost = LIBCALL_COST (2); + + /* Make the cost of sdiv more expensive so when both sdiv and udiv are + possible udiv is prefered. */ + *cost += (code == DIV ? COSTS_N_INSNS (1) : 0); return false; /* All arguments must be in registers. */ case MOD: @@ -9337,7 +9341,9 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code, /* Fall-through. */ case UMOD: - *cost = LIBCALL_COST (2); + /* Make the cost of sdiv more expensive so when both sdiv and udiv are + possible udiv is prefered. */ + *cost = LIBCALL_COST (2) + (code == MOD ? COSTS_N_INSNS (1) : 0); return false; /* All arguments must be in registers. */ case ROTATE: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 431e2e8368f..01f2d1842ba 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2017-06-09 Tamar Christina + + * gcc.target/arm/sdiv_costs_1.c: New. + 2017-06-09 Tom de Vries PR target/80855 diff --git a/gcc/testsuite/gcc.target/arm/sdiv_costs_1.c b/gcc/testsuite/gcc.target/arm/sdiv_costs_1.c new file mode 100644 index 00000000000..76086ab9ce2 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/sdiv_costs_1.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=armv8-a" } */ + +/* Both sdiv and udiv can be used here, so prefer udiv. */ +int f1 (unsigned char *p) +{ + return 100 / p[1]; +} + +int f2 (unsigned char *p, unsigned short x) +{ + return x / p[0]; +} + +int f3 (unsigned char *p, int x) +{ + x &= 0x7fffffff; + return x / p[0]; +} + +int f5 (unsigned char *p, unsigned short x) +{ + return x % p[0]; +} + +/* This should only generate signed divisions. */ +int f4 (unsigned char *p) +{ + return -100 / p[1]; +} + +int f6 (unsigned char *p, short x) +{ + return x % p[0]; +} + +/* { dg-final { scan-assembler-times "udiv\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" 4 } } */ +/* { dg-final { scan-assembler-times "sdiv\tr\[0-9\]+, r\[0-9\]+, r\[0-9\]+" 2 } } */ -- 2.30.2