From patchwork Sun Sep 5 15:12:44 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: Fix 45545 (was [PATCH] Fix PR45266) Date: Sun, 05 Sep 2010 05:12:44 -0000 From: Hans-Peter Nilsson X-Patchwork-Id: 63837 Message-Id: <201009051512.o85FCifx019492@ignucius.se.axis.com> To: rguenther@suse.de Cc: gcc-patches@gcc.gnu.org > Date: Tue, 17 Aug 2010 11:46:09 +0200 (CEST) > From: Richard Guenther > This fixes the pattern in gfortran.dg/array_memcpy_3.f90 - thanks > Steve for figuring out a working one. Nah... Well, it works for targets matching the memcpy part. For ref-all targets, you get *one* long match, not two: the "*" is "greedy" and . matches newline. DO NOT USE ".*" IN SCAN-PATTERNS! Use "\[^\\n\]*" to avoid matching newline. For the wrong reasons it worked for ref-all targets *with* the parentheses, as the parentheses and (IIUC) "regexp -inline" behavior conspired to make the match inside the parentheses to be emitted into the result in addition to the whole of the match. So in the result, there were one match and a copy, instead of two matches. I can't claim to fully understand why it does so also for memcpy, as the matching regexp-alternative then does not contain parentheses. See the session below. Regarding the ref-all vs. memcpy, I (also) don't understand, even after a brief look into the MOVE_MAX and MOVE_RATIO pchp2:hp:/tmp: rpm -qf `which tclsh` tcl-8.5.7-5.fc12.x86_64 tcl-8.5.7-5.fc12.i686 pchp2:hp:/tmp: tclsh % set a {foo (integer(kind=4)[4] * restrict x) { { static integer(kind=4) A.0[4] = {3, 1, 4, 1}; MEM[(c_char * {ref-all})x] = MEM[(c_char * {ref-all})&A.0]; } } bar (integer(kind=4)[4] * restrict x) { { static integer(kind=4) A.1[4] = {3, 1, 4, 1}; MEM[(c_char * {ref-all})x] = MEM[(c_char * {ref-all})&A.1]; } } } foo (integer(kind=4)[4] * restrict x) { { static integer(kind=4) A.0[4] = {3, 1, 4, 1}; MEM[(c_char * {ref-all})x] = MEM[(c_char * {ref-all})&A.0]; } } bar (integer(kind=4)[4] * restrict x) { { static integer(kind=4) A.1[4] = {3, 1, 4, 1}; MEM[(c_char * {ref-all})x] = MEM[(c_char * {ref-all})&A.1]; } } % set b [regexp -inline -all -- "memcpy|ref-all.*ref-all" $a] ref-all\})x\]\ =\ MEM\[(c_char\ *\ \{ref-all\})&A.0\]\;\n\ \ \}\n\}\n\n\nbar\ (integer(kind=4)\[4\]\ *\ restrict\ x)\n\{ \n\ \ \{\n\ \ \ \ static\ integer(kind=4)\ A.1\[4\]\ =\ \{3,\ 1,\ 4,\ 1\}\;\n\n\ \ \ \ MEM\[(c_char\ *\ \{ref-all\})x\]\ =\ MEM\[(c_char\ *\ \{ref-all % set b1 [llength $b] 1 % set c {foo (integer(kind=4)[4] * restrict x) { { static integer(kind=4) A.0[4] = {3, 1, 4, 1}; (void) __builtin_memcpy ((void *) x, (void *) &A.0, 16); } } bar (integer(kind=4)[4] * restrict x) { { static integer(kind=4) A.1[4] = {3, 1, 4, 1}; (void) __builtin_memcpy ((void *) x, (void *) &A.1, 16); } } } foo (integer(kind=4)[4] * restrict x) { { static integer(kind=4) A.0[4] = {3, 1, 4, 1}; (void) __builtin_memcpy ((void *) x, (void *) &A.0, 16); } } bar (integer(kind=4)[4] * restrict x) { { static integer(kind=4) A.1[4] = {3, 1, 4, 1}; (void) __builtin_memcpy ((void *) x, (void *) &A.1, 16); } } % set d [regexp -inline -all -- "memcpy|ref-all.*ref-all" $c] memcpy memcpy % set d1 [llength $d] 2 % set e [regexp -inline -all -- "memcpy|ref-all\[^\\n\]*ref-all" $a] ref-all\})x\]\ =\ MEM\[(c_char\ *\ \{ref-all ref-all\})x\]\ =\ MEM\[(c_char\ *\ \{ref-all % set e1 [llength $e] 2 % set f [regexp -inline -all -- "memcpy|ref-all\[^\\n\]*ref-all" $c] memcpy memcpy % set f1 [llength $f] 2 % set g [regexp -inline -all -- "memcpy|(ref-all.*ref-all)" $a] ref-all\})x\]\ =\ MEM\[(c_char\ *\ \{ref-all\})&A.0\]\;\n\ \ \}\n\}\n\n\nbar\ (integer(kind=4)\[4\]\ *\ restrict\ x)\n\{\n\ \ \{\n\ \ \ \ static\ integer(kind=4)\ A.1\[4\]\ =\ \{3,\ 1,\ 4,\ 1\}\;\n\n\ \ \ \ MEM\[(c_char\ *\ \{ref-all\})x\]\ =\ MEM\[(c_char\ *\ \{ref-all ref-all\})x\]\ =\ MEM\[(c_char\ *\ \{ref-all\})&A.0\]\;\n\ \ \}\n\}\n\n\nbar\ (integer(kind=4)\[4\]\ *\ restrict\ x)\n\{\n\ \ \{\n\ \ \ \ static\ integer(kind=4)\ A.1\[4\]\ =\ \{3,\ 1,\ 4,\ 1\}\;\n\n\ \ \ \ MEM\[(c_char\ *\ \{ref-all\})x\]\ =\ MEM\[(c_char\ *\ \{ref-all % set g1 [llength $g] 2 % set h [regexp -inline -all -- "memcpy|(ref-all.*ref-all)" $c] memcpy {} memcpy {} % set h1 [llength $h] 4 brgds, H-P differences, why cris-elf sees the (raw move) ref-all alternative instead of (call to __builtin_)memcpy, but since the test-case is expected to allow for it, and the final assembly looks ok (__builtin_memcpy-matching targets expanded to raw insns as well) I guess that's ok. > 2010-08-17 Richard Guenther > > PR testsuite/45266 > * gfortran.dg/array_memcpy_3.f90: Adjust pattern. > > Index: gcc/testsuite/gfortran.dg/array_memcpy_3.f90 > =================================================================== > --- gcc/testsuite/gfortran.dg/array_memcpy_3.f90 (revision 163281) > +++ gcc/testsuite/gfortran.dg/array_memcpy_3.f90 (working copy) > @@ -11,5 +11,5 @@ subroutine bar(x) > x = (/ 3, 1, 4, 1 /) > end subroutine > > -! { dg-final { scan-tree-dump-times "memcpy|(ref-all.*ref-all)" 2 "original" } } > +! { dg-final { scan-tree-dump-times "memcpy|ref-all.*ref-all" 2 "original" } } > ! { dg-final { cleanup-tree-dump "original" } } Follow-up fix committed as obvious (after verifying on cris-elf and native x86_64-guess-what) after the following tclsh session (I observed the same behavior for tcl-8.4). gcc/testsuite: PR testsuite/45545 * gfortran.dg/array_memcpy_3.f90: Correct pattern for ref-all-matching targets. Index: gfortran.dg/array_memcpy_3.f90 =================================================================== --- gfortran.dg/array_memcpy_3.f90 (revision 163868) +++ gfortran.dg/array_memcpy_3.f90 (working copy) @@ -11,5 +11,5 @@ subroutine bar(x) x = (/ 3, 1, 4, 1 /) end subroutine -! { dg-final { scan-tree-dump-times "memcpy|ref-all.*ref-all" 2 "original" } } +! { dg-final { scan-tree-dump-times "memcpy|ref-all\[^\\n\]*ref-all" 2 "original" } } ! { dg-final { cleanup-tree-dump "original" } }