Hello, I've been investigating the failure of namelist_14.f90 -O0, the last s390x-ibm-linux Fortran regression.
A much reduced test case is: program test 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): bool use_register_for_decl (tree decl) { /* Honor volatile. */ if (TREE_SIDE_EFFECTS (decl)) return false; /* Honor addressability. */ if (TREE_ADDRESSABLE (decl)) return false; /* Only register-like things go in registers. */ if (DECL_MODE (decl) == BLKmode) return false; /* 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))) return false; /* 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 true; 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? Thanks, Ulrich -- Dr. Ulrich Weigand Linux on zSeries Development [EMAIL PROTECTED]