Message ID | 20240822210554.1172978-1-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | [v2] Extend check-function-bodies to allow label and directives | expand |
"H.J. Lu" <hjl.tools@gmail.com> writes: > As PR target/116174 shown, we may need to verify labels and the directive > order. Extend check-function-bodies to support matched output lines to > allow label and directives. > > gcc/ > > * doc/sourcebuild.texi (check-function-bodies): Add an optional > argument for matched output lines. > > gcc/testsuite/ > > * gcc.target/i386/pr116174.c: Use check-function-bodies. > * lib/scanasm.exp (parse_function_bodies): Append the line if > $up_config(matched) matches the line. > (check-function-bodies): Add an argument for matched. Set > up_config(matched) to $matched. Append the expected line without > $config(line_prefix) to function_regexp if it starts with ".L". > > Signed-off-by: H.J. Lu <hjl.tools@gmail.com> > --- > gcc/doc/sourcebuild.texi | 6 +++++- > gcc/testsuite/gcc.target/i386/pr116174.c | 18 +++++++++++++++--- > gcc/testsuite/lib/scanasm.exp | 14 ++++++++++++-- > 3 files changed, 32 insertions(+), 6 deletions(-) > > diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi > index 1a31f00fb65..f7128f445cf 100644 > --- a/gcc/doc/sourcebuild.texi > +++ b/gcc/doc/sourcebuild.texi > @@ -3530,7 +3530,7 @@ assembly output. > Passes if @var{symbol} is not defined as a hidden symbol in the test's > assembly output. > > -@item check-function-bodies @var{prefix} @var{terminator} [@var{options} [@{ target/xfail @var{selector} @}]] > +@item check-function-bodies @var{prefix} @var{terminator} [@var{options} [@{ target/xfail @var{selector} @} [@var{matched}]]] > Looks through the source file for comments that give the expected assembly > output for selected functions. Each line of expected output starts with the > prefix string @var{prefix} and the expected output for a function as a whole > @@ -3544,6 +3544,10 @@ command line. This can help if a source file is compiled both with > and without optimization, since it is rarely useful to check the full > function body for unoptimized code. > > +@var{matched}, if specified, is a regular expression which matches a > +line of the function body. If @var{matched} isn't specified, lines > +beginning with labels, directives and comments are ignored. > + How about instead splitting: Depending on the configuration (see @code{configure_check-function-bodies} in @file{gcc/testsuite/lib/scanasm.exp}), the test may discard from the compiler's assembly output directives such as @code{.cfi_startproc}, local label definitions such as @code{.LFB0}, and more. It then matches the result against the expected output for a function as a single regular expression. This means that later lines can use backslashes to refer back to @samp{(@dots{})} captures on earlier lines. For example: into two paragraphs at "If then", and describing the new behaviour at the end of the first paragraph: ------------------------------------------------------------------------ Depending on the configuration (see @code{configure_check-function-bodies} in @file{gcc/testsuite/lib/scanasm.exp}), the test may discard from the compiler's assembly output directives such as @code{.cfi_startproc}, local label definitions such as @code{.LFB0}, and more. This behavior can be overridden using the optional @var{matched} argument, which specifies a regexp for lines that should not be discarded in this way. The test then matches the result against the expected output for a function as a single regular expression. This means that later lines can use backslashes to refer back to @samp{(@dots{})} captures on earlier lines. For example: ------------------------------------------------------------------------ > The first line of the expected output for a function @var{fn} has the form: > > @smallexample > diff --git a/gcc/testsuite/gcc.target/i386/pr116174.c b/gcc/testsuite/gcc.target/i386/pr116174.c > index 8877d0b51af..91ec3288786 100644 > --- a/gcc/testsuite/gcc.target/i386/pr116174.c > +++ b/gcc/testsuite/gcc.target/i386/pr116174.c > @@ -1,6 +1,20 @@ > /* { dg-do compile { target *-*-linux* } } */ > -/* { dg-options "-O2 -fcf-protection=branch" } */ > +/* { dg-options "-O2 -g0 -fcf-protection=branch" } */ > +/* Keep labels and directives ('.p2align', '.cfi_startproc'). > +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {.*} } } */ This works, but matches everything. Maybe {^\t?\.} would be more precise. The current version is fine too though, if you think it will work for all assembly dialects. > > +/* > +**foo: > +**.LFB0: > +** .cfi_startproc > +** ( > +** endbr64 > +** .p2align 5 > +** | > +** endbr32 > +** ) > +**... > +*/ > char * > foo (char *dest, const char *src) > { > @@ -8,5 +22,3 @@ foo (char *dest, const char *src) > /* nothing */; > return --dest; > } > - > -/* { dg-final { scan-assembler "\t\.cfi_startproc\n\tendbr(32|64)\n" } } */ > diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp > index 42c719c512c..9dc99836762 100644 > --- a/gcc/testsuite/lib/scanasm.exp > +++ b/gcc/testsuite/lib/scanasm.exp > @@ -952,6 +952,8 @@ proc parse_function_bodies { config filename result } { > verbose "parse_function_bodies: $function_name:\n$function_body" > set up_result($function_name) $function_body > set in_function 0 > + } elseif { $up_config(matched) ne "" && [regexp $up_config(matched) $line] } { Nit: long line: } elseif { $up_config(matched) ne "" && [regexp $up_config(matched) $line] } { > + append function_body $line "\n" > } elseif { [regexp $up_config(fluff) $line] } { > verbose "parse_function_bodies: $function_name: ignoring fluff line: $line" > } else { > @@ -982,7 +984,7 @@ proc check_function_body { functions name body_regexp } { > > # Check the implementations of functions against expected output. Used as: > # > -# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION[ SELECTOR]] } } > +# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION[ SELECTOR [MATCHED]]] } } > # > # See sourcebuild.texi for details. > > @@ -990,7 +992,7 @@ proc check-function-bodies { args } { > if { [llength $args] < 2 } { > error "too few arguments to check-function-bodies" > } > - if { [llength $args] > 4 } { > + if { [llength $args] > 5 } { > error "too many arguments to check-function-bodies" > } > > @@ -1029,6 +1031,11 @@ proc check-function-bodies { args } { > } > } > > + set matched "" > + if { [llength $args] >= 5 } { > + set matched [lindex $args 4] > + } > + > set testcase [testname-for-summary] > # The name might include a list of options; extract the file name. > set filename [lindex $testcase 0] > @@ -1048,6 +1055,7 @@ proc check-function-bodies { args } { > # (name in \1). This may be different from '$config(start)'. > set start_expected {^(\S+):$} > > + set config(matched) $matched > configure_check-function-bodies config > set have_bodies 0 > if { [is_remote host] } { > @@ -1090,6 +1098,8 @@ proc check-function-bodies { args } { > append function_regexp ")" > } elseif { [string equal $line "..."] } { > append function_regexp ".*" > + } elseif { [regexp "^.L.*" $line] } { {^\.L} would be more precise than "^.L.*". OK with those changes, thanks, and also without the suggested change to pr116174.c. Richard > + append function_regexp $line "\n" > } else { > append function_regexp $config(line_prefix) $line "\n" > }
On Tue, Aug 27, 2024 at 2:18 AM Richard Sandiford <richard.sandiford@arm.com> wrote: > > "H.J. Lu" <hjl.tools@gmail.com> writes: > > As PR target/116174 shown, we may need to verify labels and the directive > > order. Extend check-function-bodies to support matched output lines to > > allow label and directives. > > > > gcc/ > > > > * doc/sourcebuild.texi (check-function-bodies): Add an optional > > argument for matched output lines. > > > > gcc/testsuite/ > > > > * gcc.target/i386/pr116174.c: Use check-function-bodies. > > * lib/scanasm.exp (parse_function_bodies): Append the line if > > $up_config(matched) matches the line. > > (check-function-bodies): Add an argument for matched. Set > > up_config(matched) to $matched. Append the expected line without > > $config(line_prefix) to function_regexp if it starts with ".L". > > > > Signed-off-by: H.J. Lu <hjl.tools@gmail.com> > > --- > > gcc/doc/sourcebuild.texi | 6 +++++- > > gcc/testsuite/gcc.target/i386/pr116174.c | 18 +++++++++++++++--- > > gcc/testsuite/lib/scanasm.exp | 14 ++++++++++++-- > > 3 files changed, 32 insertions(+), 6 deletions(-) > > > > diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi > > index 1a31f00fb65..f7128f445cf 100644 > > --- a/gcc/doc/sourcebuild.texi > > +++ b/gcc/doc/sourcebuild.texi > > @@ -3530,7 +3530,7 @@ assembly output. > > Passes if @var{symbol} is not defined as a hidden symbol in the test's > > assembly output. > > > > -@item check-function-bodies @var{prefix} @var{terminator} [@var{options} [@{ target/xfail @var{selector} @}]] > > +@item check-function-bodies @var{prefix} @var{terminator} [@var{options} [@{ target/xfail @var{selector} @} [@var{matched}]]] > > Looks through the source file for comments that give the expected assembly > > output for selected functions. Each line of expected output starts with the > > prefix string @var{prefix} and the expected output for a function as a whole > > @@ -3544,6 +3544,10 @@ command line. This can help if a source file is compiled both with > > and without optimization, since it is rarely useful to check the full > > function body for unoptimized code. > > > > +@var{matched}, if specified, is a regular expression which matches a > > +line of the function body. If @var{matched} isn't specified, lines > > +beginning with labels, directives and comments are ignored. > > + > > How about instead splitting: > > Depending on the configuration (see > @code{configure_check-function-bodies} in > @file{gcc/testsuite/lib/scanasm.exp}), the test may discard from the > compiler's assembly output directives such as @code{.cfi_startproc}, > local label definitions such as @code{.LFB0}, and more. > It then matches the result against the expected > output for a function as a single regular expression. This means that > later lines can use backslashes to refer back to @samp{(@dots{})} > captures on earlier lines. For example: > > into two paragraphs at "If then", and describing the new behaviour at > the end of the first paragraph: > > ------------------------------------------------------------------------ > Depending on the configuration (see > @code{configure_check-function-bodies} in > @file{gcc/testsuite/lib/scanasm.exp}), the test may discard from the > compiler's assembly output directives such as @code{.cfi_startproc}, > local label definitions such as @code{.LFB0}, and more. This behavior > can be overridden using the optional @var{matched} argument, which > specifies a regexp for lines that should not be discarded in this way. > > The test then matches the result against the expected > output for a function as a single regular expression. This means that > later lines can use backslashes to refer back to @samp{(@dots{})} > captures on earlier lines. For example: > ------------------------------------------------------------------------ Fixed in v3. > > The first line of the expected output for a function @var{fn} has the form: > > > > @smallexample > > diff --git a/gcc/testsuite/gcc.target/i386/pr116174.c b/gcc/testsuite/gcc.target/i386/pr116174.c > > index 8877d0b51af..91ec3288786 100644 > > --- a/gcc/testsuite/gcc.target/i386/pr116174.c > > +++ b/gcc/testsuite/gcc.target/i386/pr116174.c > > @@ -1,6 +1,20 @@ > > /* { dg-do compile { target *-*-linux* } } */ > > -/* { dg-options "-O2 -fcf-protection=branch" } */ > > +/* { dg-options "-O2 -g0 -fcf-protection=branch" } */ > > +/* Keep labels and directives ('.p2align', '.cfi_startproc'). > > +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {.*} } } */ > > This works, but matches everything. Maybe {^\t?\.} would be more precise. Fixed in v3. > The current version is fine too though, if you think it will work for all > assembly dialects. > > > > > +/* > > +**foo: > > +**.LFB0: > > +** .cfi_startproc > > +** ( > > +** endbr64 > > +** .p2align 5 > > +** | > > +** endbr32 > > +** ) > > +**... > > +*/ > > char * > > foo (char *dest, const char *src) > > { > > @@ -8,5 +22,3 @@ foo (char *dest, const char *src) > > /* nothing */; > > return --dest; > > } > > - > > -/* { dg-final { scan-assembler "\t\.cfi_startproc\n\tendbr(32|64)\n" } } */ > > diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp > > index 42c719c512c..9dc99836762 100644 > > --- a/gcc/testsuite/lib/scanasm.exp > > +++ b/gcc/testsuite/lib/scanasm.exp > > @@ -952,6 +952,8 @@ proc parse_function_bodies { config filename result } { > > verbose "parse_function_bodies: $function_name:\n$function_body" > > set up_result($function_name) $function_body > > set in_function 0 > > + } elseif { $up_config(matched) ne "" && [regexp $up_config(matched) $line] } { > > Nit: long line: Fixed in v3. > > } elseif { $up_config(matched) ne "" > && [regexp $up_config(matched) $line] } { > > > + append function_body $line "\n" > > } elseif { [regexp $up_config(fluff) $line] } { > > verbose "parse_function_bodies: $function_name: ignoring fluff line: $line" > > } else { > > @@ -982,7 +984,7 @@ proc check_function_body { functions name body_regexp } { > > > > # Check the implementations of functions against expected output. Used as: > > # > > -# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION[ SELECTOR]] } } > > +# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION[ SELECTOR [MATCHED]]] } } > > # > > # See sourcebuild.texi for details. > > > > @@ -990,7 +992,7 @@ proc check-function-bodies { args } { > > if { [llength $args] < 2 } { > > error "too few arguments to check-function-bodies" > > } > > - if { [llength $args] > 4 } { > > + if { [llength $args] > 5 } { > > error "too many arguments to check-function-bodies" > > } > > > > @@ -1029,6 +1031,11 @@ proc check-function-bodies { args } { > > } > > } > > > > + set matched "" > > + if { [llength $args] >= 5 } { > > + set matched [lindex $args 4] > > + } > > + > > set testcase [testname-for-summary] > > # The name might include a list of options; extract the file name. > > set filename [lindex $testcase 0] > > @@ -1048,6 +1055,7 @@ proc check-function-bodies { args } { > > # (name in \1). This may be different from '$config(start)'. > > set start_expected {^(\S+):$} > > > > + set config(matched) $matched > > configure_check-function-bodies config > > set have_bodies 0 > > if { [is_remote host] } { > > @@ -1090,6 +1098,8 @@ proc check-function-bodies { args } { > > append function_regexp ")" > > } elseif { [string equal $line "..."] } { > > append function_regexp ".*" > > + } elseif { [regexp "^.L.*" $line] } { > > {^\.L} would be more precise than "^.L.*". I tried {^\.L}. It didn't work. I used "^.L" in v3. > OK with those changes, thanks, and also without the suggested change > to pr116174.c. The v3 patch is at https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661580.html Thanks.
"H.J. Lu" <hjl.tools@gmail.com> writes: >> > append function_regexp ")" >> > } elseif { [string equal $line "..."] } { >> > append function_regexp ".*" >> > + } elseif { [regexp "^.L.*" $line] } { >> >> {^\.L} would be more precise than "^.L.*". > > I tried {^\.L}. It didn't work. I used "^.L" in v3. Why didn't it work though? "^.L.*" matches "ALL" as well as ".L". Richard
On Tue, Aug 27, 2024 at 6:54 AM Richard Sandiford <richard.sandiford@arm.com> wrote: > > "H.J. Lu" <hjl.tools@gmail.com> writes: > >> > append function_regexp ")" > >> > } elseif { [string equal $line "..."] } { > >> > append function_regexp ".*" > >> > + } elseif { [regexp "^.L.*" $line] } { > >> > >> {^\.L} would be more precise than "^.L.*". > > > > I tried {^\.L}. It didn't work. I used "^.L" in v3. > > Why didn't it work though? "^.L.*" matches "ALL" as well as ".L". > > Richard I tried it again by typing it by hand. It works now. Fixed in v4: https://gcc.gnu.org/pipermail/gcc-patches/2024-August/661586.html Thanks. -- H.J.
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 1a31f00fb65..f7128f445cf 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -3530,7 +3530,7 @@ assembly output. Passes if @var{symbol} is not defined as a hidden symbol in the test's assembly output. -@item check-function-bodies @var{prefix} @var{terminator} [@var{options} [@{ target/xfail @var{selector} @}]] +@item check-function-bodies @var{prefix} @var{terminator} [@var{options} [@{ target/xfail @var{selector} @} [@var{matched}]]] Looks through the source file for comments that give the expected assembly output for selected functions. Each line of expected output starts with the prefix string @var{prefix} and the expected output for a function as a whole @@ -3544,6 +3544,10 @@ command line. This can help if a source file is compiled both with and without optimization, since it is rarely useful to check the full function body for unoptimized code. +@var{matched}, if specified, is a regular expression which matches a +line of the function body. If @var{matched} isn't specified, lines +beginning with labels, directives and comments are ignored. + The first line of the expected output for a function @var{fn} has the form: @smallexample diff --git a/gcc/testsuite/gcc.target/i386/pr116174.c b/gcc/testsuite/gcc.target/i386/pr116174.c index 8877d0b51af..91ec3288786 100644 --- a/gcc/testsuite/gcc.target/i386/pr116174.c +++ b/gcc/testsuite/gcc.target/i386/pr116174.c @@ -1,6 +1,20 @@ /* { dg-do compile { target *-*-linux* } } */ -/* { dg-options "-O2 -fcf-protection=branch" } */ +/* { dg-options "-O2 -g0 -fcf-protection=branch" } */ +/* Keep labels and directives ('.p2align', '.cfi_startproc'). +/* { dg-final { check-function-bodies "**" "" "" { target "*-*-*" } {.*} } } */ +/* +**foo: +**.LFB0: +** .cfi_startproc +** ( +** endbr64 +** .p2align 5 +** | +** endbr32 +** ) +**... +*/ char * foo (char *dest, const char *src) { @@ -8,5 +22,3 @@ foo (char *dest, const char *src) /* nothing */; return --dest; } - -/* { dg-final { scan-assembler "\t\.cfi_startproc\n\tendbr(32|64)\n" } } */ diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp index 42c719c512c..9dc99836762 100644 --- a/gcc/testsuite/lib/scanasm.exp +++ b/gcc/testsuite/lib/scanasm.exp @@ -952,6 +952,8 @@ proc parse_function_bodies { config filename result } { verbose "parse_function_bodies: $function_name:\n$function_body" set up_result($function_name) $function_body set in_function 0 + } elseif { $up_config(matched) ne "" && [regexp $up_config(matched) $line] } { + append function_body $line "\n" } elseif { [regexp $up_config(fluff) $line] } { verbose "parse_function_bodies: $function_name: ignoring fluff line: $line" } else { @@ -982,7 +984,7 @@ proc check_function_body { functions name body_regexp } { # Check the implementations of functions against expected output. Used as: # -# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION[ SELECTOR]] } } +# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION[ SELECTOR [MATCHED]]] } } # # See sourcebuild.texi for details. @@ -990,7 +992,7 @@ proc check-function-bodies { args } { if { [llength $args] < 2 } { error "too few arguments to check-function-bodies" } - if { [llength $args] > 4 } { + if { [llength $args] > 5 } { error "too many arguments to check-function-bodies" } @@ -1029,6 +1031,11 @@ proc check-function-bodies { args } { } } + set matched "" + if { [llength $args] >= 5 } { + set matched [lindex $args 4] + } + set testcase [testname-for-summary] # The name might include a list of options; extract the file name. set filename [lindex $testcase 0] @@ -1048,6 +1055,7 @@ proc check-function-bodies { args } { # (name in \1). This may be different from '$config(start)'. set start_expected {^(\S+):$} + set config(matched) $matched configure_check-function-bodies config set have_bodies 0 if { [is_remote host] } { @@ -1090,6 +1098,8 @@ proc check-function-bodies { args } { append function_regexp ")" } elseif { [string equal $line "..."] } { append function_regexp ".*" + } elseif { [regexp "^.L.*" $line] } { + append function_regexp $line "\n" } else { append function_regexp $config(line_prefix) $line "\n" }
As PR target/116174 shown, we may need to verify labels and the directive order. Extend check-function-bodies to support matched output lines to allow label and directives. gcc/ * doc/sourcebuild.texi (check-function-bodies): Add an optional argument for matched output lines. gcc/testsuite/ * gcc.target/i386/pr116174.c: Use check-function-bodies. * lib/scanasm.exp (parse_function_bodies): Append the line if $up_config(matched) matches the line. (check-function-bodies): Add an argument for matched. Set up_config(matched) to $matched. Append the expected line without $config(line_prefix) to function_regexp if it starts with ".L". Signed-off-by: H.J. Lu <hjl.tools@gmail.com> --- gcc/doc/sourcebuild.texi | 6 +++++- gcc/testsuite/gcc.target/i386/pr116174.c | 18 +++++++++++++++--- gcc/testsuite/lib/scanasm.exp | 14 ++++++++++++-- 3 files changed, 32 insertions(+), 6 deletions(-)