OSDN Git Service

PR rtl-optimization/46804
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Dec 2010 16:40:51 +0000 (16:40 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 10 Dec 2010 16:40:51 +0000 (16:40 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167695 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/regmove.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/pr46804.f90 [new file with mode: 0644]

index 664bef9..9b4be73 100644 (file)
@@ -1,3 +1,11 @@
+2010-12-10  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.
+
 2010-12-10  Richard Guenther  <rguenther@suse.de>
 
        PR lto/46808
index d3c733e..48a583f 100644 (file)
@@ -514,7 +514,7 @@ optimize_reg_copy_3 (rtx insn, rtx dest, rtx src)
   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, rtx src)
                                 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, rtx src)
     }
   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);
+       }
     }
 }
 
index 9705844..47022af 100644 (file)
@@ -1,3 +1,8 @@
+2010-12-10  Jakub Jelinek  <jakub@redhat.com>
+
+       PR rtl-optimization/46804
+       * gfortran.dg/pr46804.f90: New test.
+
 2010-12-10  Dave Korn  <dave.korn.cygwin@gmail.com>
 
        PR middle-end/46674
diff --git a/gcc/testsuite/gfortran.dg/pr46804.f90 b/gcc/testsuite/gfortran.dg/pr46804.f90
new file mode 100644 (file)
index 0000000..ee44a56
--- /dev/null
@@ -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