This is the mail archive of the
mailing list for the GCC project.
[RFC] Fortran ICE caused by array addressability issue
- From: Ulrich Weigand <uweigand at de dot ibm dot com>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 13 Oct 2005 19:35:27 +0200 (CEST)
- Subject: [RFC] Fortran ICE caused by array addressability issue
I've been investigating the failure of namelist_14.f90 -O0,
the last s390x-ibm-linux Fortran regression.
A much reduced test case is:
type :: mt
integer :: ii(4)
end type mt
type(mt) :: t
t = mt ((/1,1,1,1/))
end program test
Compiling this program without optimization fails with
test.f90:9: internal compiler error: in expand_assignment, at expr.c:3929
(Note that *with* optimization everything is fine.)
The ICE in expand_assignment results from expanding the
following line of code (from test.f90.t24.fixupcfg):
mt.0.ii[S.6] = D.557;
"mt.0" is a temporary of type "mt" generated by the gimplifier. As the
size of mt is 16, the expander uses TImode to hold the variable.
The ICE occurs because the expander tries to use a *register* to hold
that variable, and indexing a *variable* slot inside an array held in
a register is not supported by expand_assignment.
The decision whether to use a register or a stack slot is made in the
function use_register_for_decl (function.c):
use_register_for_decl (tree decl)
/* Honor volatile. */
if (TREE_SIDE_EFFECTS (decl))
/* Honor addressability. */
if (TREE_ADDRESSABLE (decl))
/* Only register-like things go in registers. */
if (DECL_MODE (decl) == BLKmode)
/* If -ffloat-store specified, don't put explicit float variables
into registers. */
/* ??? This should be checked after DECL_ARTIFICIAL, but tree-ssa
propagates values across these stores, and it probably shouldn't. */
if (flag_float_store && FLOAT_TYPE_P (TREE_TYPE (decl)))
/* If we're not interested in tracking debugging information for
this decl, then we can certainly put it in a register. */
if (DECL_IGNORED_P (decl))
return (optimize || DECL_REGISTER (decl));
As the variable is a temporary generated by the gimplifier, it has
its DECL_IGNORED_P flag set, which is why use_register_for_decl
decides to put it into a register, causing the ICE. I was unable
to reproduce this in C, because I don't get such temporaries there.
Now, the interesting point is that when opimization is on, this
routine would return true anyway, so why does it work then? This
is because then the TREE_ADDRESSABLE flag is set, so it will always
be placed onto the stack.
However, the routine mark_array_ref_addressable (tree-cfg.c) which
sets the TREE_ADDRESSABLE flag is only ever called from the routine
execute_cleanup_cfg_post_optimizing (tree-optimize.c), which is never
called when not optimizing ...
Now, I'm not sure how to fix this. One fix would be to always make
sure mark_array_ref_addressable is called, even when not optimizing.
I don't know what the right call point would be.
The other fix would be to remove the special treatment of
DECL_IGNORED_P from use_register_for_decl. This may cause somewhat
worse code generation, but only in the -O0 case, which I'm not
particularly concerned about ...
Any suggestions what the proper fix should be?
Dr. Ulrich Weigand
Linux on zSeries Development