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:
parent
58572bbb62
commit
546ecb0054
@ -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")]
|
||||
|
35
gcc/testsuite/gcc.target/powerpc/pr97142.c
Normal file
35
gcc/testsuite/gcc.target/powerpc/pr97142.c
Normal 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 } } */
|
Loading…
Reference in New Issue
Block a user