This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[committed] Avoid tail call opt if bit field reduction is needed (PR tree-optimization/60971)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 29 Apr 2014 16:48:45 +0200
- Subject: [committed] Avoid tail call opt if bit field reduction is needed (PR tree-optimization/60971)
- Authentication-results: sourceware.org; auth=none
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
I've committed following fix, approved by Richard on IRC and Jeff in the PR.
process_assignment was assuming that no code needs to be emitted
for gimple_assign_cast_p if the mode is the same, which is usually true,
except for the case when REDUCE_BIT_FIELD in expand_expr_real_2 needs to
mask or shift up/down to adjust for reduced precision.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed to trunk
and 4.9.
2014-04-29 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/60971
* tree-tailcall.c (process_assignment): Reject conversions which
reduce precision.
* c-c++-common/turtore/pr60971.c: New test.
--- gcc/tree-tailcall.c.jj 2014-04-17 14:48:59.000000000 +0200
+++ gcc/tree-tailcall.c 2014-04-29 12:13:12.649414120 +0200
@@ -285,9 +285,19 @@ process_assignment (gimple stmt, gimple_
{
/* 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;
--- gcc/testsuite/c-c++-common/torture/pr60971.c.jj 2014-04-29 11:15:06.448764325 +0200
+++ gcc/testsuite/c-c++-common/torture/pr60971.c 2014-04-29 11:14:49.000000000 +0200
@@ -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;
+}
Jakub