Prevent all uses of DFP when unsupported (PR c/91985)
diff mbox series

Message ID alpine.DEB.2.21.1911221638140.18133@digraph.polyomino.org.uk
State New
Headers show
Series
  • Prevent all uses of DFP when unsupported (PR c/91985)
Related show

Commit Message

Joseph Myers Nov. 22, 2019, 4:40 p.m. UTC
Code that directly uses _Decimal* types on architectures not
supporting DFP is properly diagnosed ("error: decimal floating-point
not supported for this target"), via a call to
targetm.decimal_float_supported_p, if the _Decimal32, _Decimal64 or
_Decimal128 keywords are used to access it.  Use via mode attributes
is also diagnosed ("unable to emulate 'SD'"); so is use of the
FLOAT_CONST_DECIMAL64 pragma.  However, it is possible to access those
types via typeof applied to constants or built-in functions without
such an error.  I expect that there are ways to get an ICE from this;
certainly it uses a completely undefined ABI.

This patch arranges for the types not to exist in the compiler at all
when DFP is not supported.  As is done with unsupported _FloatN /
_FloatNx types, the global tree nodes are left as NULL_TREE, and the
built-in function machinery is made to use error_mark_node for them in
that case in builtin-types.def, so that the built-in functions are
unavailable.  Code handling constants is adjusted to give an error,
and other code that might not work with the global tree nodes being
NULL_TREE is also updated.

Bootstrapped with no regressions for x86_64-pc-linux-gnu.  Also tested
with no regressions for cross to aarch64-linux-gnu, as a configuration
without DFP support.  OK to commit (the changes that aren't C front-end 
changes)?

gcc:
2019-11-22  Joseph Myers  <joseph@codesourcery.com>

	PR c/91985
	* builtin-types.def (BT_DFLOAT32, BT_DFLOAT64, BT_DFLOAT128)
	(BT_DFLOAT32_PTR, BT_DFLOAT64_PTR, BT_DFLOAT128_PTR): Define to
	error_mark_node if corresponding global tree node is NULL.
	* tree.c (build_common_tree_nodes): Do not initialize
	dfloat32_type_node, dfloat64_type_node or dfloat128_type_node if
	decimal floating-point not supported.

gcc/c:
2019-11-22  Joseph Myers  <joseph@codesourcery.com>

	PR c/91985
	* c-decl.c (finish_declspecs): Use int instead of decimal
	floating-point types if decimal floating-point not supported.

gcc/c-family:
2019-11-22  Joseph Myers  <joseph@codesourcery.com>

	PR c/91985
	* c-common.c (c_common_type_for_mode): Handle decimal
	floating-point types being NULL_TREE.
	* c-format.c (get_format_for_type_1): Handle specified types being
	NULL_TREE.
	* c-lex.c (interpret_float): Give an error for decimal
	floating-point constants when decimal floating-point not
	supported.

gcc/lto:
2019-11-22  Joseph Myers  <joseph@codesourcery.com>

	PR c/91985
	* lto-lang.c (lto_type_for_mode): Handle decimal floating-point
	types being NULL_TREE.

gcc/testsuite:
2019-11-22  Joseph Myers  <joseph@codesourcery.com>

	PR c/91985
	* gcc.dg/c2x-no-dfp-1.c, gcc.dg/gnu2x-builtins-no-dfp-1.c: New
	tests.
	* gcc.dg/fltconst-pedantic-dfp.c: Expect errors when decimal
	floating-point not supported.

Comments

Jeff Law Nov. 23, 2019, 4:55 p.m. UTC | #1
On 11/22/19 9:40 AM, Joseph Myers wrote:
> Code that directly uses _Decimal* types on architectures not
> supporting DFP is properly diagnosed ("error: decimal floating-point
> not supported for this target"), via a call to
> targetm.decimal_float_supported_p, if the _Decimal32, _Decimal64 or
> _Decimal128 keywords are used to access it.  Use via mode attributes
> is also diagnosed ("unable to emulate 'SD'"); so is use of the
> FLOAT_CONST_DECIMAL64 pragma.  However, it is possible to access those
> types via typeof applied to constants or built-in functions without
> such an error.  I expect that there are ways to get an ICE from this;
> certainly it uses a completely undefined ABI.
> 
> This patch arranges for the types not to exist in the compiler at all
> when DFP is not supported.  As is done with unsupported _FloatN /
> _FloatNx types, the global tree nodes are left as NULL_TREE, and the
> built-in function machinery is made to use error_mark_node for them in
> that case in builtin-types.def, so that the built-in functions are
> unavailable.  Code handling constants is adjusted to give an error,
> and other code that might not work with the global tree nodes being
> NULL_TREE is also updated.
> 
> Bootstrapped with no regressions for x86_64-pc-linux-gnu.  Also tested
> with no regressions for cross to aarch64-linux-gnu, as a configuration
> without DFP support.  OK to commit (the changes that aren't C front-end 
> changes)?
> 
> gcc:
> 2019-11-22  Joseph Myers  <joseph@codesourcery.com>
> 
> 	PR c/91985
> 	* builtin-types.def (BT_DFLOAT32, BT_DFLOAT64, BT_DFLOAT128)
> 	(BT_DFLOAT32_PTR, BT_DFLOAT64_PTR, BT_DFLOAT128_PTR): Define to
> 	error_mark_node if corresponding global tree node is NULL.
> 	* tree.c (build_common_tree_nodes): Do not initialize
> 	dfloat32_type_node, dfloat64_type_node or dfloat128_type_node if
> 	decimal floating-point not supported.
> 
> gcc/c:
> 2019-11-22  Joseph Myers  <joseph@codesourcery.com>
> 
> 	PR c/91985
> 	* c-decl.c (finish_declspecs): Use int instead of decimal
> 	floating-point types if decimal floating-point not supported.
> 
> gcc/c-family:
> 2019-11-22  Joseph Myers  <joseph@codesourcery.com>
> 
> 	PR c/91985
> 	* c-common.c (c_common_type_for_mode): Handle decimal
> 	floating-point types being NULL_TREE.
> 	* c-format.c (get_format_for_type_1): Handle specified types being
> 	NULL_TREE.
> 	* c-lex.c (interpret_float): Give an error for decimal
> 	floating-point constants when decimal floating-point not
> 	supported.
> 
> gcc/lto:
> 2019-11-22  Joseph Myers  <joseph@codesourcery.com>
> 
> 	PR c/91985
> 	* lto-lang.c (lto_type_for_mode): Handle decimal floating-point
> 	types being NULL_TREE.
> 
> gcc/testsuite:
> 2019-11-22  Joseph Myers  <joseph@codesourcery.com>
> 
> 	PR c/91985
> 	* gcc.dg/c2x-no-dfp-1.c, gcc.dg/gnu2x-builtins-no-dfp-1.c: New
> 	tests.
> 	* gcc.dg/fltconst-pedantic-dfp.c: Expect errors when decimal
> 	floating-point not supported.
OK
jeff
Rainer Orth Nov. 25, 2019, 8:34 p.m. UTC | #2
Hi Joseph,

> Code that directly uses _Decimal* types on architectures not
> supporting DFP is properly diagnosed ("error: decimal floating-point
> not supported for this target"), via a call to
> targetm.decimal_float_supported_p, if the _Decimal32, _Decimal64 or
> _Decimal128 keywords are used to access it.  Use via mode attributes
> is also diagnosed ("unable to emulate 'SD'"); so is use of the
> FLOAT_CONST_DECIMAL64 pragma.  However, it is possible to access those
> types via typeof applied to constants or built-in functions without
> such an error.  I expect that there are ways to get an ICE from this;
> certainly it uses a completely undefined ABI.
>
> This patch arranges for the types not to exist in the compiler at all
> when DFP is not supported.  As is done with unsupported _FloatN /
> _FloatNx types, the global tree nodes are left as NULL_TREE, and the
> built-in function machinery is made to use error_mark_node for them in
> that case in builtin-types.def, so that the built-in functions are
> unavailable.  Code handling constants is adjusted to give an error,
> and other code that might not work with the global tree nodes being
> NULL_TREE is also updated.
>
> Bootstrapped with no regressions for x86_64-pc-linux-gnu.  Also tested
> with no regressions for cross to aarch64-linux-gnu, as a configuration
> without DFP support.  OK to commit (the changes that aren't C front-end 
> changes)?

AFAICS this caused

+FAIL: libstdc++-abi/abi_check

on Solaris.  In libstdc++.log I find

# of added symbols:              0
# of missing symbols:            9
# of undesignated symbols:       0
# of incompatible symbols:       9

9 missing symbols
0
_ZTIDf
typeinfo for decimal32
version status: unversioned
type: object
type size: 8
status: subtracted
[...]

and a few more, all DFP related.  They used to be emitted by g++ for
__fundamental_type_info in libsupc++/fundamental_type_info.cc and lived
in the CXXABI_1.3.4 version.  However, since Solaris *does* lack DFP
support, that's no longer the case.  I'm uncertain how best to deal with
this, however.

	Rainer
Joseph Myers Nov. 26, 2019, 12:57 a.m. UTC | #3
On Mon, 25 Nov 2019, Rainer Orth wrote:

> and a few more, all DFP related.  They used to be emitted by g++ for
> __fundamental_type_info in libsupc++/fundamental_type_info.cc and lived
> in the CXXABI_1.3.4 version.  However, since Solaris *does* lack DFP
> support, that's no longer the case.  I'm uncertain how best to deal with
> this, however.

As I understand it, _GLIBCXX_USE_DECIMAL_FLOAT should already have been 
undefined for this target, and so std::decimal::decimal32 etc. should not 
have been usable (both the header not working without that define, and the 
mode attributes in the header being rejected by the front end when DFP is 
unsupported).  I.e. such defines in libsupc++ would never have been usable 
on this target, so I think they are something it should be safe to remove 
from the ABI baseline.
Jonathan Wakely Nov. 26, 2019, 12:13 p.m. UTC | #4
On 26/11/19 00:57 +0000, Joseph Myers wrote:
>On Mon, 25 Nov 2019, Rainer Orth wrote:
>
>> and a few more, all DFP related.  They used to be emitted by g++ for
>> __fundamental_type_info in libsupc++/fundamental_type_info.cc and lived
>> in the CXXABI_1.3.4 version.  However, since Solaris *does* lack DFP
>> support, that's no longer the case.  I'm uncertain how best to deal with
>> this, however.
>
>As I understand it, _GLIBCXX_USE_DECIMAL_FLOAT should already have been
>undefined for this target, and so std::decimal::decimal32 etc. should not
>have been usable (both the header not working without that define, and the
>mode attributes in the header being rejected by the front end when DFP is
>unsupported).  I.e. such defines in libsupc++ would never have been usable
>on this target, so I think they are something it should be safe to remove
>from the ABI baseline.

If it's actually impossible that any real program could have depended
on those symbols, then I agree.

We could consider adding some useless stubs with those symbol names
(as aliases of something else?) so the symbols are still in the
library, to keep various tools happy.
Andreas Schwab Nov. 26, 2019, 1:33 p.m. UTC | #5
On Nov 25 2019, Rainer Orth wrote:

> AFAICS this caused
>
> +FAIL: libstdc++-abi/abi_check
>
> on Solaris.  In libstdc++.log I find

That happens on all targets that don't support decimal float.

Andreas.
Rainer Orth Nov. 27, 2019, 11:26 a.m. UTC | #6
Hi Jonathan,

> On 26/11/19 00:57 +0000, Joseph Myers wrote:
>>On Mon, 25 Nov 2019, Rainer Orth wrote:
>>
>>> and a few more, all DFP related.  They used to be emitted by g++ for
>>> __fundamental_type_info in libsupc++/fundamental_type_info.cc and lived
>>> in the CXXABI_1.3.4 version.  However, since Solaris *does* lack DFP
>>> support, that's no longer the case.  I'm uncertain how best to deal with
>>> this, however.
>>
>>As I understand it, _GLIBCXX_USE_DECIMAL_FLOAT should already have been
>>undefined for this target, and so std::decimal::decimal32 etc. should not
>>have been usable (both the header not working without that define, and the
>>mode attributes in the header being rejected by the front end when DFP is
>>unsupported).  I.e. such defines in libsupc++ would never have been usable
>>on this target, so I think they are something it should be safe to remove
>>from the ABI baseline.
>
> If it's actually impossible that any real program could have depended
> on those symbols, then I agree.

this is exactly what I've got no way of telling, that's why I was asking
for guidance.  Just removing the DFP symbols from the baselines works,
of course.

	Rainer
Joseph Myers Nov. 27, 2019, 5:48 p.m. UTC | #7
On Wed, 27 Nov 2019, Rainer Orth wrote:

> Hi Jonathan,
> 
> > On 26/11/19 00:57 +0000, Joseph Myers wrote:
> >>On Mon, 25 Nov 2019, Rainer Orth wrote:
> >>
> >>> and a few more, all DFP related.  They used to be emitted by g++ for
> >>> __fundamental_type_info in libsupc++/fundamental_type_info.cc and lived
> >>> in the CXXABI_1.3.4 version.  However, since Solaris *does* lack DFP
> >>> support, that's no longer the case.  I'm uncertain how best to deal with
> >>> this, however.
> >>
> >>As I understand it, _GLIBCXX_USE_DECIMAL_FLOAT should already have been
> >>undefined for this target, and so std::decimal::decimal32 etc. should not
> >>have been usable (both the header not working without that define, and the
> >>mode attributes in the header being rejected by the front end when DFP is
> >>unsupported).  I.e. such defines in libsupc++ would never have been usable
> >>on this target, so I think they are something it should be safe to remove
> >>from the ABI baseline.
> >
> > If it's actually impossible that any real program could have depended
> > on those symbols, then I agree.
> 
> this is exactly what I've got no way of telling, that's why I was asking
> for guidance.  Just removing the DFP symbols from the baselines works,
> of course.

I don't think any real program could have used those symbols; it would 
have required using __typeof (__builtin_fabsd32 (0)) or similar to access 
types that weren't normally available for those targets (and by accessing 
the types using builtins like that, you're getting a completely undefined 
function-calling ABI for them anyway).
Jakub Jelinek Nov. 27, 2019, 6 p.m. UTC | #8
On Wed, Nov 27, 2019 at 05:48:21PM +0000, Joseph Myers wrote:
> > > On 26/11/19 00:57 +0000, Joseph Myers wrote:
> > >>On Mon, 25 Nov 2019, Rainer Orth wrote:
> > >>
> > >>> and a few more, all DFP related.  They used to be emitted by g++ for
> > >>> __fundamental_type_info in libsupc++/fundamental_type_info.cc and lived
> > >>> in the CXXABI_1.3.4 version.  However, since Solaris *does* lack DFP
> > >>> support, that's no longer the case.  I'm uncertain how best to deal with
> > >>> this, however.
> > >>
> > >>As I understand it, _GLIBCXX_USE_DECIMAL_FLOAT should already have been
> > >>undefined for this target, and so std::decimal::decimal32 etc. should not
> > >>have been usable (both the header not working without that define, and the
> > >>mode attributes in the header being rejected by the front end when DFP is
> > >>unsupported).  I.e. such defines in libsupc++ would never have been usable
> > >>on this target, so I think they are something it should be safe to remove
> > >>from the ABI baseline.
> > >
> > > If it's actually impossible that any real program could have depended
> > > on those symbols, then I agree.
> > 
> > this is exactly what I've got no way of telling, that's why I was asking
> > for guidance.  Just removing the DFP symbols from the baselines works,
> > of course.
> 
> I don't think any real program could have used those symbols; it would 
> have required using __typeof (__builtin_fabsd32 (0)) or similar to access 
> types that weren't normally available for those targets (and by accessing 
> the types using builtins like that, you're getting a completely undefined 
> function-calling ABI for them anyway).

I think various tools we use to check ABI will be unhappy about removal
of symbols.  Can't we on targets that do support aliases and don't support
decimal float e.g. alias the DFP rtti symbols to void rtti symbols?

	Jakub
Thomas Schwinge Nov. 27, 2019, 9:49 p.m. UTC | #9
Hi!

Re <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91985#c4>, which reports
(and I hereby confirm) that these changes quoted below introduce "lto1:
internal compiler error" for (at least) nvptx offloading, and such a
backtrace seemed vaguely familiar, and I did remember having fixed a
similar issue before, and indeed it seems to be another instance of such
a problem.  In particular, and assuming that I'm understanding this
correctly, the following part of the changes (for brevity formatted with
'diff --ignore-space-change'):

    --- gcc/tree.c
    +++ gcc/tree.c
    @@ -10334,6 +10334,8 @@ build_common_tree_nodes (bool signed_char)
       uint64_type_node = make_or_reuse_type (64, 1);
     
       /* Decimal float types. */
    +  if (targetm.decimal_float_supported_p ())
    +    {
           dfloat32_type_node = make_node (REAL_TYPE);
           TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE;
           SET_TYPE_MODE (dfloat32_type_node, SDmode);
    @@ -10351,6 +10353,7 @@ build_common_tree_nodes (bool signed_char)
           SET_TYPE_MODE (dfloat128_type_node, TDmode);
           layout_type (dfloat128_type_node);
           dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
    +    }
     
       complex_integer_type_node = build_complex_type (integer_type_node, true);
       complex_float_type_node = build_complex_type (float_type_node, true);

... does introduce a mismatch in the 'preload_common_nodes' between
target (for example, x86_64-pc-linux-gnu with
'targetm.decimal_float_supported_p'), and the offload target (for
example, nvptx-none without 'targetm.decimal_float_supported_p'), and
then LTO read-in explodes because the codes are then offset between
producer (target) and consumer (offload target).

For reference/context of the previous issue, see
<http://mid.mail-archive.com/87twdgb9zi.fsf@hertz.schwinge.homeip.net>,
and following messages.

If I turn that conditional cited above into 'if (1)', then nvptx
offloading testing seems to return to normality, but I have not yet
assessed whether that has any ill effects on decimal float types support,
and/or how this should be fixed properly.  (Julian, please have a look,
if you can, or tell me if you're busy with other things.)


For reference:

On 2019-11-22T16:40:01+0000, Joseph Myers <joseph@codesourcery.com> wrote:
> Code that directly uses _Decimal* types on architectures not
> supporting DFP is properly diagnosed ("error: decimal floating-point
> not supported for this target"), via a call to
> targetm.decimal_float_supported_p, if the _Decimal32, _Decimal64 or
> _Decimal128 keywords are used to access it.  Use via mode attributes
> is also diagnosed ("unable to emulate 'SD'"); so is use of the
> FLOAT_CONST_DECIMAL64 pragma.  However, it is possible to access those
> types via typeof applied to constants or built-in functions without
> such an error.  I expect that there are ways to get an ICE from this;
> certainly it uses a completely undefined ABI.
>
> This patch arranges for the types not to exist in the compiler at all
> when DFP is not supported.  As is done with unsupported _FloatN /
> _FloatNx types, the global tree nodes are left as NULL_TREE, and the
> built-in function machinery is made to use error_mark_node for them in
> that case in builtin-types.def, so that the built-in functions are
> unavailable.  Code handling constants is adjusted to give an error,
> and other code that might not work with the global tree nodes being
> NULL_TREE is also updated.
>
> Bootstrapped with no regressions for x86_64-pc-linux-gnu.  Also tested
> with no regressions for cross to aarch64-linux-gnu, as a configuration
> without DFP support.  OK to commit (the changes that aren't C front-end 
> changes)?
>
> gcc:
> 2019-11-22  Joseph Myers  <joseph@codesourcery.com>
>
> 	PR c/91985
> 	* builtin-types.def (BT_DFLOAT32, BT_DFLOAT64, BT_DFLOAT128)
> 	(BT_DFLOAT32_PTR, BT_DFLOAT64_PTR, BT_DFLOAT128_PTR): Define to
> 	error_mark_node if corresponding global tree node is NULL.
> 	* tree.c (build_common_tree_nodes): Do not initialize
> 	dfloat32_type_node, dfloat64_type_node or dfloat128_type_node if
> 	decimal floating-point not supported.
>
> gcc/c:
> 2019-11-22  Joseph Myers  <joseph@codesourcery.com>
>
> 	PR c/91985
> 	* c-decl.c (finish_declspecs): Use int instead of decimal
> 	floating-point types if decimal floating-point not supported.
>
> gcc/c-family:
> 2019-11-22  Joseph Myers  <joseph@codesourcery.com>
>
> 	PR c/91985
> 	* c-common.c (c_common_type_for_mode): Handle decimal
> 	floating-point types being NULL_TREE.
> 	* c-format.c (get_format_for_type_1): Handle specified types being
> 	NULL_TREE.
> 	* c-lex.c (interpret_float): Give an error for decimal
> 	floating-point constants when decimal floating-point not
> 	supported.
>
> gcc/lto:
> 2019-11-22  Joseph Myers  <joseph@codesourcery.com>
>
> 	PR c/91985
> 	* lto-lang.c (lto_type_for_mode): Handle decimal floating-point
> 	types being NULL_TREE.
>
> gcc/testsuite:
> 2019-11-22  Joseph Myers  <joseph@codesourcery.com>
>
> 	PR c/91985
> 	* gcc.dg/c2x-no-dfp-1.c, gcc.dg/gnu2x-builtins-no-dfp-1.c: New
> 	tests.
> 	* gcc.dg/fltconst-pedantic-dfp.c: Expect errors when decimal
> 	floating-point not supported.
>
> Index: gcc/builtin-types.def
> ===================================================================
> --- gcc/builtin-types.def	(revision 278603)
> +++ gcc/builtin-types.def	(working copy)
> @@ -136,12 +136,24 @@ DEF_PRIMITIVE_TYPE (BT_WINT, wint_type_node)
>  DEF_PRIMITIVE_TYPE (BT_STRING, string_type_node)
>  DEF_PRIMITIVE_TYPE (BT_CONST_STRING, const_string_type_node)
>  
> -DEF_PRIMITIVE_TYPE (BT_DFLOAT32, dfloat32_type_node)
> -DEF_PRIMITIVE_TYPE (BT_DFLOAT64, dfloat64_type_node)
> -DEF_PRIMITIVE_TYPE (BT_DFLOAT128, dfloat128_type_node)
> -DEF_PRIMITIVE_TYPE (BT_DFLOAT32_PTR, dfloat32_ptr_type_node)
> -DEF_PRIMITIVE_TYPE (BT_DFLOAT64_PTR, dfloat64_ptr_type_node)
> -DEF_PRIMITIVE_TYPE (BT_DFLOAT128_PTR, dfloat128_ptr_type_node)
> +DEF_PRIMITIVE_TYPE (BT_DFLOAT32, (dfloat32_type_node
> +				  ? dfloat32_type_node
> +				  : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_DFLOAT64, (dfloat64_type_node
> +				  ? dfloat64_type_node
> +				  : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_DFLOAT128, (dfloat128_type_node
> +				   ? dfloat128_type_node
> +				   : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_DFLOAT32_PTR, (dfloat32_ptr_type_node
> +				      ? dfloat32_ptr_type_node
> +				      : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_DFLOAT64_PTR, (dfloat64_ptr_type_node
> +				      ? dfloat64_ptr_type_node
> +				      : error_mark_node))
> +DEF_PRIMITIVE_TYPE (BT_DFLOAT128_PTR, (dfloat128_ptr_type_node
> +				       ? dfloat128_ptr_type_node
> +				       : error_mark_node))
>  
>  DEF_PRIMITIVE_TYPE (BT_VALIST_REF, va_list_ref_type_node)
>  DEF_PRIMITIVE_TYPE (BT_VALIST_ARG, va_list_arg_type_node)
> Index: gcc/c/c-decl.c
> ===================================================================
> --- gcc/c/c-decl.c	(revision 278603)
> +++ gcc/c/c-decl.c	(working copy)
> @@ -11619,7 +11619,9 @@ finish_declspecs (struct c_declspecs *specs)
>      case cts_dfloat128:
>        gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p
>  		  && !specs->signed_p && !specs->unsigned_p && !specs->complex_p);
> -      if (specs->typespec_word == cts_dfloat32)
> +      if (!targetm.decimal_float_supported_p ())
> +	specs->type = integer_type_node;
> +      else if (specs->typespec_word == cts_dfloat32)
>  	specs->type = dfloat32_type_node;
>        else if (specs->typespec_word == cts_dfloat64)
>  	specs->type = dfloat64_type_node;
> Index: gcc/c-family/c-common.c
> ===================================================================
> --- gcc/c-family/c-common.c	(revision 278603)
> +++ gcc/c-family/c-common.c	(working copy)
> @@ -2321,11 +2321,14 @@ c_common_type_for_mode (machine_mode mode, int uns
>  	return build_vector_type_for_mode (inner_type, mode);
>      }
>  
> -  if (mode == TYPE_MODE (dfloat32_type_node))
> +  if (dfloat32_type_node != NULL_TREE
> +      && mode == TYPE_MODE (dfloat32_type_node))
>      return dfloat32_type_node;
> -  if (mode == TYPE_MODE (dfloat64_type_node))
> +  if (dfloat64_type_node != NULL_TREE
> +      && mode == TYPE_MODE (dfloat64_type_node))
>      return dfloat64_type_node;
> -  if (mode == TYPE_MODE (dfloat128_type_node))
> +  if (dfloat128_type_node != NULL_TREE
> +      && mode == TYPE_MODE (dfloat128_type_node))
>      return dfloat128_type_node;
>  
>    if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
> Index: gcc/c-family/c-format.c
> ===================================================================
> --- gcc/c-family/c-format.c	(revision 278603)
> +++ gcc/c-family/c-format.c	(working copy)
> @@ -4390,7 +4390,7 @@ get_format_for_type_1 (const format_kind_info *fki
>        for (int i = 0; i < FMT_LEN_MAX; i++)
>  	{
>  	  const format_type_detail *ftd = &spec->types[i];
> -	  if (!ftd->type)
> +	  if (!ftd->type || *ftd->type == NULL_TREE)
>  	    continue;
>  	  if (matching_type_p (*ftd->type, effective_arg_type))
>  	    {
> Index: gcc/c-family/c-lex.c
> ===================================================================
> --- gcc/c-family/c-lex.c	(revision 278603)
> +++ gcc/c-family/c-lex.c	(working copy)
> @@ -877,7 +877,12 @@ interpret_float (const cpp_token *token, unsigned
>  
>    /* Decode type based on width and properties. */
>    if (flags & CPP_N_DFLOAT)
> -    if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
> +    if (!targetm.decimal_float_supported_p ())
> +      {
> +	error ("decimal floating-point not supported for this target");
> +	return error_mark_node;
> +      }
> +    else if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
>        type = dfloat128_type_node;
>      else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
>        type = dfloat32_type_node;
> Index: gcc/lto/lto-lang.c
> ===================================================================
> --- gcc/lto/lto-lang.c	(revision 278603)
> +++ gcc/lto/lto-lang.c	(working copy)
> @@ -1051,11 +1051,14 @@ lto_type_for_mode (machine_mode mode, int unsigned
>  	return build_vector_type_for_mode (inner_type, mode);
>      }
>  
> -  if (mode == TYPE_MODE (dfloat32_type_node))
> +  if (dfloat32_type_node != NULL_TREE
> +      && mode == TYPE_MODE (dfloat32_type_node))
>      return dfloat32_type_node;
> -  if (mode == TYPE_MODE (dfloat64_type_node))
> +  if (dfloat64_type_node != NULL_TREE
> +      && mode == TYPE_MODE (dfloat64_type_node))
>      return dfloat64_type_node;
> -  if (mode == TYPE_MODE (dfloat128_type_node))
> +  if (dfloat128_type_node != NULL_TREE
> +      && mode == TYPE_MODE (dfloat128_type_node))
>      return dfloat128_type_node;
>  
>    if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
> Index: gcc/testsuite/gcc.dg/c2x-no-dfp-1.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/c2x-no-dfp-1.c	(nonexistent)
> +++ gcc/testsuite/gcc.dg/c2x-no-dfp-1.c	(working copy)
> @@ -0,0 +1,12 @@
> +/* Test DFP types and constants rejected if no DFP support.  Bug
> +   91985.  */
> +/* { dg-do compile { target { ! dfp } } } */
> +/* { dg-options "-std=c2x" } */
> +
> +_Decimal32 d32a; /* { dg-error "not supported" } */
> +_Decimal64 d64a; /* { dg-error "not supported" } */
> +_Decimal128 d128a; /* { dg-error "not supported" } */
> +
> +_Bool d32b = 1.0DF; /* { dg-error "not supported" } */
> +_Bool d64b = 1.0DD; /* { dg-error "not supported" } */
> +_Bool d128b = 1.0DL; /* { dg-error "not supported" } */
> Index: gcc/testsuite/gcc.dg/fltconst-pedantic-dfp.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/fltconst-pedantic-dfp.c	(revision 278603)
> +++ gcc/testsuite/gcc.dg/fltconst-pedantic-dfp.c	(working copy)
> @@ -2,5 +2,8 @@
>  /* { dg-options "-pedantic" } */
>  
>  double a = 1.dl;	/* { dg-warning "decimal float" } */
> +/* { dg-error "not supported for this target" "not supported" { target { ! dfp } } .-1 } */
>  double b = 1.df;	/* { dg-warning "decimal float" } */
> +/* { dg-error "not supported for this target" "not supported" { target { ! dfp } } .-1 } */
>  double c = 1.dd;	/* { dg-warning "decimal float" } */
> +/* { dg-error "not supported for this target" "not supported" { target { ! dfp } } .-1 } */
> Index: gcc/testsuite/gcc.dg/gnu2x-builtins-no-dfp-1.c
> ===================================================================
> --- gcc/testsuite/gcc.dg/gnu2x-builtins-no-dfp-1.c	(nonexistent)
> +++ gcc/testsuite/gcc.dg/gnu2x-builtins-no-dfp-1.c	(working copy)
> @@ -0,0 +1,18 @@
> +/* Test C2x built-in functions: test DFP built-in functions are not
> +   available when no DFP support.  Bug 91985.  */
> +/* { dg-do compile { target { ! dfp } } } */
> +/* { dg-options "-std=gnu2x" } */
> +
> +int fabsd32 (void);
> +int fabsd64 (void);
> +int fabsd128 (void);
> +int nand32 (void);
> +int nand64 (void);
> +int nand128 (void);
> +
> +__typeof__ (__builtin_fabsd32 (0)) d32; /* { dg-warning "implicit" } */
> +__typeof__ (__builtin_fabsd64 (0)) d64; /* { dg-warning "implicit" } */
> +__typeof__ (__builtin_fabsd128 (0)) d128; /* { dg-warning "implicit" } */
> +__typeof__ (__builtin_nand32 (0)) d32n; /* { dg-warning "implicit" } */
> +__typeof__ (__builtin_nand64 (0)) d64n; /* { dg-warning "implicit" } */
> +__typeof__ (__builtin_nand128 (0)) d128n; /* { dg-warning "implicit" } */
> Index: gcc/tree.c
> ===================================================================
> --- gcc/tree.c	(revision 278603)
> +++ gcc/tree.c	(working copy)
> @@ -10334,23 +10334,26 @@ build_common_tree_nodes (bool signed_char)
>    uint64_type_node = make_or_reuse_type (64, 1);
>  
>    /* Decimal float types. */
> -  dfloat32_type_node = make_node (REAL_TYPE);
> -  TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE;
> -  SET_TYPE_MODE (dfloat32_type_node, SDmode);
> -  layout_type (dfloat32_type_node);
> -  dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node);
> +  if (targetm.decimal_float_supported_p ())
> +    {
> +      dfloat32_type_node = make_node (REAL_TYPE);
> +      TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE;
> +      SET_TYPE_MODE (dfloat32_type_node, SDmode);
> +      layout_type (dfloat32_type_node);
> +      dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node);
>  
> -  dfloat64_type_node = make_node (REAL_TYPE);
> -  TYPE_PRECISION (dfloat64_type_node) = DECIMAL64_TYPE_SIZE;
> -  SET_TYPE_MODE (dfloat64_type_node, DDmode);
> -  layout_type (dfloat64_type_node);
> -  dfloat64_ptr_type_node = build_pointer_type (dfloat64_type_node);
> +      dfloat64_type_node = make_node (REAL_TYPE);
> +      TYPE_PRECISION (dfloat64_type_node) = DECIMAL64_TYPE_SIZE;
> +      SET_TYPE_MODE (dfloat64_type_node, DDmode);
> +      layout_type (dfloat64_type_node);
> +      dfloat64_ptr_type_node = build_pointer_type (dfloat64_type_node);
>  
> -  dfloat128_type_node = make_node (REAL_TYPE);
> -  TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE;
> -  SET_TYPE_MODE (dfloat128_type_node, TDmode);
> -  layout_type (dfloat128_type_node);
> -  dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
> +      dfloat128_type_node = make_node (REAL_TYPE);
> +      TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE;
> +      SET_TYPE_MODE (dfloat128_type_node, TDmode);
> +      layout_type (dfloat128_type_node);
> +      dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
> +    }
>  
>    complex_integer_type_node = build_complex_type (integer_type_node, true);
>    complex_float_type_node = build_complex_type (float_type_node, true);


Grüße
 Thomas
Joseph Myers Nov. 27, 2019, 10:33 p.m. UTC | #10
On Wed, 27 Nov 2019, Thomas Schwinge wrote:

> If I turn that conditional cited above into 'if (1)', then nvptx
> offloading testing seems to return to normality, but I have not yet
> assessed whether that has any ill effects on decimal float types support,
> and/or how this should be fixed properly.  (Julian, please have a look,
> if you can, or tell me if you're busy with other things.)

Whatever allows this to work for _FloatN types (when x86_64 supports 
_Float128 but nxptx doesn't, for example) should be applied to the DFP 
types as well.
Thomas Schwinge Nov. 28, 2019, 2:13 p.m. UTC | #11
Hi!

So, testing just finished, and indeed:

On 2019-11-27T22:33:25+0000, Joseph Myers <joseph@codesourcery.com> wrote:
> On Wed, 27 Nov 2019, Thomas Schwinge wrote:
>
>> If I turn that conditional cited above into 'if (1)', then nvptx
>> offloading testing seems to return to normality, but I have not yet
>> assessed whether that has any ill effects on decimal float types support,

... this (see attached) doesn't disturb x86_64-pc-linux-gnu (with nvptx
offloading) as well as powerpc64le-unknown-linux-gnu (without offloading)
tests in any way.

>> and/or how this should be fixed properly.  (Julian, please have a look,
>> if you can, or tell me if you're busy with other things.)
>
> Whatever allows this to work for _FloatN types (when x86_64 supports 
> _Float128 but nxptx doesn't, for example) should be applied to the DFP 
> types as well.

Joseph, Julian, or anyone else, please review if that's (conceptually)
the correct fix, and before commit, I'll then remove the 'if'
conditional, and re-indent, obviously.  If approving this patch
(conceptually), please respond with "Reviewed-by: NAME <EMAIL>" so that
your effort will be recorded in the commit log, see
<https://gcc.gnu.org/wiki/Reviewed-by>.


Grüße
 Thomas

Patch
diff mbox series

Index: gcc/builtin-types.def
===================================================================
--- gcc/builtin-types.def	(revision 278603)
+++ gcc/builtin-types.def	(working copy)
@@ -136,12 +136,24 @@  DEF_PRIMITIVE_TYPE (BT_WINT, wint_type_node)
 DEF_PRIMITIVE_TYPE (BT_STRING, string_type_node)
 DEF_PRIMITIVE_TYPE (BT_CONST_STRING, const_string_type_node)
 
-DEF_PRIMITIVE_TYPE (BT_DFLOAT32, dfloat32_type_node)
-DEF_PRIMITIVE_TYPE (BT_DFLOAT64, dfloat64_type_node)
-DEF_PRIMITIVE_TYPE (BT_DFLOAT128, dfloat128_type_node)
-DEF_PRIMITIVE_TYPE (BT_DFLOAT32_PTR, dfloat32_ptr_type_node)
-DEF_PRIMITIVE_TYPE (BT_DFLOAT64_PTR, dfloat64_ptr_type_node)
-DEF_PRIMITIVE_TYPE (BT_DFLOAT128_PTR, dfloat128_ptr_type_node)
+DEF_PRIMITIVE_TYPE (BT_DFLOAT32, (dfloat32_type_node
+				  ? dfloat32_type_node
+				  : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_DFLOAT64, (dfloat64_type_node
+				  ? dfloat64_type_node
+				  : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_DFLOAT128, (dfloat128_type_node
+				   ? dfloat128_type_node
+				   : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_DFLOAT32_PTR, (dfloat32_ptr_type_node
+				      ? dfloat32_ptr_type_node
+				      : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_DFLOAT64_PTR, (dfloat64_ptr_type_node
+				      ? dfloat64_ptr_type_node
+				      : error_mark_node))
+DEF_PRIMITIVE_TYPE (BT_DFLOAT128_PTR, (dfloat128_ptr_type_node
+				       ? dfloat128_ptr_type_node
+				       : error_mark_node))
 
 DEF_PRIMITIVE_TYPE (BT_VALIST_REF, va_list_ref_type_node)
 DEF_PRIMITIVE_TYPE (BT_VALIST_ARG, va_list_arg_type_node)
Index: gcc/c/c-decl.c
===================================================================
--- gcc/c/c-decl.c	(revision 278603)
+++ gcc/c/c-decl.c	(working copy)
@@ -11619,7 +11619,9 @@  finish_declspecs (struct c_declspecs *specs)
     case cts_dfloat128:
       gcc_assert (!specs->long_p && !specs->long_long_p && !specs->short_p
 		  && !specs->signed_p && !specs->unsigned_p && !specs->complex_p);
-      if (specs->typespec_word == cts_dfloat32)
+      if (!targetm.decimal_float_supported_p ())
+	specs->type = integer_type_node;
+      else if (specs->typespec_word == cts_dfloat32)
 	specs->type = dfloat32_type_node;
       else if (specs->typespec_word == cts_dfloat64)
 	specs->type = dfloat64_type_node;
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 278603)
+++ gcc/c-family/c-common.c	(working copy)
@@ -2321,11 +2321,14 @@  c_common_type_for_mode (machine_mode mode, int uns
 	return build_vector_type_for_mode (inner_type, mode);
     }
 
-  if (mode == TYPE_MODE (dfloat32_type_node))
+  if (dfloat32_type_node != NULL_TREE
+      && mode == TYPE_MODE (dfloat32_type_node))
     return dfloat32_type_node;
-  if (mode == TYPE_MODE (dfloat64_type_node))
+  if (dfloat64_type_node != NULL_TREE
+      && mode == TYPE_MODE (dfloat64_type_node))
     return dfloat64_type_node;
-  if (mode == TYPE_MODE (dfloat128_type_node))
+  if (dfloat128_type_node != NULL_TREE
+      && mode == TYPE_MODE (dfloat128_type_node))
     return dfloat128_type_node;
 
   if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
Index: gcc/c-family/c-format.c
===================================================================
--- gcc/c-family/c-format.c	(revision 278603)
+++ gcc/c-family/c-format.c	(working copy)
@@ -4390,7 +4390,7 @@  get_format_for_type_1 (const format_kind_info *fki
       for (int i = 0; i < FMT_LEN_MAX; i++)
 	{
 	  const format_type_detail *ftd = &spec->types[i];
-	  if (!ftd->type)
+	  if (!ftd->type || *ftd->type == NULL_TREE)
 	    continue;
 	  if (matching_type_p (*ftd->type, effective_arg_type))
 	    {
Index: gcc/c-family/c-lex.c
===================================================================
--- gcc/c-family/c-lex.c	(revision 278603)
+++ gcc/c-family/c-lex.c	(working copy)
@@ -877,7 +877,12 @@  interpret_float (const cpp_token *token, unsigned
 
   /* Decode type based on width and properties. */
   if (flags & CPP_N_DFLOAT)
-    if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
+    if (!targetm.decimal_float_supported_p ())
+      {
+	error ("decimal floating-point not supported for this target");
+	return error_mark_node;
+      }
+    else if ((flags & CPP_N_WIDTH) == CPP_N_LARGE)
       type = dfloat128_type_node;
     else if ((flags & CPP_N_WIDTH) == CPP_N_SMALL)
       type = dfloat32_type_node;
Index: gcc/lto/lto-lang.c
===================================================================
--- gcc/lto/lto-lang.c	(revision 278603)
+++ gcc/lto/lto-lang.c	(working copy)
@@ -1051,11 +1051,14 @@  lto_type_for_mode (machine_mode mode, int unsigned
 	return build_vector_type_for_mode (inner_type, mode);
     }
 
-  if (mode == TYPE_MODE (dfloat32_type_node))
+  if (dfloat32_type_node != NULL_TREE
+      && mode == TYPE_MODE (dfloat32_type_node))
     return dfloat32_type_node;
-  if (mode == TYPE_MODE (dfloat64_type_node))
+  if (dfloat64_type_node != NULL_TREE
+      && mode == TYPE_MODE (dfloat64_type_node))
     return dfloat64_type_node;
-  if (mode == TYPE_MODE (dfloat128_type_node))
+  if (dfloat128_type_node != NULL_TREE
+      && mode == TYPE_MODE (dfloat128_type_node))
     return dfloat128_type_node;
 
   if (ALL_SCALAR_FIXED_POINT_MODE_P (mode))
Index: gcc/testsuite/gcc.dg/c2x-no-dfp-1.c
===================================================================
--- gcc/testsuite/gcc.dg/c2x-no-dfp-1.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/c2x-no-dfp-1.c	(working copy)
@@ -0,0 +1,12 @@ 
+/* Test DFP types and constants rejected if no DFP support.  Bug
+   91985.  */
+/* { dg-do compile { target { ! dfp } } } */
+/* { dg-options "-std=c2x" } */
+
+_Decimal32 d32a; /* { dg-error "not supported" } */
+_Decimal64 d64a; /* { dg-error "not supported" } */
+_Decimal128 d128a; /* { dg-error "not supported" } */
+
+_Bool d32b = 1.0DF; /* { dg-error "not supported" } */
+_Bool d64b = 1.0DD; /* { dg-error "not supported" } */
+_Bool d128b = 1.0DL; /* { dg-error "not supported" } */
Index: gcc/testsuite/gcc.dg/fltconst-pedantic-dfp.c
===================================================================
--- gcc/testsuite/gcc.dg/fltconst-pedantic-dfp.c	(revision 278603)
+++ gcc/testsuite/gcc.dg/fltconst-pedantic-dfp.c	(working copy)
@@ -2,5 +2,8 @@ 
 /* { dg-options "-pedantic" } */
 
 double a = 1.dl;	/* { dg-warning "decimal float" } */
+/* { dg-error "not supported for this target" "not supported" { target { ! dfp } } .-1 } */
 double b = 1.df;	/* { dg-warning "decimal float" } */
+/* { dg-error "not supported for this target" "not supported" { target { ! dfp } } .-1 } */
 double c = 1.dd;	/* { dg-warning "decimal float" } */
+/* { dg-error "not supported for this target" "not supported" { target { ! dfp } } .-1 } */
Index: gcc/testsuite/gcc.dg/gnu2x-builtins-no-dfp-1.c
===================================================================
--- gcc/testsuite/gcc.dg/gnu2x-builtins-no-dfp-1.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/gnu2x-builtins-no-dfp-1.c	(working copy)
@@ -0,0 +1,18 @@ 
+/* Test C2x built-in functions: test DFP built-in functions are not
+   available when no DFP support.  Bug 91985.  */
+/* { dg-do compile { target { ! dfp } } } */
+/* { dg-options "-std=gnu2x" } */
+
+int fabsd32 (void);
+int fabsd64 (void);
+int fabsd128 (void);
+int nand32 (void);
+int nand64 (void);
+int nand128 (void);
+
+__typeof__ (__builtin_fabsd32 (0)) d32; /* { dg-warning "implicit" } */
+__typeof__ (__builtin_fabsd64 (0)) d64; /* { dg-warning "implicit" } */
+__typeof__ (__builtin_fabsd128 (0)) d128; /* { dg-warning "implicit" } */
+__typeof__ (__builtin_nand32 (0)) d32n; /* { dg-warning "implicit" } */
+__typeof__ (__builtin_nand64 (0)) d64n; /* { dg-warning "implicit" } */
+__typeof__ (__builtin_nand128 (0)) d128n; /* { dg-warning "implicit" } */
Index: gcc/tree.c
===================================================================
--- gcc/tree.c	(revision 278603)
+++ gcc/tree.c	(working copy)
@@ -10334,23 +10334,26 @@  build_common_tree_nodes (bool signed_char)
   uint64_type_node = make_or_reuse_type (64, 1);
 
   /* Decimal float types. */
-  dfloat32_type_node = make_node (REAL_TYPE);
-  TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE;
-  SET_TYPE_MODE (dfloat32_type_node, SDmode);
-  layout_type (dfloat32_type_node);
-  dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node);
+  if (targetm.decimal_float_supported_p ())
+    {
+      dfloat32_type_node = make_node (REAL_TYPE);
+      TYPE_PRECISION (dfloat32_type_node) = DECIMAL32_TYPE_SIZE;
+      SET_TYPE_MODE (dfloat32_type_node, SDmode);
+      layout_type (dfloat32_type_node);
+      dfloat32_ptr_type_node = build_pointer_type (dfloat32_type_node);
 
-  dfloat64_type_node = make_node (REAL_TYPE);
-  TYPE_PRECISION (dfloat64_type_node) = DECIMAL64_TYPE_SIZE;
-  SET_TYPE_MODE (dfloat64_type_node, DDmode);
-  layout_type (dfloat64_type_node);
-  dfloat64_ptr_type_node = build_pointer_type (dfloat64_type_node);
+      dfloat64_type_node = make_node (REAL_TYPE);
+      TYPE_PRECISION (dfloat64_type_node) = DECIMAL64_TYPE_SIZE;
+      SET_TYPE_MODE (dfloat64_type_node, DDmode);
+      layout_type (dfloat64_type_node);
+      dfloat64_ptr_type_node = build_pointer_type (dfloat64_type_node);
 
-  dfloat128_type_node = make_node (REAL_TYPE);
-  TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE;
-  SET_TYPE_MODE (dfloat128_type_node, TDmode);
-  layout_type (dfloat128_type_node);
-  dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
+      dfloat128_type_node = make_node (REAL_TYPE);
+      TYPE_PRECISION (dfloat128_type_node) = DECIMAL128_TYPE_SIZE;
+      SET_TYPE_MODE (dfloat128_type_node, TDmode);
+      layout_type (dfloat128_type_node);
+      dfloat128_ptr_type_node = build_pointer_type (dfloat128_type_node);
+    }
 
   complex_integer_type_node = build_complex_type (integer_type_node, true);
   complex_float_type_node = build_complex_type (float_type_node, true);