re PR middle-end/19874 (ICE in emit_move_insn with __attribute__((mode (QI))) enum)
authorRoger Sayle <sayle@gcc.gnu.org>
Mon, 28 Feb 2005 17:21:20 +0000 (17:21 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Mon, 28 Feb 2005 17:21:20 +0000 (17:21 +0000)
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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.c-torture/execute/20050119-2.c [new file with mode: 0644]
gcc/tree-ssa.c

index b813efe62a5334a5faa58d7684c69050f84ddd5b..a0b92190d2b55f09f1c6c773128028a6c7cf809b 100644 (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
index fdac060d4edf58a4cdcf155e063fedb803728907..9ed60b0cad467734469c455e0633809c2d530dd6 100644 (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.
diff --git a/gcc/testsuite/gcc.c-torture/execute/20050119-2.c b/gcc/testsuite/gcc.c-torture/execute/20050119-2.c
new file mode 100644 (file)
index 0000000..568109c
--- /dev/null
@@ -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);
+}
+
index b39c260c273a5e3374007af3f633e1b91c8b5733..9346d6cf7065425debbaf304d132a92db5073dff 100644 (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))
     {