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 regmove REG_EQUAL handling (PR rtl-optimization/46804)


Hi!

Bernd in 2001 fixed handling of REG_EQUIV and attempted to fix handling of
REG_EQUAL in optimize_reg_copy_3, unfortunately for the latter it wasn't
right - p at the end of the function is no longer the setter of src_reg,
but, as we walked again forwards, insn.  We don't want to drop REG_EQUAL
from insn, but from the setter.

This patch fixes it, and also, instead of dropping REG_EQUAL, tries to
replace it with sign or zero extension of it if the REG_EQUAL note was
the same as the original SET_SRC.

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

2010-12-08  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/46804
	* regmove.c (optimize_reg_copy_3): Look for REG_EQUAL note
	on the setter of src_reg rather than on insn.  If it is
	equal to the setter's original SET_SRC, replace it with its
	zero or sign extension instead of dropping it.

	* gfortran.dg/pr46804.f90: New test.

--- gcc/regmove.c.jj	2010-12-02 11:51:31.000000000 +0100
+++ gcc/regmove.c	2010-12-08 12:36:46.000000000 +0100
@@ -514,7 +514,7 @@ optimize_reg_copy_3 (rtx insn, rtx dest,
   rtx src_reg = XEXP (src, 0);
   int src_no = REGNO (src_reg);
   int dst_no = REGNO (dest);
-  rtx p, set;
+  rtx p, set, set_insn;
   enum machine_mode old_mode;
   basic_block bb = BLOCK_FOR_INSN (insn);
 
@@ -552,6 +552,7 @@ optimize_reg_copy_3 (rtx insn, rtx dest,
 				 GET_MODE_BITSIZE (GET_MODE (src_reg))))
     return;
 
+  set_insn = p;
   old_mode = GET_MODE (src_reg);
   PUT_MODE (src_reg, GET_MODE (src));
   XEXP (src, 0) = SET_SRC (set);
@@ -584,9 +585,19 @@ optimize_reg_copy_3 (rtx insn, rtx dest,
     }
   else
     {
-      rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX);
+      rtx note = find_reg_note (set_insn, REG_EQUAL, NULL_RTX);
       if (note)
-	remove_note (p, note);
+	{
+	  if (rtx_equal_p (XEXP (note, 0), XEXP (src, 0)))
+	    {
+	      XEXP (note, 0)
+		= gen_rtx_fmt_e (GET_CODE (src), GET_MODE (src),
+				 XEXP (note, 0));
+	      df_notes_rescan (set_insn);
+	    }
+	  else
+	    remove_note (set_insn, note);
+	}
     }
 }
 
--- gcc/testsuite/gfortran.dg/pr46804.f90.jj	2010-12-08 12:41:21.000000000 +0100
+++ gcc/testsuite/gfortran.dg/pr46804.f90	2010-12-08 12:41:02.000000000 +0100
@@ -0,0 +1,36 @@
+! PR rtl-optimization/46804
+! { dg-do run }
+! { dg-options "-O -fPIC -fexpensive-optimizations -fgcse -foptimize-register-move -fpeel-loops -fno-tree-loop-optimize" }
+
+program main
+  integer, parameter :: n1 = 2, n2 = 3, n3 = 4, slen = 3
+  character (len = slen), dimension (n1, n2, n3) :: a
+  integer (kind = 1), dimension (2, 4) :: shift1
+  integer (kind = 2), dimension (2, 4) :: shift2
+  integer (kind = 4), dimension (2, 4) :: shift3
+  do i3 = 1, n3
+    do i2 = 1, n2
+      do i1 = 1, n1
+        a (i1, i2, i3) = 'ab'(i1:i1) // 'cde'(i2:i2) // 'fghi'(i3:i3)
+      end do
+    end do
+  end do
+  shift1 (1, :) = (/ 4, 11, 19, 20 /)
+  shift1 (2, :) = (/ 55, 5, 1, 2 /)
+  shift2 = shift1
+  shift3 = shift1
+  call test (cshift (a, shift2, 2))
+  call test (cshift (a, shift3, 2))
+contains
+  subroutine test (b)
+    character (len = slen), dimension (n1, n2, n3) :: b
+    do i3 = 1, n3
+      do i2 = 1, n2
+        do i1 = 1, n1
+          i2p = mod (shift1 (i1, i3) + i2 - 1, n2) + 1
+          if (b (i1, i2, i3) .ne. a (i1, i2p, i3)) call abort
+        end do
+      end do
+    end do
+  end subroutine test
+end program main

	Jakub


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