Add dg test for matching function bodies
diff mbox series

Message ID mpt4l3m848u.fsf@arm.com
State New
Headers show
Series
  • Add dg test for matching function bodies
Related show

Commit Message

Richard Sandiford July 16, 2019, 2:04 p.m. UTC
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  <richard.sandiford@arm.com>

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.

Comments

Jeff Law July 21, 2019, 8:06 p.m. UTC | #1
On 7/16/19 8:04 AM, Richard Sandiford wrote:
> 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  <richard.sandiford@arm.com>
> 
> 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.
OK
jeff

Patch
diff mbox series

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} } } */