From 62fb101e69b1b1c99e3bf4951616eb3ce3015006 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 29 Apr 2014 16:44:07 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++++ gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/c-c++-common/torture/pr60971.c | 34 ++++++++++++++++++++ gcc/tree-tailcall.c | 16 +++++++-- 4 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/torture/pr60971.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 42e0182a948..f22fe1d136a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2014-04-29 Jakub Jelinek + + PR tree-optimization/60971 + * tree-tailcall.c (process_assignment): Reject conversions which + reduce precision. + 2014-04-29 James Greenhalgh * calls.c (initialize_argument_information): Always treat diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ef61cfefd66..689f4e847fb 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2014-04-29 Jakub Jelinek + + PR tree-optimization/60971 + * c-c++-common/turtore/pr60971.c: New test. + 2014-04-29 Alan Lawrence * 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 00000000000..b7a967dabb4 --- /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 11a29659bc5..9ad25d81c6d 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; -- 2.30.2