Possible Fortran testsuite failures for default_format_*.f90

2007-10-06 Thread FX Coudert

Hi,

A reworking of Fortran testcases might lead to the following cases  
failing (or starting to fail):


  * gfortran.dg/default_format_1.f90
  * gfortran.dg/default_format_2.f90
  * gfortran.dg/default_format_denormal_1.f90
  * gfortran.dg/default_format_denormal_2.f90

This would indicate an issue with the target printf() implementation,  
so if you spot these failures on your favorite target, please report  
them to the [EMAIL PROTECTED] mailing-list so that we can xfail them.


Thanks,
FX


cgraph, unit-at-a-time, and the "used" attribute

2007-10-06 Thread Gary Funck

While working on UPC, we ran into an interesting problem
where if -O1 is enabled, and -funit-at-a-time is disabled
(which is not the default configuration) a static variable
declaration was not emitted by the assembler.  I haven't
quite worked out why this is the case, but reading the
code did notice some awkwardness in how "used" variables
are detected and handled by the call graph (cgraph) pass(es).

The gist of the issue we ran into was the handling of
this UPC construct:
  {static shared strict int x; x = x; }
In UPC, "strict" is similar to volatile.  The assignment
of the dummy variable to itself above doesn't do anything
very useful, but it does enforce a memory fence that
ensures that remote reads and writes to UPC shared
space can't flow past the assignment above.

The UPC compiler runs a gimplify pass which finds
all UPC-isms and rewrites them into C-isms, which
then flow through the backend.  The assignment
above is loosely translated into:
  upc_put([0, 0, &x], upc_get([0, 0, &x], sizeof(x)));
where [0, 0, &x] is an aggregate consstructor that
builds the representation of a shared pointer having
a thread number of 0, a phase of 0, and a virtual
address of &x.  All UPC shared vairables are located
in a special linkage section.  In this way, &x points
to a location in the global shared address space,
and the linker lays out each thread's contribution to
the global shared address.

The difficulty comes in when we generate the runtime
calls above referring to &x, by referring to a shadow
variable we create (by necessity, to prevent infinite
recursion in the gimplify pass) that has the same external
name as 'x', with the shared qualifier removed.

What happens is that cgraph has already been run and
determined that 'x' isn't needed and therefore
it doesn't emit the declaration of 'x' into the generated
assembler code.  We tried asserting TREE_USED()
on 'x' when it was declared, but it turns out
that instead of referring to TREE_USED() or
even DECL_PRESERVE_P(), cgraph instead refers
directly to the "used" attribute. 

Because of this, if __attribute__ ((used)) is added to the
declaration above, all is well.  That is because the front-end
checks directly for the "used" attribute in various places
but seems not to check various tree flags.

Here are the relevant references (in the HEAD branch):

c-decl.c-}
c-decl.c-
c-decl.c-  /* If this was marked 'used', be sure it will be output.  */
c-decl.c:  if (!flag_unit_at_a_time && lookup_attribute ("used", 
DECL_ATTRIBUTES (decl)))
c-decl.c-mark_decl_referenced (decl);
c-decl.c-
c-decl.c-  if (TREE_CODE (decl) == TYPE_DECL)
--
cgraphunit.c-  if (node->local.externally_visible)
cgraphunit.c-return true;
cgraphunit.c-
cgraphunit.c:  if (!flag_unit_at_a_time && lookup_attribute ("used", 
DECL_ATTRIBUTES (decl)))
cgraphunit.c-return true;
cgraphunit.c-
cgraphunit.c-  /* ??? If the assembler name is set by hand, it is possible to 
assemble
--
cgraphunit.c-  for (node = cgraph_nodes; node != first; node = node->next)
cgraphunit.c-{
cgraphunit.c-  tree decl = node->decl;
cgraphunit.c:  if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
cgraphunit.c-   {
cgraphunit.c- mark_decl_referenced (decl);
cgraphunit.c- if (node->local.finalized)
--
cgraphunit.c-  for (vnode = varpool_nodes; vnode != first_var; vnode = 
vnode->next)
cgraphunit.c-{
cgraphunit.c-  tree decl = vnode->decl;
cgraphunit.c:  if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
cgraphunit.c-   {
cgraphunit.c- mark_decl_referenced (decl);
cgraphunit.c- if (vnode->finalized)
--
ipa-pure-const.c-{
ipa-pure-const.c-  /* If the variable has the "used" attribute, treat it as if 
it had a
ipa-pure-const.c- been touched by the devil.  */
ipa-pure-const.c:  if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
ipa-pure-const.c-{
ipa-pure-const.c-  local->pure_const_state = IPA_NEITHER;
ipa-pure-const.c-  return;
--
ipa-reference.c-{
ipa-reference.c-  /* If the variable has the "used" attribute, treat it as if 
it had a
ipa-reference.c- been touched by the devil.  */
ipa-reference.c:  if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
ipa-reference.c-return false;
ipa-reference.c-
ipa-reference.c-  /* Do not want to do anything with volatile except mark any
--
ipa-type-escape.c-  tree type = get_canon_type (TREE_TYPE (t), false, false);
ipa-type-escape.c-  if (!type) return;
ipa-type-escape.c-
ipa-type-escape.c:  if (lookup_attribute ("used", DECL_ATTRIBUTES (t)))
ipa-type-escape.c-{
ipa-type-escape.c-  mark_interesting_type (type, FULL_ESCAPE);
ipa-type-escape.c-  return;
--
varpool.c-  if (node->externally_visible || node->force_output)
varpool.c-return true;
varpool.c-  if (!flag_unit_at_a_time
varpool.c:  && lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
varpool.c-return true;
varpool.c-
varpool.c-  /* ??? If the assembler name is set by hand, it is possible to 
assemble

Given that the process