This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH, rs6000] Fix PR target/80246, DFP builtins using the wrong types
- From: Peter Bergner <bergner at vnet dot ibm dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Segher Boessenkool <segher at kernel dot crashing dot org>, David Edelsohn <dje dot gcc at gmail dot com>, Bill Schmidt <wschmidt at linux dot vnet dot ibm dot com>
- Date: Wed, 29 Mar 2017 16:11:19 -0500
- Subject: [PATCH, rs6000] Fix PR target/80246, DFP builtins using the wrong types
- Authentication-results: sourceware.org; auth=none
PR80246 shows a problem with the dxex, dxexq, diex and diexq insn patterns,
that shows up when calling their associated builtins. The dxex and dxexq
instructions are defined to return 64-bit signed integers (in a FP register),
but the output mode of their patterns is _Decimal64/_Decimal128.
This leads to corrupting of the returned value if we assign the return
value to a integer type variable (ie, we do a cast). A similar problem
exists with the diex and diexq patterns on their input operand that
is supposed to hold a 64-bit signed integer.
This patch fixes the patterns to use DImode (ie, a 64-bit integer).
Google shows no use of the builtins anywhere except in the GCC source,
so it should be safe to change these. If there were users, they would
have noticed how broken the builtins were.
This passed bootstrap and regtesting on powerpc64le-linux and
powerpc64-linux (testsuite in both 32-bit and 64-bit). Ok for mainline?
Ok for the open release branches too?
Peter
gcc/
PR target/80246
* config/rs6000/dfp.md (dfp_dxex_<mode>): Update mode of operand 0.
(dfp_diex_<mode>): Update mode of operand 1.
* doc/extend.texi (dxex, dxexq): Document change to return type.
(diex, diexq): Document change to argument type.
gcc/testsuite/
PR target/80246
* gcc.target/powerpc/dfp-builtin-1.c (dxex, dxexq): Update return types.
(diex, diexq): Update argment types.
* gcc.target/powerpc/pr80246.c: New test.
Index: gcc/config/rs6000/dfp.md
===================================================================
--- gcc/config/rs6000/dfp.md (revision 246539)
+++ gcc/config/rs6000/dfp.md (working copy)
@@ -348,9 +348,9 @@
[(set_attr "type" "dfp")])
(define_insn "dfp_dxex_<mode>"
- [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
- (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
- UNSPEC_DXEX))]
+ [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
+ (unspec:DI [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
+ UNSPEC_DXEX))]
"TARGET_DFP"
"dxex<dfp_suffix> %0,%1"
[(set_attr "type" "dfp")])
@@ -357,7 +357,7 @@
(define_insn "dfp_diex_<mode>"
[(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
- (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+ (unspec:D64_D128 [(match_operand:DI 1 "gpc_reg_operand" "d")
(match_operand:D64_D128 2 "gpc_reg_operand" "d")]
UNSPEC_DXEX))]
"TARGET_DFP"
Index: gcc/doc/extend.texi
===================================================================
--- gcc/doc/extend.texi (revision 246539)
+++ gcc/doc/extend.texi (working copy)
@@ -15427,14 +15427,14 @@
of processors when hardware decimal floating point
(@option{-mhard-dfp}) is available:
@smallexample
-_Decimal64 __builtin_dxex (_Decimal64);
-_Decimal128 __builtin_dxexq (_Decimal128);
+long long __builtin_dxex (_Decimal64);
+long long __builtin_dxexq (_Decimal128);
_Decimal64 __builtin_ddedpd (int, _Decimal64);
_Decimal128 __builtin_ddedpdq (int, _Decimal128);
_Decimal64 __builtin_denbcd (int, _Decimal64);
_Decimal128 __builtin_denbcdq (int, _Decimal128);
-_Decimal64 __builtin_diex (_Decimal64, _Decimal64);
-_Decimal128 _builtin_diexq (_Decimal128, _Decimal128);
+_Decimal64 __builtin_diex (long long, _Decimal64);
+_Decimal128 _builtin_diexq (long long, _Decimal128);
_Decimal64 __builtin_dscli (_Decimal64, int);
_Decimal128 __builtin_dscliq (_Decimal128, int);
_Decimal64 __builtin_dscri (_Decimal64, int);
Index: gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c (revision 246539)
+++ gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c (working copy)
@@ -52,7 +52,7 @@
return __builtin_denbcd (1, a);
}
-_Decimal64
+long long
do_xex (_Decimal64 a)
{
return __builtin_dxex (a);
@@ -59,7 +59,7 @@
}
_Decimal64
-do_iex (_Decimal64 a, _Decimal64 b)
+do_iex (long long a, _Decimal64 b)
{
return __builtin_diex (a, b);
}
Index: gcc/testsuite/gcc.target/powerpc/pr80246.c
===================================================================
--- gcc/testsuite/gcc.target/powerpc/pr80246.c (nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr80246.c (working copy)
@@ -0,0 +1,40 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target dfp } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-times "dxex " 1 } } */
+/* { dg-final { scan-assembler-times "dxexq " 1 } } */
+/* { dg-final { scan-assembler-times "diex " 1 } } */
+/* { dg-final { scan-assembler-times "diexq " 1 } } */
+/* { dg-final { scan-assembler-not "bl __builtin" } } */
+/* { dg-final { scan-assembler-not "drintn\\." } } */
+/* { dg-final { scan-assembler-not "drintnq\\." } } */
+/* { dg-final { scan-assembler-not "dctfix" } } */
+/* { dg-final { scan-assembler-not "dctfixq" } } */
+/* { dg-final { scan-assembler-not "dcffix" } } */
+/* { dg-final { scan-assembler-not "dcffixq" } } */
+
+long long
+do_xex (_Decimal64 arg)
+{
+ return __builtin_dxex (arg);
+}
+
+long long
+do_xexq (_Decimal128 arg)
+{
+ return __builtin_dxexq (arg);
+}
+
+_Decimal64
+do_iex (long long exp, _Decimal64 arg)
+{
+ return __builtin_diex (exp, arg);
+}
+
+_Decimal128
+do_iexq (long long exp, _Decimal128 arg)
+{
+ return __builtin_diexq (exp, arg);
+}