diff options
author | Pat Haugen <pthaugen@linux.ibm.com> | 2023-03-23 14:08:00 -0500 |
---|---|---|
committer | Pat Haugen <pthaugen@linux.ibm.com> | 2023-03-23 14:08:00 -0500 |
commit | f58cbbb7c90d8cfea87dc4490b575a368e1e2c82 (patch) | |
tree | 86f180c1449a40adf1a978716c5702bbf027adbd | |
parent | 80ed2a6471a39dd95192a334789fd63d5efd2e8a (diff) | |
download | gcc-f58cbbb7c90d8cfea87dc4490b575a368e1e2c82.zip gcc-f58cbbb7c90d8cfea87dc4490b575a368e1e2c82.tar.gz gcc-f58cbbb7c90d8cfea87dc4490b575a368e1e2c82.tar.bz2 |
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 (*mod<mode>3, umod<mode>3): Add
non-earlyclobber alternative.
gcc/testsuite/
* gcc.target/powerpc/mod-no_copy.c: New.
* gcc.target/powerpc/mod-peephole.c: New.
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 12 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/mod-no_copy.c | 16 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/powerpc/mod-peephole.c | 25 |
3 files changed, 47 insertions, 6 deletions
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 81bffb0..44f7dd5 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 "*mod<mode>3" - [(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<wd> %0,%1,%2" [(set_attr "type" "div") @@ -3447,9 +3447,9 @@ (define_insn "umod<mode>3" - [(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<wd> %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 0000000..c55e486 --- /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 0000000..7517fbc --- /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} } } */ |