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. */ 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); return false; /* All arguments must be in registers. */ case ROTATE: 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 0000000000000000000000000000000000000000..76086ab9ce28fceb37a4e8a615a38923fa7b985a --- /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 } } */