This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[committed] Avoid tail call opt if bit field reduction is needed (PR tree-optimization/60971)


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]