LoongArch: Provide fmin/fmax RTL pattern
We already had smin/smax RTL pattern using fmin/fmax instruction. But for smin/smax, it's unspecified what will happen if either operand is NaN. So we would generate calls to libc fmin/fmax functions with -fno-finite-math-only (the default for all optimization levels expect -Ofast). But, LoongArch fmin/fmax instruction is IEEE-754-2008 conformant so we can also use the instruction for fmin/fmax pattern and avoid the library function call. gcc/ChangeLog: * config/loongarch/loongarch.md (fmax<mode>3): New RTL pattern. (fmin<mode>3): Likewise. gcc/testsuite/ChangeLog: * gcc.target/loongarch/fmax-fmin.c: New test.
This commit is contained in:
parent
80f78716c2
commit
3cab897a67
2 changed files with 48 additions and 0 deletions
|
@ -1023,6 +1023,24 @@
|
|||
[(set_attr "type" "fmove")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "fmax<mode>3"
|
||||
[(set (match_operand:ANYF 0 "register_operand" "=f")
|
||||
(smax:ANYF (match_operand:ANYF 1 "register_operand" "f")
|
||||
(match_operand:ANYF 2 "register_operand" "f")))]
|
||||
""
|
||||
"fmax.<fmt>\t%0,%1,%2"
|
||||
[(set_attr "type" "fmove")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "fmin<mode>3"
|
||||
[(set (match_operand:ANYF 0 "register_operand" "=f")
|
||||
(smin:ANYF (match_operand:ANYF 1 "register_operand" "f")
|
||||
(match_operand:ANYF 2 "register_operand" "f")))]
|
||||
""
|
||||
"fmin.<fmt>\t%0,%1,%2"
|
||||
[(set_attr "type" "fmove")
|
||||
(set_attr "mode" "<MODE>")])
|
||||
|
||||
(define_insn "smaxa<mode>3"
|
||||
[(set (match_operand:ANYF 0 "register_operand" "=f")
|
||||
(if_then_else:ANYF
|
||||
|
|
30
gcc/testsuite/gcc.target/loongarch/fmax-fmin.c
Normal file
30
gcc/testsuite/gcc.target/loongarch/fmax-fmin.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
/* { dg-do compile } */
|
||||
/* { dg-options "-mdouble-float -fno-finite-math-only" } */
|
||||
/* { dg-final { scan-assembler "fmin\\.s" } } */
|
||||
/* { dg-final { scan-assembler "fmin\\.d" } } */
|
||||
/* { dg-final { scan-assembler "fmax\\.s" } } */
|
||||
/* { dg-final { scan-assembler "fmax\\.d" } } */
|
||||
|
||||
double
|
||||
_fmax(double a, double b)
|
||||
{
|
||||
return __builtin_fmax(a, b);
|
||||
}
|
||||
|
||||
float
|
||||
_fmaxf(float a, float b)
|
||||
{
|
||||
return __builtin_fmaxf(a, b);
|
||||
}
|
||||
|
||||
double
|
||||
_fmin(double a, double b)
|
||||
{
|
||||
return __builtin_fmin(a, b);
|
||||
}
|
||||
|
||||
float
|
||||
_fminf(float a, float b)
|
||||
{
|
||||
return __builtin_fminf(a, b);
|
||||
}
|
Loading…
Add table
Reference in a new issue