From: Pat Haugen Date: Thu, 23 Mar 2023 19:08:00 +0000 (-0500) Subject: Don't force target of modulo into a distinct register. X-Git-Tag: basepoints/gcc-14~370 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f58cbbb7c90d8cfea87dc4490b575a368e1e2c82;p=thirdparty%2Fgcc.git Don't force target of modulo into a distinct register. The define_insns for the modulo operation currently force the target register to a distinct reg in preparation for a possible future peephole combining div/mod. But this can lead to cases of a needless copy being inserted. Fixed with the following patch. gcc/ * config/rs6000/rs6000.md (*mod3, umod3): Add non-earlyclobber alternative. gcc/testsuite/ * gcc.target/powerpc/mod-no_copy.c: New. * gcc.target/powerpc/mod-peephole.c: New. --- diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 81bffb04ceb0..44f7dd509cb4 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -3437,9 +3437,9 @@ ;; In order to enable using a peephole2 for combining div/mod to eliminate the ;; mod, prefer putting the result of mod into a different register (define_insn "*mod3" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") - (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "gpc_reg_operand" "r")))] + [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r,r") + (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:GPR 2 "gpc_reg_operand" "r,r")))] "TARGET_MODULO" "mods %0,%1,%2" [(set_attr "type" "div") @@ -3447,9 +3447,9 @@ (define_insn "umod3" - [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") - (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") - (match_operand:GPR 2 "gpc_reg_operand" "r")))] + [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r,r") + (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") + (match_operand:GPR 2 "gpc_reg_operand" "r,r")))] "TARGET_MODULO" "modu %0,%1,%2" [(set_attr "type" "div") diff --git a/gcc/testsuite/gcc.target/powerpc/mod-no_copy.c b/gcc/testsuite/gcc.target/powerpc/mod-no_copy.c new file mode 100644 index 000000000000..c55e486ee9b9 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/mod-no_copy.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=power9 -O2" } */ + +/* Verify r3 is used as source and target, no copy inserted. */ + +long foo (long a, long b) +{ + return (a % b); +} + +unsigned long foo2 (unsigned long a, unsigned long b) +{ + return (a % b); +} + +/* { dg-final { scan-assembler-not {\mmr\M} } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/mod-peephole.c b/gcc/testsuite/gcc.target/powerpc/mod-peephole.c new file mode 100644 index 000000000000..7517fbc397c9 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/mod-peephole.c @@ -0,0 +1,25 @@ +/* { dg-do compile } */ +/* { dg-options "-mdejagnu-cpu=power9 -O2" } */ + +/* Verify peephole fires to combine div/mod using same opnds. */ + +long foo (long a, long b) +{ + long x, y; + + x = a / b; + y = a % b; + return (x + y); +} + +unsigned long foo2 (unsigned long a, unsigned long b) +{ + unsigned long x, y; + + x = a / b; + y = a % b; + return (x + y); +} + +/* { dg-final { scan-assembler-not {\mmodsd\M} } } */ +/* { dg-final { scan-assembler-not {\mmodud\M} } } */