rs6000: Expand fmod and remainder when built with fast-math [PR97142]

fmod/fmodf and remainder/remainderf could be expanded instead of library
call when fast-math build, which is much faster.

fmodf:
     fdivs   f0,f1,f2
     friz    f0,f0
     fnmsubs f1,f2,f0,f1

remainderf:
     fdivs   f0,f1,f2
     frin    f0,f0
     fnmsubs f1,f2,f0,f1

SPEC2017 Ofast P8LE: 511.povray_r +1.14%,  526.blender_r +1.72%

gcc/ChangeLog:

2021-09-07  Xionghu Luo  <luoxhu@linux.ibm.com>

	PR target/97142
	* config/rs6000/rs6000.md (fmod<mode>3): New define_expand.
	(remainder<mode>3): Likewise.

gcc/testsuite/ChangeLog:

2021-09-07  Xionghu Luo  <luoxhu@linux.ibm.com>

	PR target/97142
	* gcc.target/powerpc/pr97142.c: New test.
This commit is contained in:
Xionghu Luo 2021-09-06 20:22:50 -05:00
parent 58572bbb62
commit 546ecb0054
2 changed files with 71 additions and 0 deletions

View File

@ -4986,6 +4986,42 @@
[(set_attr "type" "fp")
(set_attr "isa" "*,<Fisa>")])
(define_expand "fmod<mode>3"
[(use (match_operand:SFDF 0 "gpc_reg_operand"))
(use (match_operand:SFDF 1 "gpc_reg_operand"))
(use (match_operand:SFDF 2 "gpc_reg_operand"))]
"TARGET_HARD_FLOAT
&& TARGET_FPRND
&& flag_unsafe_math_optimizations"
{
rtx div = gen_reg_rtx (<MODE>mode);
emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
rtx friz = gen_reg_rtx (<MODE>mode);
emit_insn (gen_btrunc<mode>2 (friz, div));
emit_insn (gen_nfms<mode>4 (operands[0], operands[2], friz, operands[1]));
DONE;
})
(define_expand "remainder<mode>3"
[(use (match_operand:SFDF 0 "gpc_reg_operand"))
(use (match_operand:SFDF 1 "gpc_reg_operand"))
(use (match_operand:SFDF 2 "gpc_reg_operand"))]
"TARGET_HARD_FLOAT
&& TARGET_FPRND
&& flag_unsafe_math_optimizations"
{
rtx div = gen_reg_rtx (<MODE>mode);
emit_insn (gen_div<mode>3 (div, operands[1], operands[2]));
rtx frin = gen_reg_rtx (<MODE>mode);
emit_insn (gen_round<mode>2 (frin, div));
emit_insn (gen_nfms<mode>4 (operands[0], operands[2], frin, operands[1]));
DONE;
})
(define_insn "*rsqrt<mode>2"
[(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
(unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]

View File

@ -0,0 +1,35 @@
/* { dg-do compile } */
/* { dg-options "-Ofast" } */
#include <math.h>
float test1 (float x, float y)
{
return fmodf (x, y);
}
double test2 (double x, double y)
{
return fmod (x, y);
}
float test3 (float x, float y)
{
return remainderf (x, y);
}
double test4 (double x, double y)
{
return remainder (x, y);
}
/* { dg-final { scan-assembler-not {(?n)\mb.*fmod} } } */
/* { dg-final { scan-assembler-not {(?n)\mb.*fmodf} } } */
/* { dg-final { scan-assembler-not {(?n)\mb.*remainder} } } */
/* { dg-final { scan-assembler-not {(?n)\mb.*remainderf} } } */
/* { dg-final { scan-assembler-times {\mfdiv\M} 2 } } */
/* { dg-final { scan-assembler-times {\mfdivs\M} 2 } } */
/* { dg-final { scan-assembler-times {\mfnmsub\M} 2 } } */
/* { dg-final { scan-assembler-times {\mfnmsubs\M} 2 } } */
/* { dg-final { scan-assembler-times {\mfriz\M} 2 } } */
/* { dg-final { scan-assembler-times {\mfrin\M} 2 } } */