Enhanced testcase for PR c/19342 still ICEs e.g. on x86_64 at -O2, particularly in emit_move_insn. expand_value_return is called with val = (reg:QI 64), but return_reg has different mode, (reg:SI 58 [ <result> ]).
Created attachment 8161 [details] pr19874-test.patch
This is a regression from GCC 3.4.x and earlier btw. The problem seems to be that STRIP_USELESS_TYPE_CONVERSION strips E to E __attribute__ ((mode (__byte__))) conversion as useless, although it has different TYPE_MODE and TYPE_PRECISION. This is because both have the same TYPE_MAIN_VARIANT. I tried following patch which cures this for C, but unfortunately breaks C++ at the same time (C++ needs both enums to have the same main variant): --- gcc/c-common.c.jj 2005-02-14 09:25:46.000000000 +0100 +++ gcc/c-common.c 2005-02-21 14:43:53.000000000 +0100 @@ -4364,7 +4364,7 @@ handle_mode_attribute (tree *node, tree } if (!(flags & (int) ATTR_FLAG_TYPE_IN_PLACE)) - type = build_variant_type_copy (type); + type = build_distinct_type_copy (type); /* We cannot use layout_type here, because that will attempt to re-layout all variants, corrupting our original. */ --- gcc/c-typeck.c.jj 2005-02-19 00:31:52.000000000 +0100 +++ gcc/c-typeck.c 2005-02-21 15:07:51.249019189 +0100 @@ -755,12 +755,19 @@ comptypes (tree type1, tree type2) if (c_dialect_objc () && objc_comptypes (t1, t2, 0) == 1) val = 1; - case ENUMERAL_TYPE: case UNION_TYPE: if (val != 1 && !same_translation_unit_p (t1, t2)) val = tagged_types_tu_compatible_p (t1, t2); break; + /* Don't consider enum E { A, B } and enum E __attribute__((mode (byte))) + to be compatible. */ + case ENUMERAL_TYPE: + if (val != 1 && TYPE_MODE (t1) == TYPE_MODE (t2) + && !same_translation_unit_p (t1, t2)) + val = tagged_types_tu_compatible_p (t1, t2); + break; + case VECTOR_TYPE: val = TYPE_VECTOR_SUBPARTS (t1) == TYPE_VECTOR_SUBPARTS (t2) && comptypes (TREE_TYPE (t1), TREE_TYPE (t2)); Alternative would be e.g. to change c_types_compatible_p to special case ENUMERAL_TYPEs and requiring there TYPE_MODE () to be compatible.
Subject: Bug 19874 CVSROOT: /cvs/gcc Module name: gcc Changes by: sayle@gcc.gnu.org 2005-02-28 17:21:24 Modified files: gcc : ChangeLog tree-ssa.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.c-torture/execute: 20050119-2.c Log message: PR middle-end/19874 * tree-ssa.c (tree_ssa_useless_type_conversion_1): A conversion between different machine modes is never a "useless" conversion. * gcc.c-torture/execute/20050119-2.c: New test case. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&r1=2.7612&r2=2.7613 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-ssa.c.diff?cvsroot=gcc&r1=2.78&r2=2.79 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&r1=1.5096&r2=1.5097 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/20050119-2.c.diff?cvsroot=gcc&r1=NONE&r2=1.1
Fixed on the mainline waiting for the commit for the 4.0 branch.
Subject: Bug 19874 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-4_0-branch Changes by: sayle@gcc.gnu.org 2005-02-28 22:22:19 Modified files: gcc : ChangeLog tree-ssa.c gcc/testsuite : ChangeLog Added files: gcc/testsuite/gcc.c-torture/execute: 20050119-2.c Log message: PR middle-end/19874 * tree-ssa.c (tree_ssa_useless_type_conversion_1): A conversion between different machine modes is never a "useless" conversion. * gcc.c-torture/execute/20050119-2.c: New test case. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=2.7592.2.10&r2=2.7592.2.11 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/tree-ssa.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=2.78&r2=2.78.2.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.5084.2.9&r2=1.5084.2.10 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/testsuite/gcc.c-torture/execute/20050119-2.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.2.1
Fixed.