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]

Re: [PATCH] Fix -fcrossjumping at -O1 (PR rtl-optimization/48156)


I believe that this is not the right way to go.

if someone specifies -fcrossjumping, then the pass should turn on live for the duration of the pass just as ifcvt does. If they ask for crossjumping you should give them crossjumping and not some crippled version of it.

kenny



On 03/18/2011 12:13 PM, Jakub Jelinek wrote:
Hi!

The testcase below is miscompiled on x86_64-linux.
The problem is that try_head_merge_bb uses df_get_bb_dirty
to see if it can use df_get_live_out () info
(through simulate_backwards_to_point) reliably, but as at
-O1 the live problem isn't computed, only lr problem,
df_get_live_out () returns the lr out bitmap, but
df_get_bb_dirty which only looks at df_live problem always
returns false.  Thus, if the merge_bb's to compute live_union
from for can_move_insns_across has dirty lr solution caused by earlier
successful crossjumping in the same pass, we happily use its out of data
lr bitmap.

Fixed by returning if the bb has dirty lr problem if live problem
isn't computed.  df_get_bb_dirty is only used here in crossjumping and
in ifcvt, but in the latter we add the live problem at the start of
ifcvt and remove it at the end of ifcvt for -O1.

Bootstrapped/regtested on x86_64-linux, ok for trunk and 4.6.1?

While it is a wrong-code bug, I doubt many people are using
-O -fcrossjumping
options together, and -fcrossjumping is only the default for -O2+,
where live problem is added by default.

2011-03-18 Jakub Jelinek<jakub@redhat.com>

	PR rtl-optimization/48156
	* df-core.c (df_get_bb_dirty): Use df_lr if df_live is NULL.

* gcc.dg/pr48156.c: New test.

--- gcc/df-core.c.jj	2010-12-14 08:11:39.000000000 +0100
+++ gcc/df-core.c	2011-03-18 14:22:43.000000000 +0100
@@ -1400,10 +1400,16 @@ df_mark_solutions_dirty (void)
  bool
  df_get_bb_dirty (basic_block bb)
  {
-  if (df&&  df_live)
-    return bitmap_bit_p (df_live->out_of_date_transfer_functions, bb->index);
-  else
-    return false;
+  if (df)
+    {
+      if (df_live)
+	return bitmap_bit_p (df_live->out_of_date_transfer_functions,
+			     bb->index);
+      else if (df_lr)
+	return bitmap_bit_p (df_lr->out_of_date_transfer_functions,
+			     bb->index);
+    }
+  return false;
  }


--- gcc/testsuite/gcc.dg/pr48156.c.jj 2011-03-18 14:57:34.000000000 +0100 +++ gcc/testsuite/gcc.dg/pr48156.c 2011-03-18 14:57:14.000000000 +0100 @@ -0,0 +1,45 @@ +/* PR rtl-optimization/48156 */ +/* { dg-do run } */ +/* { dg-options "-O -fcrossjumping --param min-crossjump-insns=1" } */ + +extern void abort (void); + +static int __attribute__ ((noinline, noclone)) +equals (int s1, int s2) +{ + return s1 == s2; +} + +static int __attribute__ ((noinline, noclone)) +bar (void) +{ + return 1; +} + +static void __attribute__ ((noinline, noclone)) +baz (int f, int j) +{ + if (f != 4 || j != 2) + abort (); +} + +void +foo (int x) +{ + int i = 0, j = bar (); + + if (x == 1) + i = 2; + + if (j&& equals (i, j)) + baz (8, i); + else + baz (4, i); +} + +int +main () +{ + foo (1); + return 0; +}

Jakub


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