re PR middle-end/19874 (ICE in emit_move_insn with __attribute__((mode (QI))) enum)

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.

From-SVN: r95688
This commit is contained in:
Roger Sayle 2005-02-28 17:21:20 +00:00
parent dd1f53fbd7
commit 4f380bf815
4 changed files with 60 additions and 6 deletions

View File

@ -1,4 +1,10 @@
2005-02-28 <bosch@gnat.com>
2005-02-28 Roger Sayle <roger@eyesopen.com>
PR middle-end/19874
* tree-ssa.c (tree_ssa_useless_type_conversion_1): A conversion
between different machine modes is never a "useless" conversion.
2005-02-28 Geert Bosch <bosch@gnat.com>
PR ada/15977
* doc/contrib.texi: List contributors for Ada front end

View File

@ -1,3 +1,8 @@
2005-02-28 Jakub Jelinek <jakub@redhat.com>
PR middle-end/19874
* gcc.c-torture/execute/20050119-2.c: New test case.
2005-02-28 Ben Elliston <bje@au.ibm.com>
* README: Update the DejaGnu bug reporting address.

View File

@ -0,0 +1,40 @@
/* PR middle-end/19874 */
typedef enum { A, B, C, D } E;
struct S {
E __attribute__ ((mode (__byte__))) a;
E __attribute__ ((mode (__byte__))) b;
E __attribute__ ((mode (__byte__))) c;
E __attribute__ ((mode (__byte__))) d;
};
extern void abort (void);
extern void exit (int);
E
foo (struct S *s)
{
if (s->a != s->b)
abort ();
if (s->c != C)
abort ();
return s->d;
}
int
main (void)
{
struct S s[2];
s[0].a = B;
s[0].b = B;
s[0].c = C;
s[0].d = D;
s[1].a = D;
s[1].b = C;
s[1].c = B;
s[1].d = A;
if (foo (s) != D)
abort ();
exit (0);
}

View File

@ -778,11 +778,17 @@ delete_tree_ssa (void)
bool
tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
{
if (inner_type == outer_type)
return true;
/* Changes in machine mode are never useless conversions. */
if (TYPE_MODE (inner_type) != TYPE_MODE (outer_type))
return false;
/* If the inner and outer types are effectively the same, then
strip the type conversion and enter the equivalence into
the table. */
if (inner_type == outer_type
|| (lang_hooks.types_compatible_p (inner_type, outer_type)))
if (lang_hooks.types_compatible_p (inner_type, outer_type))
return true;
/* If both types are pointers and the outer type is a (void *), then
@ -793,7 +799,6 @@ tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
implement the ABI. */
else if (POINTER_TYPE_P (inner_type)
&& POINTER_TYPE_P (outer_type)
&& TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
&& TYPE_REF_CAN_ALIAS_ALL (inner_type)
== TYPE_REF_CAN_ALIAS_ALL (outer_type)
&& TREE_CODE (TREE_TYPE (outer_type)) == VOID_TYPE)
@ -803,7 +808,6 @@ tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
so strip conversions that just switch between them. */
else if (POINTER_TYPE_P (inner_type)
&& POINTER_TYPE_P (outer_type)
&& TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
&& TYPE_REF_CAN_ALIAS_ALL (inner_type)
== TYPE_REF_CAN_ALIAS_ALL (outer_type)
&& lang_hooks.types_compatible_p (TREE_TYPE (inner_type),
@ -819,7 +823,6 @@ tree_ssa_useless_type_conversion_1 (tree outer_type, tree inner_type)
mean that testing of precision is necessary. */
else if (INTEGRAL_TYPE_P (inner_type)
&& INTEGRAL_TYPE_P (outer_type)
&& TYPE_MODE (inner_type) == TYPE_MODE (outer_type)
&& TYPE_UNSIGNED (inner_type) == TYPE_UNSIGNED (outer_type)
&& TYPE_PRECISION (inner_type) == TYPE_PRECISION (outer_type))
{