New: Member record alignment triggering an ICE
13 answers - 2552 bytes -

This problem happens for platforms that set STRICT_ALIGNMENT. For them it is
possible for a given record type to be expressed using an integer mode if used
as a member record, and the BLK mode if used standalone. As a result an
assignment where lhs is BLKmode and rhs is *Imode may be generated and this
triggers an ICE.
I've been able to trigger it for 4.0.0 using alpha-linux-gnu,
mipsel-linux-gnu and mips64el-linux cross-compilers run on i386-linux-gnu
as well as a native mipsel-linux-gnu one. The compiler was configured as
follows:
$ CC=i386-linux-gcc \
CXX=i386-linux-g++ \
F77=i386-linux-gfortran \
CFLAGS='-pipe -fomit-frame-pointer -mtune=i486' \
CXXFLAGS='-pipe -fomit-frame-pointer -mtune=i486' \
FCFLAGS='-pipe -fomit-frame-pointer -mtune=i486' \
CC_FR_BUILD=i386-linux-gcc \
CFLAGS_FR_BUILD='-pipe -fomit-frame-pointer -mtune=i486' \
CFLAGS_FR_TARGET='-mcpu=ev4 -pipe -fomit-frame-pointer' \
CXXFLAGS_FR_TARGET='-mcpu=ev4 -pipe -fomit-frame-pointer' \
FCFLAGS_FR_TARGET='-mcpu=ev4 -pipe -fomit-frame-pointer' \
INSTALL_PRGRAM='${INSTALL} -s' \
/configure /usr '${datadir}/man' \
'${prefix}/alpha-linux/local' \
\
\
\
\
\
\
then built as follows:
$ make 'BT_CFLAGS=-pipe -fomit-frame-pointer -mtune=i486' \
'GCJFLAGS=-mcpu=ev4 -pipe -fomit-frame-pointer' \
CXX_FR_BUILD=i386-linux-g++ \
'CXXFLAGS_FR_BUILD=-pipe -fomit-frame-pointer -mtune=i486' all
(this is for alpha-linux-gnu -- the others were built similarly; I can supply
details if needed).
I'm sending a set of sources that trigger the problem for me. They are
actually a part of the Ada binding of ncurses 5.4. To reproduce, build as
follows:
$ alpha-linux-gcc -c -gnatpn -pipe -fomit-frame-pointer \
terminal_interface-curses.adb
I've been able to track the problem down to the alignment of member records
being increased implicitly in an attempt to fit them into an integer mode.
I believe it is incorrect as it changes the alignment of the containing
record as well and therefore it changes the ABI. That would be true e.g. for
the MIPS ABI as far as C is concerned, but I don't know if Ada follows the
same rules, so my opinion is not definite. Anyway I've prepared a patch
proposal that fixes the problem for me.
Please consider.
No.1 | | 146 bytes |
| 
Additional Comments From macro at linux-mips dot org 2005-06-06 20:43
Created an attachment (id=9041)
()
This is the set of the sources
No.2 | | 112 bytes |
| 
Additional Comments From macro at linux-mips dot org 2005-06-06 20:45
Created an attachment (id=9042)
()
No.3 | | 81 bytes |
| 
--
What |Removed |Added
CC| |pluto at agmk dot net
No.4 | | 83 bytes |
| 
--
What |Removed |Added
Keywords| |ice-on-valid-code
No.5 | | 827 bytes |
| 
Additional Comments From macro at linux-mips dot org 2005-06-07 10:28
Here are details missing from the original report (sorry about that).
This is output from the compiler when the ICE happens:
4.0.0 (alpha-unknown-linux-gnu) GCC error:
in simplify_subreg, at simplify-rtx.c:3726
Error detected at
[]
raised TYPES.UNRECVERABLE_ERRR : comperr.adb:387
This is a ChangeLog entry for the patch:
2005-06-07 Maciej W. Rozycki <macro (AT) linux-mips (DOT) org>
* ada/decl.c (make_packable_type): Use the same alignment for the new
type.
Finally, as I have a native compiler for an affected platform, specifically
mipsel-linux-gnu, I have run the Ada testsuite both without and with the
patch applied and the change hasn't introduced any regressions.
No.6 | | 1189 bytes |
| 
Additional Comments From ebotcazou at gcc dot gnu dot org 2005-06-07 11:30
This problem happens for platforms that set STRICT_ALIGNMENT. For them it is
possible for a given record type to be expressed using an integer mode if used
as a member record, and the BLK mode if used standalone. As a result an
assignment where lhs is BLKmode and rhs is *Imode may be generated and this
triggers an ICE.
That's not quite true, the type is not the same.
I've been able to track the problem down to the alignment of member records
being increased implicitly in an attempt to fit them into an integer mode.
I believe it is incorrect as it changes the alignment of the containing
record as well and therefore it changes the ABI.
How does that change the ABI for the containing record type? The type is laid
out only once. As for members, this is only done for non-aliased members so ABI
considerations are irrelevant.
2005-06-07 Maciej W. Rozycki <macro (AT) linux-mips (DOT) org>
* ada/decl.c (make_packable_type): Use the same alignment for the new
type.
That would defeat the purpose of make_packable_type.
No.7 | | 93 bytes |
| 
Additional Comments From ebotcazou at gcc dot gnu dot org 2005-06-07 11:31
Investigating.
No.8 | | 1539 bytes |
| 
Additional Comments From macro at linux-mips dot org 2005-06-07 12:14
That's not quite true, the type is not the same.
It's hard to argue for me as Ada is not a language I'm familiar with, but
the problematic assignment is:
return Ch.Attr;
in Get_Character_Attribute() and both Ch.Attr and the return value of the
function are declared as Character_Attribute_Set, so I guess they are both
of the same type, aren't they.
How does that change the ABI for the containing record type? The type is laid
out only once. As for members, this is only done for non-aliased members so ABI
considerations are irrelevant.
course it changes the ABI -- if any member of a record (which is an
equivalent to a C structure) gets its alignment increased, then the alignment
of the containing record (structure) gets adjusted appropriately.
the member's record alignment requirement couldn't possibly be satisfied at
the link time. And of course the alignment does matter for platforms that
care about alignment as different machine code may be needed to access data.
2005-06-07 Maciej W. Rozycki <macro (AT) linux-mips (DOT) org>
* ada/decl.c (make_packable_type): Use the same alignment for the new
type.
That would defeat the purpose of make_packable_type.
If I understand code correctly compute_record_mode() should still be able to
use one of the integer modes for platforms that don't care about alignment.
No.9 | | 682 bytes |
| 
Additional Comments From ebotcazou at gcc dot gnu dot org 2005-06-07 12:16
This worked in 3.4.x because we added a conversion operator:
tree_transform <N_Return_Statement>:
expand_return (build_binary_op (MDIFY_EXPR, NULL_TREE,
DECL_RESULT (current_function_decl),
gnu_ret_val));
In 4.x we directly build a MDIFY_EXPR:
gnat_to_gnu <N_Return_Statement>:
if (gnu_ret_val)
gnu_result = build2 (MDIFY_EXPR, TREE_TYPE (gnu_ret_val),
gnu_lhs, gnu_ret_val);
Reinstating build_binary_op yields an ICE in the gimplifier instead, so either
build_binary_op or the gimplifier would probably need to be tweaked a bit.
No.10 | | 1217 bytes |
| 
Additional Comments From ebotcazou at gcc dot gnu dot org 2005-06-07 12:26
It's hard to argue for me as Ada is not a language I'm familiar with, but
the problematic assignment is:
return Ch.Attr;
in Get_Character_Attribute() and both Ch.Attr and the return value of the
function are declared as Character_Attribute_Set, so I guess they are both
of the same type, aren't they.
No, the types are not the same in the IL, that's why they can get different
machine modes.
course it changes the ABI -- if any member of a record (which is an
equivalent to a C structure) gets its alignment increased, then the alignment
of the containing record (structure) gets adjusted appropriately.
Sure, but since all records of this type will be laid out the same way, where is
the problem? This only happens for packed records or records with
representation clauses, both not bound to any ABI rules as far as Ada is concerned.
If I understand code correctly compute_record_mode() should still be able to
use one of the integer modes for platforms that don't care about alignment.
x86 is not (yet) the only platform out there. :-)
No.11 | | 1377 bytes |
| 
Additional Comments From macro at linux-mips dot org 2005-06-07 18:16
course it changes the ABI -- if any member of a record (which is an
equivalent to a C structure) gets its alignment increased, then the alignment
of the containing record (structure) gets adjusted appropriately.
Sure, but since all records of this type will be laid out the same way, where is
the problem? This only happens for packed records or records with
After a short consideration I agree -- it would only be a problem if the case
was reversed, i.e. standalone records got their alignment bumped while member
oned did not.
representation clauses, both not bound to any ABI rules as far as Ada is
concerned.
Well, there may be no written standard for this case, but there is always an
ABI, even if limited to GCC.
If I understand code correctly compute_record_mode() should still be able to
use one of the integer modes for platforms that don't care about alignment.
x86 is not (yet) the only platform out there. :-)
Well, you may have noticed I'm already aware of this -- otherwise I wouldn't
have filed the report in the first place. But the problem is the i386 is
probably the architecture most code is primarily tested with and unfortunately
it has quite forgiving restrictions about alignment.
No.12 | | 703 bytes |
| 
Additional Comments From ebotcazou at gcc dot gnu dot org 2005-06-07 18:56
Well, you may have noticed I'm already aware of this -- otherwise I wouldn't
have filed the report in the first place. But the problem is the i386 is
probably the architecture most code is primarily tested with and unfortunately
it has quite forgiving restrictions about alignment.
The 4.0.x Ada compiler has been regularly tested on PowerPC and SPARC too (apart
from being interested in Ada, I'm also a SPARC maintainer) so it shouldn't be
that broken on non-x86 platforms. However it is true that RISC platforms are
more demanding than x86, at least as far as Ada is concerned.
No.13 | | 104 bytes |
| 
Additional Comments From ebotcazou at gcc dot gnu dot org 2005-09-06 08:26
Same problem on mainline.