There is currently no support for matching at least x lines of assembly (only scan-assembler-times). This patch would allow setting upper or lower bounds.
Use case: using different scheduler descriptions and/or cost models will change assembler output. Testing common functionality across tunes would require a separate testcase per tune since each assembly output would be different. If we know a base number of lines should appear across all tunes (i.e. testing return values: we expect at minimum n stores into register x), we can lower-bound the test to search for scan-assembler-bound {RE for storing into register x} >= n. This avoids artificially inflating the scan-assembler-times expected count due to the assembler choosing to perform extra stores into register x (using it as a temporary register). The testcase would be more robust to cpu/tune changes at the cost of not being as granular towards specific cpu tuning. gcc/ChangeLog: * doc/sourcebuild.texi: add scan-assembler-bound gcc/testsuite/ChangeLog: * lib/scanasm.exp: add scan-assembler-bound Signed-off-by: Edwin Lu <e...@rivosinc.com> --- gcc/doc/sourcebuild.texi | 4 +++ gcc/testsuite/lib/scanasm.exp | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi index 193be19767f..4a8c672c9fd 100644 --- a/gcc/doc/sourcebuild.texi +++ b/gcc/doc/sourcebuild.texi @@ -3396,6 +3396,10 @@ excluding LTO sections. Passes if @var{regex} is matched exactly @var{num} times in the test's assembler output, excluding LTO sections. +@item scan-assembler-bound @var{regex} @var{cmp} @var{num} [@{ target/xfail @var{selector} @}] +Passes if @var{regex} is matched @var{cmp} @var{num} times in the test's +assembler output, excluding LTO sections. @var{cmp} is a comparitor. + @item scan-assembler-dem @var{regex} [@{ target/xfail @var{selector} @}] Passes if @var{regex} matches text in the test's demangled assembler output, excluding LTO sections. diff --git a/gcc/testsuite/lib/scanasm.exp b/gcc/testsuite/lib/scanasm.exp index 165890eb976..741a5a048b8 100644 --- a/gcc/testsuite/lib/scanasm.exp +++ b/gcc/testsuite/lib/scanasm.exp @@ -516,6 +516,70 @@ proc scan-assembler-times { args } { set_required_options_for scan-assembler-times +# Call pass if pattern is present within a lower or upper bound, +# otherwise fail. +# ex /* { dg-final { scan-assembler-bound {RE} > 3 } } +proc scan-assembler-bound { args } { + if { [llength $args] < 3 } { + error "scan-assembler-bound: too few arguments" + return + } + if { [llength $args] > 4 } { + error "scan-assembler-bound: too many arguments" + return + } + if { [llength $args] >= 4 } { + switch [dg-process-target [lindex $args 3]] { + "S" { } + "N" { return } + "F" { setup_xfail "*-*-*" } + "P" { } + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + set pattern [lindex $args 0] + set cmp [lindex $args 1] + set bound [lindex $args 2] + set pp_pattern [make_pattern_printable $pattern] + + # This must match the rule in gcc-dg.exp. + set output_file "[file rootname [file tail $filename]].s" + + set files [glob -nocomplain $output_file] + if { $files == "" } { + verbose -log "$testcase: output file does not exist" + unresolved "$testcase scan-assembler-bound $pp_pattern $min $max" + return + } + + if { [lsearch { < > <= >= } $cmp] == -1 } { + error "scan-assembler-bound: illegal argument: $cmp" + return + } + if ![string is integer $bound ] { + error "scan-assembler-bound: illegal argument: $bound" + return + } + + set fd [open $output_file r] + set text [read $fd] + close $fd + regsub -all {(^|\n)[[:space:]]*\.section[[:space:]]*"?\.gnu\.lto_(?:[^\n]*\n(?![[:space:]]*\.(section|text|data|bss)))*[^\n]*\n} $text {\1} text + + set result_count [regexp -all -- $pattern $text] + if [expr $result_count $cmp $bound] { + pass "$testcase scan-assembler-bound $pp_pattern $cmp $bound" + } else { + verbose -log "$testcase: $pp_pattern found $result_count times" + fail "$testcase scan-assembler-bound $pp_pattern $cmp $bound" + } +} + +set_required_options_for scan-assembler-bound + # Utility for scanning demangled compiler result, invoked via dg-final. # Call pass if pattern is present, otherwise fail. proc scan-assembler-dem { args } { -- 2.34.1