Patchwork Fix regmove REG_EQUAL handling (PR rtl-optimization/46804)

login
register
mail settings
Submitter Jakub Jelinek
Date Dec. 8, 2010, 4:42 p.m.
Message ID <20101208164217.GF29412@tyan-ft48-01.lab.bos.redhat.com>
Download mbox | patch
Permalink /patch/74745/
State New
Headers show

Comments

Jakub Jelinek - Dec. 8, 2010, 4:42 p.m.
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.


	Jakub
Jeff Law - Dec. 10, 2010, 4:33 p.m.
On 12/08/10 09:42, Jakub Jelinek wrote:
> 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.
OK.  Thanks.

jeff

Patch

--- 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