aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2014-04-29 16:44:07 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2014-04-29 16:44:07 +0200
commit62fb101e69b1b1c99e3bf4951616eb3ce3015006 (patch)
tree09f0906e732040a14e4c16680206a15c68ca8130
parentd77f7b19b7f15ac0fec0823e7cc507f39ab36c30 (diff)
downloadgcc-62fb101e69b1b1c99e3bf4951616eb3ce3015006.zip
gcc-62fb101e69b1b1c99e3bf4951616eb3ce3015006.tar.gz
gcc-62fb101e69b1b1c99e3bf4951616eb3ce3015006.tar.bz2
re PR tree-optimization/60971 (Wrong code when coercing unsigned char to bool)
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
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/c-c++-common/torture/pr60971.c34
-rw-r--r--gcc/tree-tailcall.c16
4 files changed, 58 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 42e0182..f22fe1d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ef61cfe..689f4e8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..b7a967d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/torture/pr60971.c
@@ -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;
+}
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index 11a2965..9ad25d8 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -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;