This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH, rs6000, generic builtins] Fix unary TDmode patterns and add DFP ABS builtins
- From: Peter Bergner <bergner at vnet dot ibm dot com>
- To: David Edelsohn <dje dot gcc at gmail dot com>
- Cc: "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>, Jakub Jelinek <jakub at redhat dot com>
- Date: Fri, 16 Aug 2013 17:32:17 -0500
- Subject: Re: [PATCH, rs6000, generic builtins] Fix unary TDmode patterns and add DFP ABS builtins
- References: <1376672816 dot 5807 dot 8 dot camel at otta> <20130816171133 dot GI1814 at tucnak dot redhat dot com> <1376687898 dot 5807 dot 26 dot camel at otta> <20130816212523 dot GL1814 at tucnak dot redhat dot com>
On Fri, 2013-08-16 at 23:25 +0200, Jakub Jelinek wrote:
> On Fri, Aug 16, 2013 at 04:18:18PM -0500, Peter Bergner wrote:
> > --- gcc/config/rs6000/dfp.md (revision 201779)
> > +++ gcc/config/rs6000/dfp.md (working copy)
> > @@ -132,11 +132,14 @@ (define_expand "negtd2"
> > "")
> >
> > (define_insn "*negtd2_fpr"
> > - [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
> > - (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
> > + [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
> > + (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d,0")))]
>
> I'm surprised if it works in this order, I'd expect that alternative 0
> would match even for the same regno and that the second alternative wouldn't
> be tried.
Ok, updated to switch the order of the alternatives. This works...just
like the previous one. I created two versions of the TD test case to
test both alternatives and to make sure we get fmrs on the one and
no fmrs on the other.
Peter
gcc/
* builtins.def (BUILT_IN_FABSD32): New DFP ABS builtin.
(BUILT_IN_FABSD64): Likewise.
(BUILT_IN_FABSD128): Likewise.
* builtins.c (expand_builtin): Add support for new DFP ABS builtins.
(fold_builtin_1): Likewise.
* config/rs6000/dfp.md (*negtd2_fpr): Handle non-overlapping destination
and source operands.
(*abstd2_fpr): Likewise.
(*nabstd2_fpr): Likewise.
gcc/testsuite/
* gcc.target/powerpc/dfp-dd-2.c: New test.
* gcc.target/powerpc/dfp-td-2.c: Likewise.
* gcc.target/powerpc/dfp-td-3.c: Likewise.
Index: gcc/builtins.c
===================================================================
--- gcc/builtins.c (revision 201779)
+++ gcc/builtins.c (working copy)
@@ -5865,6 +5865,9 @@ expand_builtin (tree exp, rtx target, rt
switch (fcode)
{
CASE_FLT_FN (BUILT_IN_FABS):
+ case BUILT_IN_FABSD32:
+ case BUILT_IN_FABSD64:
+ case BUILT_IN_FABSD128:
target = expand_builtin_fabs (exp, target, subtarget);
if (target)
return target;
@@ -10314,6 +10317,9 @@ fold_builtin_1 (location_t loc, tree fnd
return fold_builtin_strlen (loc, type, arg0);
CASE_FLT_FN (BUILT_IN_FABS):
+ case BUILT_IN_FABSD32:
+ case BUILT_IN_FABSD64:
+ case BUILT_IN_FABSD128:
return fold_builtin_fabs (loc, arg0, type);
case BUILT_IN_ABS:
Index: gcc/builtins.def
===================================================================
--- gcc/builtins.def (revision 201779)
+++ gcc/builtins.def (working copy)
@@ -257,6 +257,9 @@ DEF_C99_BUILTIN (BUILT_IN_EXPM1L,
DEF_LIB_BUILTIN (BUILT_IN_FABS, "fabs", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_FABSD128, "fabsd128", BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
Index: gcc/config/rs6000/dfp.md
===================================================================
--- gcc/config/rs6000/dfp.md (revision 201779)
+++ gcc/config/rs6000/dfp.md (working copy)
@@ -132,11 +132,14 @@ (define_expand "negtd2"
"")
(define_insn "*negtd2_fpr"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
+ [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
+ (neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
- "fneg %0,%1"
- [(set_attr "type" "fp")])
+ "@
+ fneg %0,%1
+ fneg %0,%1\;fmr %L0,%L1"
+ [(set_attr "type" "fp")
+ (set_attr "length" "4,8")])
(define_expand "abstd2"
[(set (match_operand:TD 0 "gpc_reg_operand" "")
@@ -145,18 +148,24 @@ (define_expand "abstd2"
"")
(define_insn "*abstd2_fpr"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
+ [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
+ (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
- "fabs %0,%1"
- [(set_attr "type" "fp")])
+ "@
+ fabs %0,%1
+ fabs %0,%1\;fmr %L0,%L1"
+ [(set_attr "type" "fp")
+ (set_attr "length" "4,8")])
(define_insn "*nabstd2_fpr"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d"))))]
+ [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
+ (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
- "fnabs %0,%1"
- [(set_attr "type" "fp")])
+ "@
+ fnabs %0,%1
+ fnabs %0,%1\;fmr %L0,%L1"
+ [(set_attr "type" "fp")
+ (set_attr "length" "4,8")])
;; Hardware support for decimal floating point operations.
Index: gcc/testsuite/gcc.target/powerpc/dfp-dd-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/dfp-dd-2.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/dfp-dd-2.c (revision 0)
@@ -0,0 +1,26 @@
+/* Test generation of DFP instructions for POWER6. */
+/* { dg-do compile { target { powerpc*-*-linux* && powerpc_fprs } } } */
+/* { dg-options "-std=gnu99 -O1 -mcpu=power6" } */
+
+/* { dg-final { scan-assembler-times "fneg" 1 } } */
+/* { dg-final { scan-assembler-times "fabs" 1 } } */
+/* { dg-final { scan-assembler-times "fnabs" 1 } } */
+/* { dg-final { scan-assembler-times "fmr" 0 } } */
+
+_Decimal64
+func1 (_Decimal64 a, _Decimal64 b)
+{
+ return -b;
+}
+
+_Decimal64
+func2 (_Decimal64 a, _Decimal64 b)
+{
+ return __builtin_fabsd64 (b);
+}
+
+_Decimal64
+func3 (_Decimal64 a, _Decimal64 b)
+{
+ return - __builtin_fabsd64 (b);
+}
Index: gcc/testsuite/gcc.target/powerpc/dfp-td-2.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/dfp-td-2.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/dfp-td-2.c (revision 0)
@@ -0,0 +1,29 @@
+/* Test generation of DFP instructions for POWER6. */
+/* { dg-do compile { target { powerpc*-*-linux* && powerpc_fprs } } } */
+/* { dg-options "-std=gnu99 -O1 -mcpu=power6" } */
+
+/* { dg-final { scan-assembler-times "fneg" 1 } } */
+/* { dg-final { scan-assembler-times "fabs" 1 } } */
+/* { dg-final { scan-assembler-times "fnabs" 1 } } */
+/* { dg-final { scan-assembler-times "fmr" 0 } } */
+
+/* These tests verify we only generate fneg, fabs and fnabs
+ instructions and no fmr's since these are done in place. */
+
+_Decimal128
+func1 (_Decimal128 a)
+{
+ return -a;
+}
+
+_Decimal128
+func2 (_Decimal128 a)
+{
+ return __builtin_fabsd128 (a);
+}
+
+_Decimal128
+func3 (_Decimal128 a)
+{
+ return - __builtin_fabsd128 (a);
+}
Index: gcc/testsuite/gcc.target/powerpc/dfp-td-3.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/dfp-td-3.c (revision 0)
+++ gcc/testsuite/gcc.target/powerpc/dfp-td-3.c (revision 0)
@@ -0,0 +1,29 @@
+/* Test generation of DFP instructions for POWER6. */
+/* { dg-do compile { target { powerpc*-*-linux* && powerpc_fprs } } } */
+/* { dg-options "-std=gnu99 -O1 -mcpu=power6" } */
+
+/* { dg-final { scan-assembler-times "fneg" 1 } } */
+/* { dg-final { scan-assembler-times "fabs" 1 } } */
+/* { dg-final { scan-assembler-times "fnabs" 1 } } */
+/* { dg-final { scan-assembler-times "fmr" 3 } } */
+
+/* These tests verify we generate fneg, fabs and fnabs and
+ associated fmr's since these are not done in place. */
+
+_Decimal128
+func1 (_Decimal128 a, _Decimal128 b)
+{
+ return -b;
+}
+
+_Decimal128
+func2 (_Decimal128 a, _Decimal128 b)
+{
+ return __builtin_fabsd128 (b);
+}
+
+_Decimal128
+func3 (_Decimal128 a, _Decimal128 b)
+{
+ return - __builtin_fabsd128 (b);
+}