From patchwork Tue Jul 16 14:04:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1132790 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-505151-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="uSJgM9oh"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45p2GY5HM3z9s7T for ; Wed, 17 Jul 2019 00:05:08 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; q=dns; s= default; b=aSgRWYL1b2y5bq3zz9N0yslMBUuRk+eLGmoAxH4emJRyyw/JpIvVF 10Nb7GoxkEEDTsOyN6G+4B+URyRdkxDlElFfkAhuDtYja7tygA/GTFn8r6aSiCUP Z1md2CtRo1DyY0AkBkqAajN/oiEfk6hW8eA7I/Jvf7ak9oKBudi3XM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type; s= default; bh=HBsA2VuryvL2ff4jS/pUxkecl6A=; b=uSJgM9ohmrjzsJKwqxIq QX9kPLOLXFX3WUZQSSN7yesj6T/kyMqTBg3eSiX5Kqr57lGC/e9xtgyNIivOt0Op wFjhTX6hZGHiQ9pYTLZBzOm/jJ1LmCDhfVe0lMZw8c/DPQLLlNtN3fQ9kjrYP0tn pIf/SxWNNa+77DD63XvVWJY= Received: (qmail 66721 invoked by alias); 16 Jul 2019 14:04:59 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 66713 invoked by uid 89); 16 Jul 2019 14:04:59 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-10.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS autolearn=ham version=3.3.1 spammy=54, 5.5, demo, 5.3 X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 16 Jul 2019 14:04:52 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C1D9E344 for ; Tue, 16 Jul 2019 07:04:50 -0700 (PDT) Received: from localhost (e121540-lin.manchester.arm.com [10.32.98.39]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 4CA0F3F59C for ; Tue, 16 Jul 2019 07:04:50 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: Add dg test for matching function bodies Date: Tue, 16 Jul 2019 15:04:49 +0100 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes There isn't a 1:1 mapping from SVE intrinsics to SVE instructions, but the intrinsics are still close enough to the instructions for there to be a specific preferred sequence (or sometimes choice of preferred sequences) for a given combination of operands. Sometimes these sequences will be one instruction, sometimes they'll be several. I therefore wanted a convenient way of matching the exact assembly implementation of a given function. It's possible to do that using single scan-assembler lines, but: (a) they become hard to read for multiline matches (b) the PASS/FAIL lines tend to be long (c) it's useful to have a single place that skips over uninteresting lines, such as entry block labels and .cfi_* directives, without being overly broad This patch therefore adds a new check-function-bodies dg-final test that looks for specially-formatted comments. As a demo, the patch converts the SVE vec_init tests to use the new harness instead of scan-assembler. The regexps in parse_function_bodies are fairly general, but might still need to be extended in future for targets like Darwin or AIX. Tested on aarch64-linux-gnu (and x86_64-linux-gnu, somewhat pointlessly given the contents of the patch). OK to install? Richard 2019-07-16 Richard Sandiford gcc/ * doc/sourcebuild.texi (check-function-bodies): Document. gcc/testsuite/ * lib/scanasm.exp (parse_function_bodies, check_function_body) (check-function-bodies): New procedures. * gcc.target/aarch64/sve/init_1.c: Use check-function-bodies instead of scan-assembler. * gcc.target/aarch64/sve/init_2.c: Likewise. * gcc.target/aarch64/sve/init_3.c: Likewise. * gcc.target/aarch64/sve/init_4.c: Likewise. * gcc.target/aarch64/sve/init_5.c: Likewise. * gcc.target/aarch64/sve/init_6.c: Likewise. * gcc.target/aarch64/sve/init_7.c: Likewise. * gcc.target/aarch64/sve/init_8.c: Likewise. * gcc.target/aarch64/sve/init_9.c: Likewise. * gcc.target/aarch64/sve/init_10.c: Likewise. * gcc.target/aarch64/sve/init_11.c: Likewise. * gcc.target/aarch64/sve/init_12.c: Likewise. Index: gcc/doc/sourcebuild.texi =================================================================== --- gcc/doc/sourcebuild.texi 2019-07-01 09:37:04.424547899 +0100 +++ gcc/doc/sourcebuild.texi 2019-07-16 14:57:25.602820637 +0100 @@ -2669,6 +2669,91 @@ assembly output. @item scan-not-hidden @var{symbol} [@{ target/xfail @var{selector} @}] 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{option}] +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 +is followed by a line that starts with the string @var{terminator}. +Specifying an empty terminator is equivalent to specifying @samp{"*/"}. + +If @var{option} is specified, the test only applies to command lines +that contain @var{option}. This can be useful if a source file is compiled +both with and without optimization, since it is rarely useful to check the +assembly output for unoptimized code. + +The first line of the expected output for a function @var{fn} has the form: + +@smallexample +@var{prefix} @var{fn}: [@{ target/xfail @var{selector} @}] +@end smallexample + +Subsequent lines of the expected output also start with @var{prefix}. +In both cases, whitespace after @var{prefix} is not significant. + +The test discards assembly directives such as @code{.cfi_startproc} +and local label definitions such as @code{.LFB0} from the compiler's +assembly output. 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: + +@smallexample +/* @{ dg-final @{ check-function-bodies "**" "" "-DCHECK_ASM" @} @} */ +@dots{} +/* +** add_w0_s8_m: +** mov (z[0-9]+\.b), w0 +** add z0\.b, p0/m, z0\.b, \1 +** ret +*/ +svint8_t add_w0_s8_m (@dots{}) @{ @dots{} @} +@dots{} +/* +** add_b0_s8_m: +** mov (z[0-9]+\.b), b0 +** add z1\.b, p0/m, z1\.b, \1 +** ret +*/ +svint8_t add_b0_s8_m (@dots{}) @{ @dots{} @} +@end smallexample + +checks whether the implementations of @code{add_w0_s8_m} and +@code{add_b0_s8_m} match the regular expressions given. The test only +runs when @samp{-DCHECK_ASM} is passed on the command line. + +It is possible to create non-capturing multi-line regular expression +groups of the form @samp{(@var{a}|@var{b}|@dots{})} by putting the +@samp{(}, @samp{|} and @samp{)} on separate lines (each still using +@var{prefix}). For example: + +@smallexample +/* +** cmple_f16_tied: +** ( +** fcmge p0\.h, p0/z, z1\.h, z0\.h +** | +** fcmle p0\.h, p0/z, z0\.h, z1\.h +** ) +** ret +*/ +svbool_t cmple_f16_tied (@dots{}) @{ @dots{} @} +@end smallexample + +checks whether @code{cmple_f16_tied} is implemented by the +@code{fcmge} instruction followed by @code{ret} or by the +@code{fcmle} instruction followed by @code{ret}. The test is +still a single regular rexpression. + +A line containing just: + +@smallexample +@var{prefix} ... +@end smallexample + +stands for zero or more unmatched lines; the whitespace after +@var{prefix} is again not significant. + @end table @subsubsection Scan optimization dump files Index: gcc/testsuite/lib/scanasm.exp =================================================================== --- gcc/testsuite/lib/scanasm.exp 2019-06-18 09:35:53.045884968 +0100 +++ gcc/testsuite/lib/scanasm.exp 2019-07-16 14:57:25.602820637 +0100 @@ -546,3 +546,169 @@ proc scan-lto-assembler { args } { verbose "output_file: $output_file" dg-scan "scan-lto-assembler" 1 $testcase $output_file $args } + +# Read assembly file FILENAME and store a mapping from function names +# to function bodies in array RESULT. FILENAME has already been uploaded +# locally where necessary and is known to exist. + +proc parse_function_bodies { filename result } { + upvar $result up_result + + # Regexp for the start of a function definition (name in \1). + set label {^([a-zA-Z_]\S+):$} + + # Regexp for the end of a function definition. + set terminator {^\s*\.size} + + # Regexp for lines that aren't interesting. + set fluff {^\s*(?:\.|//)} + + set fd [open $filename r] + set in_function 0 + while { [gets $fd line] >= 0 } { + if { [regexp $label $line dummy function_name] } { + set in_function 1 + set function_body "" + } elseif { $in_function } { + if { [regexp $terminator $line] } { + set up_result($function_name) $function_body + set in_function 0 + } elseif { ![regexp $fluff $line] } { + append function_body $line "\n" + } + } + } + close $fd +} + +# FUNCTIONS is an array that maps function names to function bodies. +# Return true if it contains a definition of function NAME and if +# that definition matches BODY_REGEXP. + +proc check_function_body { functions name body_regexp } { + upvar $functions up_functions + + if { ![info exists up_functions($name)] } { + return 0 + } + return [regexp "^$body_regexp\$" $up_functions($name)] +} + +# Check the implementations of functions against expected output. Used as: +# +# { dg-do { check-function-bodies PREFIX TERMINATOR[ OPTION] } } +# +# See sourcebuild.texi for details. + +proc check-function-bodies { args } { + if { [llength $args] < 2 } { + error "too few arguments to check-function-bodies" + } + if { [llength $args] > 3 } { + error "too many arguments to check-function-bodies" + } + + if { [llength $args] == 3 } { + set required_flag [lindex $args 2] + + upvar 2 dg-extra-tool-flags extra_tool_flags + set flags $extra_tool_flags + + global torture_current_flags + if { [info exists torture_current_flags] } { + append flags " " $torture_current_flags + } + if { ![regexp " $required_flag " $flags] } { + return + } + } + + set testcase [testname-for-summary] + # The name might include a list of options; extract the file name. + set filename [lindex $testcase 0] + + global srcdir + set input_filename "$srcdir/$filename" + set output_filename "[file rootname [file tail $filename]].s" + + set prefix [lindex $args 0] + set prefix_len [string length $prefix] + set terminator [lindex $args 1] + if { [string equal $terminator ""] } { + set terminator "*/" + } + set terminator_len [string length $terminator] + + set have_bodies 0 + if { [is_remote host] } { + remote_upload host "$filename" + } + if { [file exists $output_filename] } { + parse_function_bodies $output_filename functions + set have_bodies 1 + } else { + verbose -log "$testcase: output file does not exist" + } + + set count 0 + set function_regexp "" + set label {^(\S+):$} + + set lineno 1 + set fd [open $input_filename r] + set in_function 0 + while { [gets $fd line] >= 0 } { + if { [string equal -length $prefix_len $line $prefix] } { + set line [string trim [string range $line $prefix_len end]] + if { !$in_function } { + if { [regexp "^(.*\\S)\\s+{(.*)}\$" $line dummy \ + line selector] } { + set selector [dg-process-target $selector] + } else { + set selector "P" + } + if { ![regexp $label $line dummy function_name] } { + close $fd + error "check-function-bodies: line $lineno does not have a function label" + } + set in_function 1 + set function_regexp "" + } elseif { [string equal $line "("] } { + append function_regexp "(?:" + } elseif { [string equal $line "|"] } { + append function_regexp "|" + } elseif { [string equal $line ")"] } { + append function_regexp ")" + } elseif { [string equal $line "..."] } { + append function_regexp ".*" + } else { + append function_regexp "\t" $line "\n" + } + } elseif { [string equal -length $terminator_len $line $terminator] } { + if { ![string equal $selector "N"] } { + if { [string equal $selector "F"] } { + setup_xfail "*-*-*" + } + set testname "$testcase check-function-bodies $function_name" + if { !$have_bodies } { + unresolved $testname + } elseif { [check_function_body functions $function_name \ + $function_regexp] } { + pass $testname + } else { + fail $testname + } + } + set in_function 0 + incr count + } + incr lineno + } + close $fd + if { $in_function } { + error "check-function-bodies: missing \"$terminator\"" + } + if { $count == 0 } { + error "check-function-bodies: no matches found" + } +} Index: gcc/testsuite/gcc.target/aarch64/sve/init_1.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_1.c 2019-06-18 09:35:52.945885794 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_1.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 1.1: Trailing constants with stepped sequence. */ @@ -7,20 +8,15 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** index (z[0-9]+\.s), #1, #1 +** insr \1, w1 +** insr \1, w0 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b) { return (vnx4si) { a, b, 1, 2, 3, 4, 5, 6 }; } - -/* -foo: -.LFB0: - .cfi_startproc - index z0.s, #1, #1 - insr z0.s, w1 - insr z0.s, w0 - ret -*/ - -/* { dg-final { scan-assembler {\tindex\t(z[0-9]+\.s), #1, #1\n\tinsr\t\1, w1\n\tinsr\t\1, w0} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_2.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_2.c 2019-06-18 09:35:52.945885794 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_2.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 1.2: Trailing constants with repeating sequence. */ @@ -7,23 +8,16 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** ... +** ld1w (z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\] +** insr \1, w1 +** insr \1, w0 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b) { return (vnx4si) { a, b, 2, 3, 2, 3, 2, 3 }; } - -/* -foo: -.LFB0: - .cfi_startproc - ptrue p0.s, vl8 - adrp x2, .LANCHOR0 - add x2, x2, :lo12:.LANCHOR0 - ld1w z0.s, p0/z, [x2] - insr z0.s, w1 - insr z0.s, w0 - ret -*/ - -/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\]\n\tinsr\t\1, w1\n\tinsr\t\1, w0} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_3.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_3.c 2019-06-18 09:35:52.945885794 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_3.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 2.1: Leading constants with stepped sequence. */ @@ -7,21 +8,17 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** index (z[0-9]+\.s), #6, #-1 +** insr \1, w0 +** insr \1, w1 +** rev \1, \1 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b) { return (vnx4si) { 1, 2, 3, 4, 5, 6, a, b }; } -/* -foo: -.LFB0: - .cfi_startproc - index z0.s, #6, #-1 - insr z0.s, w0 - insr z0.s, w1 - rev z0.s, z0.s - ret -*/ - -/* { dg-final { scan-assembler {\tindex\t(z[0-9]+\.s), #6, #-1\n\tinsr\t\1, w0\n\tinsr\t\1, w1\n\trev\t\1, \1} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_4.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_4.c 2019-06-18 09:35:52.949885761 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_4.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 2.2: Leading constants with stepped sequence. */ @@ -7,24 +8,17 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** ... +** ld1w (z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\] +** insr \1, w1 +** insr \1, w0 +** rev \1, \1 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b) { return (vnx4si) { 3, 2, 3, 2, 3, 2, b, a }; } - -/* -foo: -.LFB0: - .cfi_startproc - ptrue p0.s, vl8 - adrp x2, .LANCHOR0 - add x2, x2, :lo12:.LANCHOR0 - ld1w z0.s, p0/z, [x2] - insr z0.s, w1 - insr z0.s, w0 - rev z0.s, z0.s - ret -*/ - -/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\]\n\tinsr\t\1, w1\n\tinsr\t\1, w0\n\trev\t\1, \1} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_5.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_5.c 2019-06-18 09:35:52.949885761 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_5.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 3: Trailing same element. */ @@ -7,20 +8,15 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** mov (z[0-9]+\.s), w2 +** insr \1, w1 +** insr \1, w0 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b, int c) { return (vnx4si) { a, b, c, c, c, c, c, c }; } - -/* -foo: -.LFB0: - .cfi_startproc - mov z0.s, w2 - insr z0.s, w1 - insr z0.s, w0 - ret -*/ - -/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w2\n\tinsr\t\1, w1\n\tinsr\t\1, w0} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_6.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_6.c 2019-06-18 09:35:52.949885761 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_6.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 3: Trailing same element. */ @@ -7,21 +8,16 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** mov (z[0-9]+\.s), w2 +** insr \1, w1 +** insr \1, w0 +** rev \1, \1 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b, int c) { return (vnx4si) { c, c, c, c, c, c, b, a }; } - -/* -foo: -.LFB0: - .cfi_startproc - mov z0.s, w2 - insr z0.s, w1 - insr z0.s, w0 - rev z0.s, z0.s - ret -*/ - -/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w2\n\tinsr\t\1, w1\n\tinsr\t\1, w0\n\trev\t\1, \1} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_7.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_7.c 2019-06-18 09:35:52.949885761 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_7.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 5.1: All elements. */ @@ -7,25 +8,20 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** mov (z[0-9]+\.s), w7 +** insr \1, w6 +** insr \1, w5 +** insr \1, w4 +** insr \1, w3 +** insr \1, w2 +** insr \1, w1 +** insr \1, w0 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b, int c, int d, int e, int f, int g, int h) { return (vnx4si) { a, b, c, d, e, f, g, h }; } - -/* -foo: -.LFB0: - .cfi_startproc - mov z0.s, w7 - insr z0.s, w6 - insr z0.s, w5 - insr z0.s, w4 - insr z0.s, w3 - insr z0.s, w2 - insr z0.s, w1 - insr z0.s, w0 - ret -*/ - -/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w7\n\tinsr\t\1, w6\n\tinsr\t\1, w5\n\tinsr\t\1, w4\n\tinsr\t\1, w3\n\tinsr\t\1, w2\n\tinsr\t\1, w1\n\tinsr\t\1, w0} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_8.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_8.c 2019-06-18 09:35:52.945885794 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_8.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\]\n\tmov\t(z[0-9]+\.s), w3\n\tinsr\t\2, w2\n\tinsr\t\2, w1\n\tinsr\t\2, w0\n\tzip1\t\2, \2, \1} } } */ /* Case 5.2: Interleaved elements and constants. */ @@ -7,26 +8,19 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** ... +** ld1w (z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\] +** mov (z[0-9]+\.s), w3 +** insr \2, w2 +** insr \2, w1 +** insr \2, w0 +** zip1 \2, \2, \1 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b, int c, int d) { return (vnx4si) { a, 1, b, 2, c, 3, d, 4 }; } - -/* -foo: -.LFB0: - .cfi_startproc - ptrue p0.s, vl8 - adrp x4, .LANCHOR0 - add x4, x4, :lo12:.LANCHOR0 - ld1w z1.s, p0/z, [x4] - mov z0.s, w3 - insr z0.s, w2 - insr z0.s, w1 - insr z0.s, w0 - zip1 z0.s, z0.s, z1.s - ret -*/ - -/* { dg-final { scan-assembler {\tld1w\t(z[0-9]+\.s), p[0-9]+/z, \[x[0-9]+\]\n\tmov\t(z[0-9]+\.s), w3\n\tinsr\t\2, w2\n\tinsr\t\2, w1\n\tinsr\t\2, w0\n\tzip1\t\2, \2, \1} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_9.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_9.c 2019-06-18 09:35:52.945885794 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_9.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 5.3: Repeated elements. */ @@ -7,20 +8,15 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** mov (z[0-9]+\.s), w0 +** mov (z[0-9]+\.s), w1 +** zip1 \1, \1, \2 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b) { return (vnx4si) { a, b, a, b, a, b, a, b }; } - -/* -foo: -.LFB0: - .cfi_startproc - mov z0.s, w0 - mov z1.s, w1 - zip1 z0.s, z0.s, z1.s - ret -*/ - -/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w0\n\tmov\t(z[0-9]+\.s), w1\n\tzip1\t\1, \1, \2} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_10.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_10.c 2019-06-18 09:35:52.945885794 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_10.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 5.4: Interleaved repeating elements and non-repeating elements. */ @@ -7,22 +8,17 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** mov (z[0-9]+\.s), w3 +** mov (z[0-9]+\.s), w2 +** insr \2, w1 +** insr \2, w0 +** zip1 \2, \2, \1 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b, int c, int f) { return (vnx4si) { a, f, b, f, c, f, c, f }; } - -/* -foo: -.LFB0: - .cfi_startproc - mov z1.s, w3 - mov z0.s, w2 - insr z0.s, w1 - insr z0.s, w0 - zip1 z0.s, z0.s, z1.s - ret -*/ - -/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w3\n\tmov\t(z[0-9]+\.s), w2\n\tinsr\t\2, w1\n\tinsr\t\2, w0\n\tzip1\t\2, \2, \1} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_11.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_11.c 2019-06-18 09:35:52.949885761 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_11.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 5.5: Interleaved repeating elements and trailing same elements. */ @@ -7,21 +8,16 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** mov (z[0-9]+\.s), w1 +** insr \1, w0 +** mov (z[0-9]+\.s), w2 +** zip1 \1, \1, \2 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b, int f) { return (vnx4si) { a, f, b, f, b, f, b, f }; } - -/* -foo: -.LFB0: - .cfi_startproc - mov z0.s, w1 - insr z0.s, w0 - mov z1.s, w2 - zip1 z0.s, z0.s, z1.s - ret -*/ - -/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w1\n\tinsr\t\1, w0\n\tmov\t(z[0-9]+\.s), w2\n\tzip1\t\1, \1, \2} } } */ Index: gcc/testsuite/gcc.target/aarch64/sve/init_12.c =================================================================== --- gcc/testsuite/gcc.target/aarch64/sve/init_12.c 2019-06-18 09:35:52.949885761 +0100 +++ gcc/testsuite/gcc.target/aarch64/sve/init_12.c 2019-07-16 14:57:25.602820637 +0100 @@ -1,5 +1,6 @@ /* { dg-do assemble { target aarch64_asm_sve_ok } } */ /* { dg-options "-O -msve-vector-bits=256 --save-temps" } */ +/* { dg-final { check-function-bodies "**" "" } } */ /* Case 5.5: Interleaved repeating elements and trailing same elements. */ @@ -7,23 +8,18 @@ typedef int32_t vnx4si __attribute__((vector_size (32))); +/* +** foo: +** mov (z[0-9]+\.s), w2 +** mov (z[0-9]+\.s), w0 +** insr \2, w1 +** insr \2, w1 +** insr \2, w1 +** zip1 \2, \2, \1 +** ... +*/ __attribute__((noipa)) vnx4si foo(int a, int b, int f) { return (vnx4si) { b, f, b, f, b, f, a, f }; } - -/* -foo: -.LFB0: - .cfi_startproc - mov z1.s, w2 - mov z0.s, w0 - insr z0.s, w1 - insr z0.s, w1 - insr z0.s, w1 - zip1 z0.s, z0.s, z1.s - ret -*/ - -/* { dg-final { scan-assembler {\tmov\t(z[0-9]+\.s), w2\n\tmov\t(z[0-9]+\.s), w0\n\tinsr\t\2, w1\n\tinsr\t\2, w1\n\tinsr\t\2, w1\n\tzip1\t\2, \2, \1} } } */