claudiu.zissulescu-iancule...@oracle.com writes: > diff --git a/gcc/testsuite/gcc.target/aarch64/memtag/basic-1.c > b/gcc/testsuite/gcc.target/aarch64/memtag/basic-1.c > new file mode 100644 > index 00000000000..70b790c6c3e > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/memtag/basic-1.c > @@ -0,0 +1,15 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-O2" } */ > +/* FIXME - scan-assembler-times-not subg ? */ > +/* FIXME - generate stgp instead of stg + str ? */
Were you planning to address these in this series, or are they TODOs for future work? Similarly for the other FIXMEs. > + > +int use (int *x); > + > +void foo (int n) > +{ > + int x = 99; > + use (&x); > +} > + > +/* { dg-final { scan-assembler-times {\tirg\t} 1 } } */ > +/* { dg-final { scan-assembler-times {\tstg\t} 2 } } */ > diff --git a/gcc/testsuite/gcc.target/aarch64/memtag/basic-3.c > b/gcc/testsuite/gcc.target/aarch64/memtag/basic-3.c > new file mode 100644 > index 00000000000..2838c934a62 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/memtag/basic-3.c > @@ -0,0 +1,21 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-O2" } */ > + > +int use (int *x); > + > +void foo (int n) > +{ > + int a, b, c; > + use (&a); > + use (&b); > + use (&c); > +} > + > +/* 3 stack vars need 48 bytes. Expected: 3 stg to tag, 1 st2g + 1 stg to > + untag. */ > + > +/* { dg-final { scan-assembler-times {\tirg\t} 1 } } */ > +/* { dg-final { scan-assembler-times {stg\t...?, \[sp, 48\]\n} 1 } } */ > +/* { dg-final { scan-assembler-times {st2g\t...?, \[sp, 32\]\n} 1 } } */ > +/* { dg-final { scan-assembler-times {stg\t...?, \[sp, 32\]\n} 1 } } */ > +/* { dg-final { scan-assembler-times {stg\t...?, \[sp, 64\]\n} 2 } } */ I'm not sure this makes it sufficiently clear what bytes [16, 31] are being used for. > [...] > diff --git a/gcc/testsuite/gcc.target/aarch64/memtag/large-array.c > b/gcc/testsuite/gcc.target/aarch64/memtag/large-array.c > new file mode 100644 > index 00000000000..f233ce04d35 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/memtag/large-array.c > @@ -0,0 +1,24 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-O2" } */ > +/* FIXME - add other checks later. For now make sure this does not ICE. */ It looks from the dg-finals below that the test already does more than that. > + > +#define ARRAY_LEN 12000 > + > +int create (void); > + > +void sort (int *data, int n); > + > +void sort_array (void) > +{ > + int data[ARRAY_LEN], i; > + > + for (i=0; i < ARRAY_LEN; ++i) > + { > + data[i] = create (); > + } > + > + sort (data, ARRAY_LEN); > +} > + > +/* { dg-final { scan-assembler-times {\tirg\t} 1 } } */ > +/* { dg-final { scan-assembler-times {st2g\t...?, \[...?\], 32\n} 2 } } */ > diff --git a/gcc/testsuite/gcc.target/aarch64/memtag/local-no-escape.c > b/gcc/testsuite/gcc.target/aarch64/memtag/local-no-escape.c > new file mode 100644 > index 00000000000..173fe1135bf > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/memtag/local-no-escape.c > @@ -0,0 +1,20 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-O0" } */ > + > +/* FIXME - If x doesnt escape the function, why should MTE tagging be done > for > + x ? */ Do we? I would have expected x to be optimised away by gimple. Does that not happen? It's not really clear to me what this is testing. Is it an anti-ICE test? (No need to change it, just curious.) > + > +extern int use (int *x); > +extern int bar (int *x); > +extern int baz (int *x); > + > +int a[10]; > + > +int foo (int n) > +{ > + int x = use (a); > + if (x) > + return bar (a); > + else > + return baz (a); > +} > diff --git a/gcc/testsuite/gcc.target/aarch64/memtag/memtag.exp > b/gcc/testsuite/gcc.target/aarch64/memtag/memtag.exp > new file mode 100644 > index 00000000000..ba32f43d846 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/memtag/memtag.exp > @@ -0,0 +1,64 @@ > +# Copyright (C) 2024 Free Software Foundation, Inc. > + > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 3 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > +# GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with GCC; see the file COPYING3. If not see > +# <http://www.gnu.org/licenses/>. > + > +# GCC testsuite that uses the `dg.exp' driver. > + > +# Load support procs. > +load_lib gcc-dg.exp > + > +# Return 1 if target can compile and run binary for stack > +# sanitization, 0 otherwise. > + > +proc check_effective_target_memtag_exec {} { > + if ![check_runtime memtag_exec { > + #ifdef __cplusplus > + extern "C" { > + #endif > + extern int prctl(int, unsigned long, unsigned long, unsigned long, > unsigned long); > + #ifdef __cplusplus > + } > + #endif > + int main (void) { > + #define PR_SET_TAGGED_ADDR_CTRL 55 > + #define PR_GET_TAGGED_ADDR_CTRL 56 > + #define PR_TAGGED_ADDR_ENABLE (1UL << 0) > + #define PR_MTE_TCF_SYNC (1UL << 1) > + #define PR_MTE_TAG_SHIFT 3 > + if (prctl (PR_GET_TAGGED_ADDR_CTRL, 0,0,0,0) == -1) > + return -1; > + if (prctl (PR_SET_TAGGED_ADDR_CTRL, > + PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC > + | (0xfffe << PR_MTE_TAG_SHIFT), 0, 0, 0) == -1 > + || !prctl (PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)) > + return 1; > + return 0; > + } > + }] { > + return 0; > + } > + return 1; > +} I might have said this before, but this seems like it should go in target-supports.exp. > +# Initialize `dg'. > +dg-init > + > +# Main loop. > +if [check_effective_target_aarch64_mte] { > + dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cCS\]]] \ > + "" "-fsanitize=memtag-stack -march=armv8.5-a+memtag" > +} > + > +# All done. > +dg-finish > diff --git a/gcc/testsuite/gcc.target/aarch64/memtag/mte-sig.h > b/gcc/testsuite/gcc.target/aarch64/memtag/mte-sig.h > new file mode 100644 > index 00000000000..efb3c6d187c > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/memtag/mte-sig.h > @@ -0,0 +1,15 @@ > +#include <stdlib.h> > +#include <signal.h> > +#include <string.h> > + > +void handler (int nSig) > +{ > + /* We hit the exception. Return error. */ > + exit (1); > +} > + > + > +static void setHandler (void) > +{ > + signal (SIGSEGV, handler); > +} > diff --git a/gcc/testsuite/gcc.target/aarch64/memtag/no-sanitize-attribute.c > b/gcc/testsuite/gcc.target/aarch64/memtag/no-sanitize-attribute.c > new file mode 100644 > index 00000000000..0d40063dc08 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/memtag/no-sanitize-attribute.c > @@ -0,0 +1,17 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-O2" } */ > + > +int use (int *x); > + > +__attribute__((no_sanitize("memtag-stack"))) > +void foo (int n) > +{ > + int x = 99; > + use (&x); > +} > + > +/* { dg-final { scan-assembler-not "irg" } } */ > +/* { dg-final { scan-assembler-not "stg" } } */ > +/* { dg-final { scan-assembler-not "st2g" } } */ > +/* { dg-final { scan-assembler-not "subg" } } */ > +/* { dg-final { scan-assembler-not "addg" } } */ It's probably worth adding \t to the beginning of each string, so that we don't accidentally match fragments of filenames. > diff --git a/gcc/testsuite/gcc.target/aarch64/memtag/texec-1.c > b/gcc/testsuite/gcc.target/aarch64/memtag/texec-1.c > new file mode 100644 > index 00000000000..b63619b04d3 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/memtag/texec-1.c > @@ -0,0 +1,27 @@ > +/* { dg-do run { xfail *-*-* } } */ Why are all but one of the run tests XFAILed? > +/* { dg-require-effective-target memtag_exec } */ > +/* { dg-additional-options "-O2" } */ > + > +#include "mte-sig.h" > + > +void __attribute__((noinline)) > +use (volatile unsigned char *ptr) > +{ > + ptr[0] = 0x41; > + ptr[1] = 0x42; > +} > + > +int main(void) > +{ > + volatile unsigned char array[15]; > + volatile unsigned char *ptr = &array[0]; > + > + setHandler(); > + use (ptr); > + > + /* Write to memory beyond the 16 byte granule (offsest 0x10) MTE should > + generate an exception If the offset is less than 0x10 no SIGSEGV will > + occur. */ > + ptr[0x10] = 0x55; > + return 0; > +} > [...] > diff --git a/gcc/testsuite/gcc.target/aarch64/memtag/vararray-gimple.c > b/gcc/testsuite/gcc.target/aarch64/memtag/vararray-gimple.c > new file mode 100644 > index 00000000000..c960048d670 > --- /dev/null > +++ b/gcc/testsuite/gcc.target/aarch64/memtag/vararray-gimple.c > @@ -0,0 +1,17 @@ > +/* { dg-do compile } */ > +/* { dg-additional-options "-fdump-tree-asan -O2" } */ > +/* { dg-skip-if "" { *-*-* } { "-O0" } { "" } } */ The last line shouldn't be necessary, since AFAICT each test is only run once, with -O2 in this case. Otherwise it looks good, thanks. Richard > + > +extern int *use (int *b, int n); > + > +int *foo (int n) > +{ > + int b[n]; > + return use (b, n); > +} > + > +/* HWASAN_ALLOCA_POISON is used for alloca and VLAs when MEMTAG is in effect. > + Although HWASAN_ALLOCA_UNPOISON is (also) used for untagging frame, it > + doesnt hurt to check it in context of the current test. */ > +/* { dg-final { scan-tree-dump "HWASAN_ALLOCA_POISON" "asan1" } } */ > +/* { dg-final { scan-tree-dump "HWASAN_ALLOCA_UNPOISON" "asan1" } } */