[PATCH][GCC][ARM] Adjust costs so udiv is preferred over sdiv when both are valid. [Patch (2/2)]
Kyrill Tkachov
kyrylo.tkachov@foss.arm.com
Wed Jun 7 10:04:00 GMT 2017
On 02/05/17 16:37, Tamar Christina wrote:
> Hi All,
>
> This patch adjusts the cost model so that when both sdiv and udiv are possible
> it prefers udiv over sdiv. This was done by making sdiv slightly more expensive
> instead of making udiv cheaper to keep the baseline costs of a division the same
> as before.
>
> Similar to aarch64 this patch along with my other two related mid-end changes
> makes a big difference in division by constants.
>
> Given:
>
> int f2(int x)
> {
> return ((x * x) % 300) + ((x * x) / 300);
> }
>
> we now generate
>
> f2:
> mul r3, r0, r0
> mov r0, r3
> ldr r1, .L3
> umull r2, r3, r0, r1
> lsr r2, r3, #5
> add r3, r2, r2, lsl #2
> rsb r3, r3, r3, lsl #4
> sub r0, r0, r3, lsl #2
> add r0, r0, r2
> bx lr
>
> as opposed to
>
> f2:
> mul r3, r0, r0
> mov r0, r3
> ldr r3, .L4
> push {r4, r5}
> smull r4, r5, r0, r3
> asr r3, r0, #31
> rsb r3, r3, r5, asr #5
> add r2, r3, r3, lsl #2
> rsb r2, r2, r2, lsl #4
> sub r0, r0, r2, lsl #2
> add r0, r0, r3
> pop {r4, r5}
> bx lr
>
> Bootstrapped and reg tested on arm-none-eabi
> with no regressions.
>
> OK for trunk?
>
> Thanks,
> Tamar
>
>
> gcc/
> 2017-05-02 Tamar Christina <tamar.christina@arm.com>
>
> * config/arm/arm.c (arm_rtx_costs_internal): Make sdiv more expensive than udiv.
>
>
> gcc/testsuite/
> 2017-05-02 Tamar Christina <tamar.christina@arm.com>
>
> * gcc.target/arm/sdiv_costs_1.c: New.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index b24143e32e2f100000f3b150f7ed0df4fabb3cc8..ecc7688b1db6309a4dd694a8e254e64abe14d7e3 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -9258,6 +9258,8 @@ 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);
+
+ *cost += (code == DIV ? 1 : 0);
return false; /* All arguments must be in registers. */
We usually try to avoid adjusting the costs in units other than COSTS_N_INSNS.
Would adding COSTS_N_INSNS (1) here work?
If so, could you also add a comment here to describe why we're adjusting the cost.
case MOD:
@@ -9280,7 +9282,7 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code,
/* Fall-through. */
case UMOD:
- *cost = LIBCALL_COST (2);
+ *cost = LIBCALL_COST (2) + (code == MOD ? 1 : 0);
Same here.
Thanks,
Kyrill
More information about the Gcc-patches
mailing list