From 15a7b0e3d162ad95f6b6218465cb1552ce3d2914 Mon Sep 17 00:00:00 2001 From: jakub Date: Fri, 10 Dec 2010 16:40:51 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167695 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 8 ++++++++ gcc/regmove.c | 17 ++++++++++++++--- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gfortran.dg/pr46804.f90 | 36 +++++++++++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/pr46804.f90 diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 664bef963e2..9b4be737ab4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2010-12-10 Jakub Jelinek + + 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 PR lto/46808 diff --git a/gcc/regmove.c b/gcc/regmove.c index d3c733e38bb..48a583fa215 100644 --- a/gcc/regmove.c +++ b/gcc/regmove.c @@ -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); + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9705844d5ef..47022afe9c9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-12-10 Jakub Jelinek + + PR rtl-optimization/46804 + * gfortran.dg/pr46804.f90: New test. + 2010-12-10 Dave Korn PR middle-end/46674 diff --git a/gcc/testsuite/gfortran.dg/pr46804.f90 b/gcc/testsuite/gfortran.dg/pr46804.f90 new file mode 100644 index 00000000000..ee44a56c897 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/pr46804.f90 @@ -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 -- 2.11.0