* [RS6000] complex long double ABI_V4 fix
@ 2016-05-06 6:24 Alan Modra
2016-05-06 6:30 ` Alan Modra
` (2 more replies)
0 siblings, 3 replies; 6+ messages in thread
From: Alan Modra @ 2016-05-06 6:24 UTC (permalink / raw)
To: gcc-patches, Michael Meissner; +Cc: David Edelsohn, Segher Boessenkool
Revision 235792 regressed compat/scalar-by-value-6 for powerpc-linux
-m32 due to accidentally changing the ABI. By another historical
accident, complex long double is stupidly passed in gprs for -m32.
Bootstrapped and regression tested powerpc64-linux. Also fixes
gfortran.dg/{large_real_kind_2.F90,large_real_kind_form_io_1.f90}.
OK to apply?
* config/rs6000/rs6000.c (rs6000_function_arg): Exclude IBM
complex long double from args passed in fprs for ABI_V4.
(rs6000_function_arg_boundary, rs6000_function_arg_advance_1,
rs6000_gimplify_va_arg): Likewise.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 1215925..9c7a37b 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -10142,6 +10142,7 @@ rs6000_function_arg_boundary (machine_mode mode, const_tree type)
&& (GET_MODE_SIZE (mode) == 8
|| (TARGET_HARD_FLOAT
&& TARGET_FPRS
+ && !(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
&& FLOAT128_2REG_P (mode))))
return 64;
else if (FLOAT128_VECTOR_P (mode))
@@ -10524,7 +10525,8 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode,
if (TARGET_HARD_FLOAT && TARGET_FPRS
&& ((TARGET_SINGLE_FLOAT && mode == SFmode)
|| (TARGET_DOUBLE_FLOAT && mode == DFmode)
- || FLOAT128_2REG_P (mode)
+ || (!(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
+ && FLOAT128_2REG_P (mode))
|| DECIMAL_FLOAT_MODE_P (mode)))
{
/* _Decimal128 must use an even/odd register pair. This assumes
@@ -11185,7 +11187,10 @@ rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
if (TARGET_HARD_FLOAT && TARGET_FPRS
&& ((TARGET_SINGLE_FLOAT && mode == SFmode)
|| (TARGET_DOUBLE_FLOAT && mode == DFmode)
- || FLOAT128_2REG_P (mode)
+ /* ABI_V4 passes complex IBM long double in 8 gprs.
+ Stupid, but we can't change the ABI now. */
+ || (!(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
+ && FLOAT128_2REG_P (mode))
|| DECIMAL_FLOAT_MODE_P (mode)))
{
/* _Decimal128 must use an even/odd register pair. This assumes
@@ -12107,19 +12112,21 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
rsize = (size + 3) / 4;
align = 1;
+ machine_mode mode = TYPE_MODE (type);
if (TARGET_HARD_FLOAT && TARGET_FPRS
- && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
+ && ((TARGET_SINGLE_FLOAT && mode == SFmode)
|| (TARGET_DOUBLE_FLOAT
- && (TYPE_MODE (type) == DFmode
- || FLOAT128_2REG_P (TYPE_MODE (type))
- || DECIMAL_FLOAT_MODE_P (TYPE_MODE (type))))))
+ && (mode == DFmode
+ || (!(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
+ && FLOAT128_2REG_P (mode))
+ || DECIMAL_FLOAT_MODE_P (mode)))))
{
/* FP args go in FP registers, if present. */
reg = fpr;
n_reg = (size + 7) / 8;
sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
- if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
+ if (mode != SFmode && mode != SDmode)
align = 8;
}
else
@@ -12139,7 +12146,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
addr = create_tmp_var (ptr_type_node, "addr");
/* AltiVec vectors never go in registers when -mabi=altivec. */
- if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
+ if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
align = 16;
else
{
@@ -12160,7 +12167,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
}
/* _Decimal128 is passed in even/odd fpr pairs; the stored
reg number is 0 for f1, so we want to make it odd. */
- else if (reg == fpr && TYPE_MODE (type) == TDmode)
+ else if (reg == fpr && mode == TDmode)
{
t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
build_int_cst (TREE_TYPE (reg), 1));
@@ -12187,7 +12194,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
FP register for 32-bit binaries. */
if (TARGET_32BIT
&& TARGET_HARD_FLOAT && TARGET_FPRS
- && TYPE_MODE (type) == SDmode)
+ && mode == SDmode)
t = fold_build_pointer_plus_hwi (t, size);
gimplify_assign (addr, t, pre_p);
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RS6000] complex long double ABI_V4 fix
2016-05-06 6:24 [RS6000] complex long double ABI_V4 fix Alan Modra
@ 2016-05-06 6:30 ` Alan Modra
2016-05-09 14:43 ` Segher Boessenkool
2016-05-09 19:11 ` Michael Meissner
2 siblings, 0 replies; 6+ messages in thread
From: Alan Modra @ 2016-05-06 6:30 UTC (permalink / raw)
To: gcc-patches, Michael Meissner; +Cc: David Edelsohn, Segher Boessenkool
On Fri, May 06, 2016 at 03:54:43PM +0930, Alan Modra wrote:
> Revision 235792 regressed compat/scalar-by-value-6 for powerpc-linux
Sorry, typo in the revision. Should be 235794, git 3c62cae0.
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RS6000] complex long double ABI_V4 fix
2016-05-06 6:24 [RS6000] complex long double ABI_V4 fix Alan Modra
2016-05-06 6:30 ` Alan Modra
@ 2016-05-09 14:43 ` Segher Boessenkool
2016-05-10 23:47 ` Alan Modra
2016-05-09 19:11 ` Michael Meissner
2 siblings, 1 reply; 6+ messages in thread
From: Segher Boessenkool @ 2016-05-09 14:43 UTC (permalink / raw)
To: Alan Modra; +Cc: gcc-patches, Michael Meissner, David Edelsohn
On Fri, May 06, 2016 at 03:54:43PM +0930, Alan Modra wrote:
> Revision 235792 regressed compat/scalar-by-value-6 for powerpc-linux
> -m32 due to accidentally changing the ABI. By another historical
> accident, complex long double is stupidly passed in gprs for -m32.
>
> Bootstrapped and regression tested powerpc64-linux. Also fixes
> gfortran.dg/{large_real_kind_2.F90,large_real_kind_form_io_1.f90}.
> OK to apply?
> * config/rs6000/rs6000.c (rs6000_function_arg): Exclude IBM
> complex long double from args passed in fprs for ABI_V4.
> (rs6000_function_arg_boundary, rs6000_function_arg_advance_1,
> rs6000_gimplify_va_arg): Likewise.
>
> diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> index 1215925..9c7a37b 100644
> --- a/gcc/config/rs6000/rs6000.c
> +++ b/gcc/config/rs6000/rs6000.c
> @@ -10142,6 +10142,7 @@ rs6000_function_arg_boundary (machine_mode mode, const_tree type)
> && (GET_MODE_SIZE (mode) == 8
> || (TARGET_HARD_FLOAT
> && TARGET_FPRS
> + && !(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
> && FLOAT128_2REG_P (mode))))
Since this monstruous, unreadable condition is used a lot, use a nicely named
helper function instead?
Segher
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RS6000] complex long double ABI_V4 fix
2016-05-06 6:24 [RS6000] complex long double ABI_V4 fix Alan Modra
2016-05-06 6:30 ` Alan Modra
2016-05-09 14:43 ` Segher Boessenkool
@ 2016-05-09 19:11 ` Michael Meissner
2 siblings, 0 replies; 6+ messages in thread
From: Michael Meissner @ 2016-05-09 19:11 UTC (permalink / raw)
To: Alan Modra
Cc: gcc-patches, Michael Meissner, David Edelsohn, Segher Boessenkool
On Fri, May 06, 2016 at 03:54:43PM +0930, Alan Modra wrote:
> Revision 235792 regressed compat/scalar-by-value-6 for powerpc-linux
> -m32 due to accidentally changing the ABI. By another historical
> accident, complex long double is stupidly passed in gprs for -m32.
Sorry about the breakage. Thanks for digging into it.
--
Michael Meissner, IBM
IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA
email: meissner@linux.vnet.ibm.com, phone: +1 (978) 899-4797
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RS6000] complex long double ABI_V4 fix
2016-05-09 14:43 ` Segher Boessenkool
@ 2016-05-10 23:47 ` Alan Modra
2016-05-11 0:14 ` Segher Boessenkool
0 siblings, 1 reply; 6+ messages in thread
From: Alan Modra @ 2016-05-10 23:47 UTC (permalink / raw)
To: Segher Boessenkool; +Cc: gcc-patches, Michael Meissner, David Edelsohn
On Mon, May 09, 2016 at 09:43:36AM -0500, Segher Boessenkool wrote:
> On Fri, May 06, 2016 at 03:54:43PM +0930, Alan Modra wrote:
> > Revision 235792 regressed compat/scalar-by-value-6 for powerpc-linux
> > -m32 due to accidentally changing the ABI. By another historical
> > accident, complex long double is stupidly passed in gprs for -m32.
> >
> > Bootstrapped and regression tested powerpc64-linux. Also fixes
> > gfortran.dg/{large_real_kind_2.F90,large_real_kind_form_io_1.f90}.
> > OK to apply?
>
> > * config/rs6000/rs6000.c (rs6000_function_arg): Exclude IBM
> > complex long double from args passed in fprs for ABI_V4.
> > (rs6000_function_arg_boundary, rs6000_function_arg_advance_1,
> > rs6000_gimplify_va_arg): Likewise.
> >
> > diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
> > index 1215925..9c7a37b 100644
> > --- a/gcc/config/rs6000/rs6000.c
> > +++ b/gcc/config/rs6000/rs6000.c
> > @@ -10142,6 +10142,7 @@ rs6000_function_arg_boundary (machine_mode mode, const_tree type)
> > && (GET_MODE_SIZE (mode) == 8
> > || (TARGET_HARD_FLOAT
> > && TARGET_FPRS
> > + && !(mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode))
> > && FLOAT128_2REG_P (mode))))
>
> Since this monstruous, unreadable condition is used a lot, use a nicely named
> helper function instead?
Like this? Regstrapped powerpc64-linux. If you look closely you'll
see that this changes the condition for rs6000_gimplify_arg slightly,
which had TARGET_DOUBLE_FLOAT being tested for more than just DFmode.
It's wrong for function_arg to be different to gimplify_va_arg, and
might matter for spe.
Note that I doubt abi_v4_pass_in_fpr is completely correct regarding
TARGET_SINGLE_FLOAT and TARGET_DOUBLE_FLOAT, but I'm going to leave
tidying that to a maintainer. It seems to me that TARGET_SINGLE_FLOAT
ought to affect SDmode as well as SFmode, and TARGET_DOUBLE_FLOAT
everything else.
* config/rs6000/rs6000.c (is_complex_IBM_long_double,
abi_v4_pass_in_fpr): New functions.
(rs6000_function_arg_boundary): Exclude complex IBM long double
from 64-bit alignment when ABI_V4.
(rs6000_function_arg, rs6000_function_arg_advance_1,
rs6000_gimplify_va_arg): Use abi_v4_pass_in_fpr.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index e01630e..2763ea6 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -10053,6 +10053,35 @@ rs6000_must_pass_in_stack (machine_mode mode, const_tree type)
return must_pass_in_stack_var_size_or_pad (mode, type);
}
+static inline bool
+is_complex_IBM_long_double (machine_mode mode)
+{
+ return mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode);
+}
+
+/* Whether ABI_V4 passes MODE args to a function in floating point
+ registers. */
+
+static bool
+abi_v4_pass_in_fpr (machine_mode mode)
+{
+ if (!TARGET_FPRS || !TARGET_HARD_FLOAT)
+ return false;
+ if (TARGET_SINGLE_FLOAT && mode == SFmode)
+ return true;
+ if (TARGET_DOUBLE_FLOAT && mode == DFmode)
+ return true;
+ /* ABI_V4 passes complex IBM long double in 8 gprs.
+ Stupid, but we can't change the ABI now. */
+ if (is_complex_IBM_long_double (mode))
+ return false;
+ if (FLOAT128_2REG_P (mode))
+ return true;
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ return true;
+ return false;
+}
+
/* If defined, a C expression which determines whether, and in which
direction, to pad out an argument with extra space. The value
should be of type `enum direction': either `upward' to pad above
@@ -10137,6 +10166,7 @@ rs6000_function_arg_boundary (machine_mode mode, const_tree type)
&& (GET_MODE_SIZE (mode) == 8
|| (TARGET_HARD_FLOAT
&& TARGET_FPRS
+ && !is_complex_IBM_long_double (mode)
&& FLOAT128_2REG_P (mode))))
return 64;
else if (FLOAT128_VECTOR_P (mode))
@@ -10516,11 +10546,7 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode,
}
else if (DEFAULT_ABI == ABI_V4)
{
- if (TARGET_HARD_FLOAT && TARGET_FPRS
- && ((TARGET_SINGLE_FLOAT && mode == SFmode)
- || (TARGET_DOUBLE_FLOAT && mode == DFmode)
- || FLOAT128_2REG_P (mode)
- || DECIMAL_FLOAT_MODE_P (mode)))
+ if (abi_v4_pass_in_fpr (mode))
{
/* _Decimal128 must use an even/odd register pair. This assumes
that the register number is odd when fregno is odd. */
@@ -11177,11 +11203,7 @@ rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
else if (abi == ABI_V4)
{
- if (TARGET_HARD_FLOAT && TARGET_FPRS
- && ((TARGET_SINGLE_FLOAT && mode == SFmode)
- || (TARGET_DOUBLE_FLOAT && mode == DFmode)
- || FLOAT128_2REG_P (mode)
- || DECIMAL_FLOAT_MODE_P (mode)))
+ if (abi_v4_pass_in_fpr (mode))
{
/* _Decimal128 must use an even/odd register pair. This assumes
that the register number is odd when fregno is odd. */
@@ -12102,19 +12124,15 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
rsize = (size + 3) / 4;
align = 1;
- if (TARGET_HARD_FLOAT && TARGET_FPRS
- && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
- || (TARGET_DOUBLE_FLOAT
- && (TYPE_MODE (type) == DFmode
- || FLOAT128_2REG_P (TYPE_MODE (type))
- || DECIMAL_FLOAT_MODE_P (TYPE_MODE (type))))))
+ machine_mode mode = TYPE_MODE (type);
+ if (abi_v4_pass_in_fpr (mode))
{
/* FP args go in FP registers, if present. */
reg = fpr;
n_reg = (size + 7) / 8;
sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
- if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
+ if (mode != SFmode && mode != SDmode)
align = 8;
}
else
@@ -12134,7 +12152,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
addr = create_tmp_var (ptr_type_node, "addr");
/* AltiVec vectors never go in registers when -mabi=altivec. */
- if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
+ if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
align = 16;
else
{
@@ -12155,7 +12173,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
}
/* _Decimal128 is passed in even/odd fpr pairs; the stored
reg number is 0 for f1, so we want to make it odd. */
- else if (reg == fpr && TYPE_MODE (type) == TDmode)
+ else if (reg == fpr && mode == TDmode)
{
t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
build_int_cst (TREE_TYPE (reg), 1));
@@ -12182,7 +12200,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
FP register for 32-bit binaries. */
if (TARGET_32BIT
&& TARGET_HARD_FLOAT && TARGET_FPRS
- && TYPE_MODE (type) == SDmode)
+ && mode == SDmode)
t = fold_build_pointer_plus_hwi (t, size);
gimplify_assign (addr, t, pre_p);
--
Alan Modra
Australia Development Lab, IBM
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [RS6000] complex long double ABI_V4 fix
2016-05-10 23:47 ` Alan Modra
@ 2016-05-11 0:14 ` Segher Boessenkool
0 siblings, 0 replies; 6+ messages in thread
From: Segher Boessenkool @ 2016-05-11 0:14 UTC (permalink / raw)
To: Alan Modra; +Cc: gcc-patches, Michael Meissner, David Edelsohn
On Wed, May 11, 2016 at 09:17:00AM +0930, Alan Modra wrote:
> On Mon, May 09, 2016 at 09:43:36AM -0500, Segher Boessenkool wrote:
> > Since this monstruous, unreadable condition is used a lot, use a nicely named
> > helper function instead?
>
> Like this?
Like that. Thanks!
> * config/rs6000/rs6000.c (is_complex_IBM_long_double,
> abi_v4_pass_in_fpr): New functions.
> (rs6000_function_arg_boundary): Exclude complex IBM long double
> from 64-bit alignment when ABI_V4.
> (rs6000_function_arg, rs6000_function_arg_advance_1,
> rs6000_gimplify_va_arg): Use abi_v4_pass_in_fpr.
Okay for trunk.
Segher
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2016-05-11 0:14 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-05-06 6:24 [RS6000] complex long double ABI_V4 fix Alan Modra
2016-05-06 6:30 ` Alan Modra
2016-05-09 14:43 ` Segher Boessenkool
2016-05-10 23:47 ` Alan Modra
2016-05-11 0:14 ` Segher Boessenkool
2016-05-09 19:11 ` Michael Meissner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).