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]

[PATCH] Fix RTL sharing bug in loop-doloop.c (PR target/79080)


Hi!

The force_operand on complex count expression in doloop_modify can invoke
various expander routines that are assuming there is rtl unsharing after
them (which is the case for expansion).  When later optimizations invoke
the expander (e.g. expand_mult in this case), they use
unshare_all_rtl_in_chain on the sequence.  The following patch does that for
doloop.  The count expression is already known not to be shared with
anything else (we do copy_rtx on it first and then create new rtls around it
if needed), so for that if it occurs just once in the sequence, we don't
need to unshare it.  For subexpression of condition I'm not sure, which is
why I've forced unsharing even if it occurs just once and is not shareable
part of the condition like REG.

Bootstrapped/regtested on powerpc64-linux, ok for trunk?

2017-01-14  Jakub Jelinek  <jakub@redhat.com>

	PR target/79080
	* loop-doloop.c (doloop_modify): Call unshare_all_rtl_in_chain on
	sequence.  Formatting fixes.
	(doloop_optimize): Formatting fixes.

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

--- gcc/loop-doloop.c.jj	2017-01-01 12:45:37.000000000 +0100
+++ gcc/loop-doloop.c	2017-01-13 09:55:36.918702356 +0100
@@ -479,9 +479,13 @@ doloop_modify (struct loop *loop, struct
 
   /* Insert initialization of the count register into the loop header.  */
   start_sequence ();
+  /* count has been already copied through copy_rtx.  */
+  reset_used_flags (count);
+  set_used_flags (condition);
   tmp = force_operand (count, counter_reg);
   convert_move (counter_reg, tmp, 1);
   sequence = get_insns ();
+  unshare_all_rtl_in_chain (sequence);
   end_sequence ();
   emit_insn_after (sequence, BB_END (loop_preheader_edge (loop)->src));
 
@@ -489,10 +493,8 @@ doloop_modify (struct loop *loop, struct
     {
       rtx ass = copy_rtx (desc->noloop_assumptions);
       basic_block preheader = loop_preheader_edge (loop)->src;
-      basic_block set_zero
-	      = split_edge (loop_preheader_edge (loop));
-      basic_block new_preheader
-	      = split_edge (loop_preheader_edge (loop));
+      basic_block set_zero = split_edge (loop_preheader_edge (loop));
+      basic_block new_preheader = split_edge (loop_preheader_edge (loop));
       edge te;
 
       /* Expand the condition testing the assumptions and if it does not pass,
@@ -688,8 +690,7 @@ doloop_optimize (struct loop *loop)
   rtx_insn *doloop_seq = targetm.gen_doloop_end (doloop_reg, start_label);
 
   word_mode_size = GET_MODE_PRECISION (word_mode);
-  word_mode_max
-	  = (HOST_WIDE_INT_1U << (word_mode_size - 1) << 1) - 1;
+  word_mode_max = (HOST_WIDE_INT_1U << (word_mode_size - 1) << 1) - 1;
   if (! doloop_seq
       && mode != word_mode
       /* Before trying mode different from the one in that # of iterations is
--- gcc/testsuite/gcc.dg/pr79080.c.jj	2017-01-13 10:03:54.518423577 +0100
+++ gcc/testsuite/gcc.dg/pr79080.c	2017-01-13 10:07:37.610608570 +0100
@@ -0,0 +1,19 @@
+/* PR target/79080 */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+/* { dg-additional-options "-mcpu=8548" { target { powerpc*-*-* && ilp32 } } } */
+
+int
+foo (char x)
+{
+  int a;
+
+  for (;;)
+    {
+      x += 59;
+      if (x != 0)
+        a = 0;
+      else
+        return 0;
+    }
+}

	Jakub


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