[08/22] aarch64: Add __builtin_aarch64_gcs* tests

Message ID 20241023110528.487830-9-yury.khrustalev@arm.com
State New
Headers
Series aarch64: Add support for Guarded Control Stack extension |

Commit Message

Yury Khrustalev Oct. 23, 2024, 11:05 a.m. UTC
  From: Szabolcs Nagy <szabolcs.nagy@arm.com>

gcc/testsuite/ChangeLog:

	* gcc.target/aarch64/gcspopm-1.c: New test.
	* gcc.target/aarch64/gcspr-1.c: New test.
	* gcc.target/aarch64/gcsss-1.c: New test.
---
 gcc/testsuite/gcc.target/aarch64/gcspopm-1.c | 69 ++++++++++++++++++++
 gcc/testsuite/gcc.target/aarch64/gcspr-1.c   | 31 +++++++++
 gcc/testsuite/gcc.target/aarch64/gcsss-1.c   | 49 ++++++++++++++
 3 files changed, 149 insertions(+)
 create mode 100644 gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/gcspr-1.c
 create mode 100644 gcc/testsuite/gcc.target/aarch64/gcsss-1.c
  

Comments

Richard Sandiford Oct. 24, 2024, 2:56 p.m. UTC | #1
Yury Khrustalev <yury.khrustalev@arm.com> writes:
> From: Szabolcs Nagy <szabolcs.nagy@arm.com>
>
> gcc/testsuite/ChangeLog:
>
> 	* gcc.target/aarch64/gcspopm-1.c: New test.
> 	* gcc.target/aarch64/gcspr-1.c: New test.
> 	* gcc.target/aarch64/gcsss-1.c: New test.
> ---
>  gcc/testsuite/gcc.target/aarch64/gcspopm-1.c | 69 ++++++++++++++++++++
>  gcc/testsuite/gcc.target/aarch64/gcspr-1.c   | 31 +++++++++
>  gcc/testsuite/gcc.target/aarch64/gcsss-1.c   | 49 ++++++++++++++
>  3 files changed, 149 insertions(+)
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/gcspr-1.c
>  create mode 100644 gcc/testsuite/gcc.target/aarch64/gcsss-1.c
>
> diff --git a/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c b/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
> new file mode 100644
> index 00000000000..6e6add39cf7
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
> @@ -0,0 +1,69 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mbranch-protection=none" } */
> +/* { dg-final { check-function-bodies "**" "" "" } } */
> +
> +/*
> +**foo1:
> +**	sysl	xzr, #3, c7, c7, #1 // gcspopm
> +**	ret
> +*/
> +void
> +foo1 (void)
> +{
> +  __builtin_aarch64_gcspopm ();
> +}
> +
> +/*
> +**foo2:
> +**	mov	x0, 0
> +**	sysl	x0, #3, c7, c7, #1 // gcspopm
> +**	ret
> +*/
> +unsigned long long
> +foo2 (void)
> +{
> +  return __builtin_aarch64_gcspopm ();
> +}
> +
> +/*
> +**foo3:
> +**	mov	x16, 1
> +** (
> +**	mov	x0, 0
> +**	hint	40 // chkfeat x16
> +** |
> +**	hint	40 // chkfeat x16
> +**	mov	x0, 0
> +** )

The mov could also happen first, before the mov x16, 1.  It would
probably be easier to use...

> +**	cbz	x16, .*
> +**	ret
> +**	mov	x0, 0
> +**	sysl	x0, #3, c7, c7, #1 // gcspopm
> +**	ret
> +*/
> +unsigned long long
> +foo3 (void)
> +{
> +  if (__builtin_aarch64_chkfeat (1) == 0)
> +    return __builtin_aarch64_gcspopm ();
> +  return 0;
> +}

unsigned long long
foo3 (unsigned long long x)
{
  if (__builtin_aarch64_chkfeat (1) == 0)
    return __builtin_aarch64_gcspopm ();
  return x;
}

so that x0 is returned unmodified if the chkfeat returns nonzero.

FWIW, if we do remove the embedded moves from the .md define_insns,
we should also be able to get rid of the redundant zeroing of x0
on the gcspopm path.

> +
> +/*
> +**foo4:
> +**	sysl	xzr, #3, c7, c7, #1 // gcspopm
> +**	mov	x0, 0
> +**	sysl	x0, #3, c7, c7, #1 // gcspopm
> +**	sysl	xzr, #3, c7, c7, #1 // gcspopm
> +**	ret
> +*/
> +unsigned long long
> +foo4 (void)
> +{
> +  unsigned long long a = __builtin_aarch64_gcspopm ();
> +  unsigned long long b = __builtin_aarch64_gcspopm ();
> +  unsigned long long c = __builtin_aarch64_gcspopm ();
> +  (void) a;
> +  (void) c;
> +  return b;
> +}

Nice test :)

> diff --git a/gcc/testsuite/gcc.target/aarch64/gcspr-1.c b/gcc/testsuite/gcc.target/aarch64/gcspr-1.c
> new file mode 100644
> index 00000000000..0e651979551
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/gcspr-1.c
> @@ -0,0 +1,31 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mbranch-protection=none" } */
> +/* { dg-final { check-function-bodies "**" "" "" } } */
> +
> +/*
> +**foo1:
> +**	mrs	x0, s3_3_c2_c5_1 // gcspr_el0
> +**	ret
> +*/
> +void *
> +foo1 (void)
> +{
> +  return __builtin_aarch64_gcspr ();
> +}
> +
> +/*
> +**foo2:
> +**	mrs	x[0-9]*, s3_3_c2_c5_1 // gcspr_el0
> +**	sysl	xzr, #3, c7, c7, #1 // gcspopm
> +**	mrs	x[0-9]*, s3_3_c2_c5_1 // gcspr_el0
> +**	sub	x0, x[0-9]*, x[0-9]*
> +**	ret
> +*/
> +long
> +foo2 (void)
> +{
> +  const char *p = __builtin_aarch64_gcspr ();
> +  __builtin_aarch64_gcspopm ();
> +  const char *q = __builtin_aarch64_gcspr ();
> +  return p - q;
> +}
> diff --git a/gcc/testsuite/gcc.target/aarch64/gcsss-1.c b/gcc/testsuite/gcc.target/aarch64/gcsss-1.c
> new file mode 100644
> index 00000000000..025c7fee647
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/aarch64/gcsss-1.c
> @@ -0,0 +1,49 @@
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -mbranch-protection=none" } */
> +/* { dg-final { check-function-bodies "**" "" "" } } */
> +
> +/*
> +**foo1:
> +**	sys	#3, c7, c7, #2, x0 // gcsss1
> +**	mov	x[0-9]*, 0
> +**	sysl	x[0-9]*, #3, c7, c7, #3 // gcsss2

Might as well make this:

**	mov	(x[0-9]+), 0
**	sysl	\1, #3, c7, c7, #3 // gcsss2


> +**	ret
> +*/
> +void
> +foo1 (void *p)
> +{
> +  __builtin_aarch64_gcsss (p);
> +}
> +
> +/*
> +**foo2:
> +**	sys	#3, c7, c7, #2, x0 // gcsss1
> +**	mov	x0, 0
> +**	sysl	x0, #3, c7, c7, #3 // gcsss2
> +**	ret
> +*/
> +void *
> +foo2 (void *p)
> +{
> +  return __builtin_aarch64_gcsss (p);
> +}
> +
> +/*
> +**foo3:
> +**	mov	x16, 1
> +**	hint	40 // chkfeat x16
> +**	cbnz	x16, .*
> +**	sys	#3, c7, c7, #2, x0 // gcsss1
> +**	mov	x0, 0
> +**	sysl	x0, #3, c7, c7, #3 // gcsss2
> +**	ret
> +**	mov	x0, 0
> +**	ret
> +*/
> +void *
> +foo3 (void *p)
> +{
> +  if (__builtin_aarch64_chkfeat (1) == 0)
> +    return __builtin_aarch64_gcsss (p);
> +  return 0;
> +}

Similarly to the above, it would probably be good to return p instead
of 0 here, to avoid awkwardness with the positioning of the return 0 path.

Thanks,
Richard
  

Patch

diff --git a/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c b/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
new file mode 100644
index 00000000000..6e6add39cf7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/gcspopm-1.c
@@ -0,0 +1,69 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=none" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+**foo1:
+**	sysl	xzr, #3, c7, c7, #1 // gcspopm
+**	ret
+*/
+void
+foo1 (void)
+{
+  __builtin_aarch64_gcspopm ();
+}
+
+/*
+**foo2:
+**	mov	x0, 0
+**	sysl	x0, #3, c7, c7, #1 // gcspopm
+**	ret
+*/
+unsigned long long
+foo2 (void)
+{
+  return __builtin_aarch64_gcspopm ();
+}
+
+/*
+**foo3:
+**	mov	x16, 1
+** (
+**	mov	x0, 0
+**	hint	40 // chkfeat x16
+** |
+**	hint	40 // chkfeat x16
+**	mov	x0, 0
+** )
+**	cbz	x16, .*
+**	ret
+**	mov	x0, 0
+**	sysl	x0, #3, c7, c7, #1 // gcspopm
+**	ret
+*/
+unsigned long long
+foo3 (void)
+{
+  if (__builtin_aarch64_chkfeat (1) == 0)
+    return __builtin_aarch64_gcspopm ();
+  return 0;
+}
+
+/*
+**foo4:
+**	sysl	xzr, #3, c7, c7, #1 // gcspopm
+**	mov	x0, 0
+**	sysl	x0, #3, c7, c7, #1 // gcspopm
+**	sysl	xzr, #3, c7, c7, #1 // gcspopm
+**	ret
+*/
+unsigned long long
+foo4 (void)
+{
+  unsigned long long a = __builtin_aarch64_gcspopm ();
+  unsigned long long b = __builtin_aarch64_gcspopm ();
+  unsigned long long c = __builtin_aarch64_gcspopm ();
+  (void) a;
+  (void) c;
+  return b;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/gcspr-1.c b/gcc/testsuite/gcc.target/aarch64/gcspr-1.c
new file mode 100644
index 00000000000..0e651979551
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/gcspr-1.c
@@ -0,0 +1,31 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=none" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+**foo1:
+**	mrs	x0, s3_3_c2_c5_1 // gcspr_el0
+**	ret
+*/
+void *
+foo1 (void)
+{
+  return __builtin_aarch64_gcspr ();
+}
+
+/*
+**foo2:
+**	mrs	x[0-9]*, s3_3_c2_c5_1 // gcspr_el0
+**	sysl	xzr, #3, c7, c7, #1 // gcspopm
+**	mrs	x[0-9]*, s3_3_c2_c5_1 // gcspr_el0
+**	sub	x0, x[0-9]*, x[0-9]*
+**	ret
+*/
+long
+foo2 (void)
+{
+  const char *p = __builtin_aarch64_gcspr ();
+  __builtin_aarch64_gcspopm ();
+  const char *q = __builtin_aarch64_gcspr ();
+  return p - q;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/gcsss-1.c b/gcc/testsuite/gcc.target/aarch64/gcsss-1.c
new file mode 100644
index 00000000000..025c7fee647
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/gcsss-1.c
@@ -0,0 +1,49 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -mbranch-protection=none" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+/*
+**foo1:
+**	sys	#3, c7, c7, #2, x0 // gcsss1
+**	mov	x[0-9]*, 0
+**	sysl	x[0-9]*, #3, c7, c7, #3 // gcsss2
+**	ret
+*/
+void
+foo1 (void *p)
+{
+  __builtin_aarch64_gcsss (p);
+}
+
+/*
+**foo2:
+**	sys	#3, c7, c7, #2, x0 // gcsss1
+**	mov	x0, 0
+**	sysl	x0, #3, c7, c7, #3 // gcsss2
+**	ret
+*/
+void *
+foo2 (void *p)
+{
+  return __builtin_aarch64_gcsss (p);
+}
+
+/*
+**foo3:
+**	mov	x16, 1
+**	hint	40 // chkfeat x16
+**	cbnz	x16, .*
+**	sys	#3, c7, c7, #2, x0 // gcsss1
+**	mov	x0, 0
+**	sysl	x0, #3, c7, c7, #3 // gcsss2
+**	ret
+**	mov	x0, 0
+**	ret
+*/
+void *
+foo3 (void *p)
+{
+  if (__builtin_aarch64_chkfeat (1) == 0)
+    return __builtin_aarch64_gcsss (p);
+  return 0;
+}