re PR tree-optimization/60971 (Wrong code when coercing unsigned char to bool)
authorJakub Jelinek <jakub@redhat.com>
Tue, 29 Apr 2014 14:44:07 +0000 (16:44 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Tue, 29 Apr 2014 14:44:07 +0000 (16:44 +0200)
PR tree-optimization/60971
* tree-tailcall.c (process_assignment): Reject conversions which
reduce precision.

* c-c++-common/turtore/pr60971.c: New test.

From-SVN: r209900

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/c-c++-common/torture/pr60971.c [new file with mode: 0644]
gcc/tree-tailcall.c

index 42e0182a9484d38fb8704d7ac2b70acb0ac31329..f22fe1d136a22c110c7abd1c7cfcc761932c6e5e 100644 (file)
@@ -1,3 +1,9 @@
+2014-04-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/60971
+       * tree-tailcall.c (process_assignment): Reject conversions which
+       reduce precision.
+
 2014-04-29  James Greenhalgh  <james.greenhalgh@arm.com>
 
        * calls.c (initialize_argument_information): Always treat
index ef61cfefd6676d8e8cd34b39b2bad7bc36c73efb..689f4e847fbf969b387d3106470256a3895de857 100644 (file)
@@ -1,3 +1,8 @@
+2014-04-29  Jakub Jelinek  <jakub@redhat.com>
+
+       PR tree-optimization/60971
+       * c-c++-common/turtore/pr60971.c: New test.
+
 2014-04-29  Alan Lawrence  <alan.lawrence@arm.com>
 
        * gcc.target/aarch64/simd/simd.exp: New file.
diff --git a/gcc/testsuite/c-c++-common/torture/pr60971.c b/gcc/testsuite/c-c++-common/torture/pr60971.c
new file mode 100644 (file)
index 0000000..b7a967d
--- /dev/null
@@ -0,0 +1,34 @@
+/* PR tree-optimization/60971 */
+/* { dg-do run } */
+
+#ifndef __cplusplus
+#define bool _Bool
+#endif
+
+volatile unsigned char c;
+
+__attribute__((noinline)) unsigned char
+foo (void)
+{
+  return c;
+}
+
+__attribute__((noinline)) bool
+bar (void)
+{
+  return foo () & 1;
+}
+
+int
+main ()
+{
+  c = 0x41;
+  c = bar ();
+  if (c != 1)
+    __builtin_abort ();
+  c = 0x20;
+  c = bar ();
+  if (c != 0)
+    __builtin_abort ();
+  return 0;
+}
index 11a29659bc5bc938190f3af28b9c732a855356a1..9ad25d81c6d49b77f161879e95d55284e93fa89d 100644 (file)
@@ -285,9 +285,19 @@ process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m,
     {
       /* Reject a tailcall if the type conversion might need
         additional code.  */
-      if (gimple_assign_cast_p (stmt)
-         && TYPE_MODE (TREE_TYPE (dest)) != TYPE_MODE (TREE_TYPE (src_var)))
-       return false;
+      if (gimple_assign_cast_p (stmt))
+       {
+         if (TYPE_MODE (TREE_TYPE (dest)) != TYPE_MODE (TREE_TYPE (src_var)))
+           return false;
+
+         /* Even if the type modes are the same, if the precision of the
+            type is smaller than mode's precision,
+            reduce_to_bit_field_precision would generate additional code.  */
+         if (INTEGRAL_TYPE_P (TREE_TYPE (dest))
+             && (GET_MODE_PRECISION (TYPE_MODE (TREE_TYPE (dest)))
+                 > TYPE_PRECISION (TREE_TYPE (dest))))
+           return false;
+       }
 
       if (src_var != *ass_var)
        return false;