From 67db31ec5a3f570a6a2bbf40f61014c267c42798 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 24 Dec 2020 14:06:30 -0800 Subject: [PATCH] x86: Add tests for IFUNC resolver with CPU_FEATURE_USABLE Add tests for IFUNC resolver using CPU_FEATURE_USABLE with and without lazy binding. --- sysdeps/x86/Makefile | 30 +++++++- sysdeps/x86/tst-ifunc-platform-1-bindnow.c | 1 + sysdeps/x86/tst-ifunc-platform-1-lazy.c | 87 ++++++++++++++++++++++ sysdeps/x86/tst-ifunc-platform-1-static.c | 1 + sysdeps/x86/tst-ifunc-platform-2-bindnow.c | 1 + sysdeps/x86/tst-ifunc-platform-2-lazy.c | 51 +++++++++++++ sysdeps/x86/tst-ifunc-platform-3-bindnow.c | 1 + sysdeps/x86/tst-ifunc-platform-3-lazy.c | 1 + sysdeps/x86/tst-ifunc-platform-mod-2.c | 65 ++++++++++++++++ sysdeps/x86/tst-ifunc-platform-mod-3.c | 71 ++++++++++++++++++ 10 files changed, 307 insertions(+), 2 deletions(-) create mode 100644 sysdeps/x86/tst-ifunc-platform-1-bindnow.c create mode 100644 sysdeps/x86/tst-ifunc-platform-1-lazy.c create mode 100644 sysdeps/x86/tst-ifunc-platform-1-static.c create mode 100644 sysdeps/x86/tst-ifunc-platform-2-bindnow.c create mode 100644 sysdeps/x86/tst-ifunc-platform-2-lazy.c create mode 100644 sysdeps/x86/tst-ifunc-platform-3-bindnow.c create mode 100644 sysdeps/x86/tst-ifunc-platform-3-lazy.c create mode 100644 sysdeps/x86/tst-ifunc-platform-mod-2.c create mode 100644 sysdeps/x86/tst-ifunc-platform-mod-3.c diff --git a/sysdeps/x86/Makefile b/sysdeps/x86/Makefile index 00109ded11..cd752b9bd6 100644 --- a/sysdeps/x86/Makefile +++ b/sysdeps/x86/Makefile @@ -7,8 +7,34 @@ sysdep-dl-routines += dl-get-cpu-features sysdep_headers += bits/platform/x86.h sys/platform/x86.h tests += tst-get-cpu-features tst-get-cpu-features-static \ - tst-cpu-features-cpuinfo tst-cpu-features-supports -tests-static += tst-get-cpu-features-static + tst-cpu-features-cpuinfo tst-cpu-features-supports \ + tst-ifunc-platform-1-bindnow \ + tst-ifunc-platform-1-lazy \ + tst-ifunc-platform-1-static \ + tst-ifunc-platform-2-bindnow \ + tst-ifunc-platform-2-lazy \ + tst-ifunc-platform-3-bindnow \ + tst-ifunc-platform-3-lazy +tests-static += tst-get-cpu-features-static \ + tst-ifunc-platform-1-static + +modules-names += tst-ifunc-platform-mod-2 \ + tst-ifunc-platform-mod-3 + +LDFLAGS-tst-ifunc-platform-1-lazy = -Wl,-z,lazy +LDFLAGS-tst-ifunc-platform-1-bindnow = -Wl,-z,now +tst-ifunc-platform-1-bindnow-ENV = LD_BIND_NOW=1 +LDFLAGS-tst-ifunc-platform-2-lazy = -Wl,-z,lazy +LDFLAGS-tst-ifunc-platform-2-bindnow = -Wl,-z,now +tst-ifunc-platform-2-bindnow-ENV = LD_BIND_NOW=1 +LDFLAGS-tst-ifunc-platform-3-lazy = -Wl,-z,lazy +LDFLAGS-tst-ifunc-platform-3-bindnow = -Wl,-z,now +tst-ifunc-platform-3-bindnow-ENV = LD_BIND_NOW=1 + +$(objpfx)tst-ifunc-platform-2-bindnow: $(objpfx)tst-ifunc-platform-mod-2.so +$(objpfx)tst-ifunc-platform-2-lazy: $(objpfx)tst-ifunc-platform-mod-2.so +$(objpfx)tst-ifunc-platform-3-bindnow: $(objpfx)tst-ifunc-platform-mod-3.so +$(objpfx)tst-ifunc-platform-3-lazy: $(objpfx)tst-ifunc-platform-mod-3.so endif ifeq ($(subdir),math) diff --git a/sysdeps/x86/tst-ifunc-platform-1-bindnow.c b/sysdeps/x86/tst-ifunc-platform-1-bindnow.c new file mode 100644 index 0000000000..f8391048ae --- /dev/null +++ b/sysdeps/x86/tst-ifunc-platform-1-bindnow.c @@ -0,0 +1 @@ +#include "tst-ifunc-platform-1-lazy.c" diff --git a/sysdeps/x86/tst-ifunc-platform-1-lazy.c b/sysdeps/x86/tst-ifunc-platform-1-lazy.c new file mode 100644 index 0000000000..2556c23f3c --- /dev/null +++ b/sysdeps/x86/tst-ifunc-platform-1-lazy.c @@ -0,0 +1,87 @@ +/* Program with local IFUNC resolver and . + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +enum isa +{ + has_none, + has_sse2, + has_avx2, + has_avx512f +}; + +static enum isa +none (void) +{ + return has_none; +} + +static enum isa +sse2 (void) +{ + return has_sse2; +} + +static enum isa +avx2 (void) +{ + return has_avx2; +} + +static enum isa +avx512f (void) +{ + return has_avx512f; +} + +static __typeof__ (avx2) * +resolver (void) +{ + if (CPU_FEATURE_USABLE (AVX512F)) + return avx512f; + else if (CPU_FEATURE_USABLE (AVX2)) + return avx2; + else if (CPU_FEATURE_USABLE (SSE2)) + return sse2; + return none; +} + +static enum isa cpuid (void) __attribute__ ((ifunc ("resolver"))); + +static int +do_test (void) +{ + enum isa has_isa = cpuid (); + TEST_VERIFY_EXIT (!!CPU_FEATURE_USABLE (SSE2) + == !!__builtin_cpu_supports ("sse2")); + TEST_VERIFY_EXIT (!!CPU_FEATURE_USABLE (AVX2) + == !!__builtin_cpu_supports ("avx2")); + TEST_VERIFY_EXIT (!!CPU_FEATURE_USABLE (AVX512F) + == !!__builtin_cpu_supports ("avx512f")); + if (__builtin_cpu_supports ("avx512f")) + TEST_VERIFY_EXIT (has_isa == has_avx512f); + else if (__builtin_cpu_supports ("avx2")) + TEST_VERIFY_EXIT (has_isa == has_avx2); + else if (__builtin_cpu_supports ("sse2")) + TEST_VERIFY_EXIT (has_isa == has_sse2); + return 0; +} + +#include diff --git a/sysdeps/x86/tst-ifunc-platform-1-static.c b/sysdeps/x86/tst-ifunc-platform-1-static.c new file mode 100644 index 0000000000..f8391048ae --- /dev/null +++ b/sysdeps/x86/tst-ifunc-platform-1-static.c @@ -0,0 +1 @@ +#include "tst-ifunc-platform-1-lazy.c" diff --git a/sysdeps/x86/tst-ifunc-platform-2-bindnow.c b/sysdeps/x86/tst-ifunc-platform-2-bindnow.c new file mode 100644 index 0000000000..7c2455c2a0 --- /dev/null +++ b/sysdeps/x86/tst-ifunc-platform-2-bindnow.c @@ -0,0 +1 @@ +#include "tst-ifunc-platform-2-lazy.c" diff --git a/sysdeps/x86/tst-ifunc-platform-2-lazy.c b/sysdeps/x86/tst-ifunc-platform-2-lazy.c new file mode 100644 index 0000000000..db3cc5e123 --- /dev/null +++ b/sysdeps/x86/tst-ifunc-platform-2-lazy.c @@ -0,0 +1,51 @@ +/* Program with local IFUNC resolver and . + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +enum isa +{ + has_none, + has_sse2, + has_avx2, + has_avx512f +}; + +extern enum isa cpuid (void); + +static int +do_test (void) +{ + enum isa has_isa = cpuid (); + TEST_VERIFY_EXIT (!!CPU_FEATURE_USABLE (SSE2) + == !!__builtin_cpu_supports ("sse2")); + TEST_VERIFY_EXIT (!!CPU_FEATURE_USABLE (AVX2) + == !!__builtin_cpu_supports ("avx2")); + TEST_VERIFY_EXIT (!!CPU_FEATURE_USABLE (AVX512F) + == !!__builtin_cpu_supports ("avx512f")); + if (__builtin_cpu_supports ("avx512f")) + TEST_VERIFY_EXIT (has_isa == has_avx512f); + else if (__builtin_cpu_supports ("avx2")) + TEST_VERIFY_EXIT (has_isa == has_avx2); + else if (__builtin_cpu_supports ("sse2")) + TEST_VERIFY_EXIT (has_isa == has_sse2); + return 0; +} + +#include diff --git a/sysdeps/x86/tst-ifunc-platform-3-bindnow.c b/sysdeps/x86/tst-ifunc-platform-3-bindnow.c new file mode 100644 index 0000000000..7c2455c2a0 --- /dev/null +++ b/sysdeps/x86/tst-ifunc-platform-3-bindnow.c @@ -0,0 +1 @@ +#include "tst-ifunc-platform-2-lazy.c" diff --git a/sysdeps/x86/tst-ifunc-platform-3-lazy.c b/sysdeps/x86/tst-ifunc-platform-3-lazy.c new file mode 100644 index 0000000000..7c2455c2a0 --- /dev/null +++ b/sysdeps/x86/tst-ifunc-platform-3-lazy.c @@ -0,0 +1 @@ +#include "tst-ifunc-platform-2-lazy.c" diff --git a/sysdeps/x86/tst-ifunc-platform-mod-2.c b/sysdeps/x86/tst-ifunc-platform-mod-2.c new file mode 100644 index 0000000000..c302277be4 --- /dev/null +++ b/sysdeps/x86/tst-ifunc-platform-mod-2.c @@ -0,0 +1,65 @@ +/* Shared object with local IFUNC resolver and . + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +enum isa +{ + has_none, + has_sse2, + has_avx2, + has_avx512f +}; + +static enum isa +none (void) +{ + return has_none; +} + +static enum isa +sse2 (void) +{ + return has_sse2; +} + +static enum isa +avx2 (void) +{ + return has_avx2; +} + +static enum isa +avx512f (void) +{ + return has_avx512f; +} + +static __typeof__ (avx2) * +resolver (void) +{ + if (CPU_FEATURE_USABLE (AVX512F)) + return avx512f; + else if (CPU_FEATURE_USABLE (AVX2)) + return avx2; + else if (CPU_FEATURE_USABLE (SSE2)) + return sse2; + return none; +} + +enum isa cpuid (void) __attribute__ ((ifunc ("resolver"))); diff --git a/sysdeps/x86/tst-ifunc-platform-mod-3.c b/sysdeps/x86/tst-ifunc-platform-mod-3.c new file mode 100644 index 0000000000..1002c444ab --- /dev/null +++ b/sysdeps/x86/tst-ifunc-platform-mod-3.c @@ -0,0 +1,71 @@ +/* Shared object with local IFUNC resolver and . + Copyright (C) 2020 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +enum isa +{ + has_none, + has_sse2, + has_avx2, + has_avx512f +}; + +static enum isa +none (void) +{ + return has_none; +} + +static enum isa +sse2 (void) +{ + return has_sse2; +} + +static enum isa +avx2 (void) +{ + return has_avx2; +} + +static enum isa +avx512f (void) +{ + return has_avx512f; +} + +static __typeof__ (avx2) * +resolver (void) +{ + if (CPU_FEATURE_USABLE (AVX512F)) + return avx512f; + else if (CPU_FEATURE_USABLE (AVX2)) + return avx2; + else if (CPU_FEATURE_USABLE (SSE2)) + return sse2; + return none; +} + +static enum isa cpuid_local (void) __attribute__ ((ifunc ("resolver"))); + +enum isa +cpuid (void) +{ + return cpuid_local (); +} -- 2.29.2