Message ID | 20201109185734.547879-1-hjl.tools@gmail.com |
---|---|
State | New |
Headers | show |
Series | x86: Add -mneeded for GNU_PROPERTY_X86_ISA_1_V[234] marker | expand |
On 11/9/20 11:57 AM, H.J. Lu via Gcc-patches wrote: > GCC 11 supports -march=x86-64-v[234] to enable x86 micro-architecture ISA > levels: > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97250 > > Binutils has been updated to support GNU_PROPERTY_X86_ISA_1_V[234] marker: > > https://gitlab.com/x86-psABIs/x86-64-ABI/-/merge_requests/13 > > with > > commit b0ab06937385e0ae25cebf1991787d64f439bf12 > Author: H.J. Lu <hjl.tools@gmail.com> > Date: Fri Oct 30 06:49:57 2020 -0700 > > x86: Support GNU_PROPERTY_X86_ISA_1_BASELINE marker > > and > > commit 32930e4edbc06bc6f10c435dbcc63131715df678 > Author: H.J. Lu <hjl.tools@gmail.com> > Date: Fri Oct 9 05:05:57 2020 -0700 > > x86: Support GNU_PROPERTY_X86_ISA_1_V[234] marker > > in x86 ELF binaries. > > Add -mneeded to emit GNU_PROPERTY_X86_ISA_1_NEEDED property to indicate > the micro-architecture ISA level required to execute the binary. > > gcc/ > > * config.gcc: Replace cet.o with gnu-property.o. Replace > i386/t-cet with i386/t-gnu-property. > * config/i386/cet.c: Renamed to ... > * config/i386/gnu-property.c: This. > (emit_gnu_property): New function. > (file_end_indicate_exec_stack_and_cet): Renamed to ... > (file_end_indicate_exec_stack_and_gnu_property): This. Call > emit_gnu_property to generate GNU_PROPERTY_X86_FEATURE_1_AND and > GNU_PROPERTY_X86_ISA_1_NEEDED properties. > * config/i386/i386.opt (mneeded): New. > * config/i386/linux-common.h (file_end_indicate_exec_stack_and_cet): > Renamed to ... > (file_end_indicate_exec_stack_and_gnu_property): This. > (TARGET_ASM_FILE_END): Updated. > * config/i386/t-cet: Renamed to ... > * config/i386/t-gnu-property: This. > (cet.o): Renamed to ... > (gnu-property.o): This. > * doc/invoke.texi: Document -mneeded. > > gcc/testsuite/ > > * gcc.target/i386/x86-needed-1.c: New test. > * gcc.target/i386/x86-needed-2.c: Likewise. > * gcc.target/i386/x86-needed-3.c: Likewise. Would it make sense to have -mneeded on by default if we detect a suitable assembler? The goal being that on the distro level we'd have the appropriate markup for everything in the distro without having to worry about injecting the -mneeded flag into every build. Jeff
On Mon, Nov 16, 2020 at 4:58 PM Jeff Law <law@redhat.com> wrote: > > > On 11/9/20 11:57 AM, H.J. Lu via Gcc-patches wrote: > > GCC 11 supports -march=x86-64-v[234] to enable x86 micro-architecture ISA > > levels: > > > > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97250 > > > > Binutils has been updated to support GNU_PROPERTY_X86_ISA_1_V[234] marker: > > > > https://gitlab.com/x86-psABIs/x86-64-ABI/-/merge_requests/13 > > > > with > > > > commit b0ab06937385e0ae25cebf1991787d64f439bf12 > > Author: H.J. Lu <hjl.tools@gmail.com> > > Date: Fri Oct 30 06:49:57 2020 -0700 > > > > x86: Support GNU_PROPERTY_X86_ISA_1_BASELINE marker > > > > and > > > > commit 32930e4edbc06bc6f10c435dbcc63131715df678 > > Author: H.J. Lu <hjl.tools@gmail.com> > > Date: Fri Oct 9 05:05:57 2020 -0700 > > > > x86: Support GNU_PROPERTY_X86_ISA_1_V[234] marker > > > > in x86 ELF binaries. > > > > Add -mneeded to emit GNU_PROPERTY_X86_ISA_1_NEEDED property to indicate > > the micro-architecture ISA level required to execute the binary. > > > > gcc/ > > > > * config.gcc: Replace cet.o with gnu-property.o. Replace > > i386/t-cet with i386/t-gnu-property. > > * config/i386/cet.c: Renamed to ... > > * config/i386/gnu-property.c: This. > > (emit_gnu_property): New function. > > (file_end_indicate_exec_stack_and_cet): Renamed to ... > > (file_end_indicate_exec_stack_and_gnu_property): This. Call > > emit_gnu_property to generate GNU_PROPERTY_X86_FEATURE_1_AND and > > GNU_PROPERTY_X86_ISA_1_NEEDED properties. > > * config/i386/i386.opt (mneeded): New. > > * config/i386/linux-common.h (file_end_indicate_exec_stack_and_cet): > > Renamed to ... > > (file_end_indicate_exec_stack_and_gnu_property): This. > > (TARGET_ASM_FILE_END): Updated. > > * config/i386/t-cet: Renamed to ... > > * config/i386/t-gnu-property: This. > > (cet.o): Renamed to ... > > (gnu-property.o): This. > > * doc/invoke.texi: Document -mneeded. > > > > gcc/testsuite/ > > > > * gcc.target/i386/x86-needed-1.c: New test. > > * gcc.target/i386/x86-needed-2.c: Likewise. > > * gcc.target/i386/x86-needed-3.c: Likewise. > > Would it make sense to have -mneeded on by default if we detect a > suitable assembler? The goal being that on the distro level we'd have > the appropriate markup for everything in the distro without having to > worry about injecting the -mneeded flag into every build. It is OK to set the file level USED ISA bits. But the file level NEEDED ISA bits should be set by developers. Otherwise, function multiversioning with AVX512 will lead to output marked with ISA v4 needed which isn't true.
On 11/16/20 6:44 PM, H.J. Lu wrote: > On Mon, Nov 16, 2020 at 4:58 PM Jeff Law <law@redhat.com> wrote: >> >> On 11/9/20 11:57 AM, H.J. Lu via Gcc-patches wrote: >>> GCC 11 supports -march=x86-64-v[234] to enable x86 micro-architecture ISA >>> levels: >>> >>> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97250 >>> >>> Binutils has been updated to support GNU_PROPERTY_X86_ISA_1_V[234] marker: >>> >>> https://gitlab.com/x86-psABIs/x86-64-ABI/-/merge_requests/13 >>> >>> with >>> >>> commit b0ab06937385e0ae25cebf1991787d64f439bf12 >>> Author: H.J. Lu <hjl.tools@gmail.com> >>> Date: Fri Oct 30 06:49:57 2020 -0700 >>> >>> x86: Support GNU_PROPERTY_X86_ISA_1_BASELINE marker >>> >>> and >>> >>> commit 32930e4edbc06bc6f10c435dbcc63131715df678 >>> Author: H.J. Lu <hjl.tools@gmail.com> >>> Date: Fri Oct 9 05:05:57 2020 -0700 >>> >>> x86: Support GNU_PROPERTY_X86_ISA_1_V[234] marker >>> >>> in x86 ELF binaries. >>> >>> Add -mneeded to emit GNU_PROPERTY_X86_ISA_1_NEEDED property to indicate >>> the micro-architecture ISA level required to execute the binary. >>> >>> gcc/ >>> >>> * config.gcc: Replace cet.o with gnu-property.o. Replace >>> i386/t-cet with i386/t-gnu-property. >>> * config/i386/cet.c: Renamed to ... >>> * config/i386/gnu-property.c: This. >>> (emit_gnu_property): New function. >>> (file_end_indicate_exec_stack_and_cet): Renamed to ... >>> (file_end_indicate_exec_stack_and_gnu_property): This. Call >>> emit_gnu_property to generate GNU_PROPERTY_X86_FEATURE_1_AND and >>> GNU_PROPERTY_X86_ISA_1_NEEDED properties. >>> * config/i386/i386.opt (mneeded): New. >>> * config/i386/linux-common.h (file_end_indicate_exec_stack_and_cet): >>> Renamed to ... >>> (file_end_indicate_exec_stack_and_gnu_property): This. >>> (TARGET_ASM_FILE_END): Updated. >>> * config/i386/t-cet: Renamed to ... >>> * config/i386/t-gnu-property: This. >>> (cet.o): Renamed to ... >>> (gnu-property.o): This. >>> * doc/invoke.texi: Document -mneeded. >>> >>> gcc/testsuite/ >>> >>> * gcc.target/i386/x86-needed-1.c: New test. >>> * gcc.target/i386/x86-needed-2.c: Likewise. >>> * gcc.target/i386/x86-needed-3.c: Likewise. >> Would it make sense to have -mneeded on by default if we detect a >> suitable assembler? The goal being that on the distro level we'd have >> the appropriate markup for everything in the distro without having to >> worry about injecting the -mneeded flag into every build. > It is OK to set the file level USED ISA bits. But the file level NEEDED > ISA bits should be set by developers. Otherwise, function multiversioning > with AVX512 will lead to output marked with ISA v4 needed which isn't > true. True. Function multi-versioning does turn a lot of traditional thinking in this space on its side. OK for the trunk. jeff
diff --git a/gcc/config.gcc b/gcc/config.gcc index dc6d68bd4eb..9bbc4274f86 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -5226,8 +5226,8 @@ case ${target} in i[34567]86-*-darwin* | x86_64-*-darwin*) ;; i[34567]86-*-linux* | x86_64-*-linux*) - extra_objs="${extra_objs} cet.o" - tmake_file="$tmake_file i386/t-linux i386/t-cet" + extra_objs="${extra_objs} gnu-property.o" + tmake_file="$tmake_file i386/t-linux i386/t-gnu-property" ;; i[34567]86-*-kfreebsd*-gnu | x86_64-*-kfreebsd*-gnu) tmake_file="$tmake_file i386/t-kfreebsd" diff --git a/gcc/config/i386/cet.c b/gcc/config/i386/cet.c deleted file mode 100644 index 5450ac307d5..00000000000 --- a/gcc/config/i386/cet.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Functions for CET/x86. - Copyright (C) 2017-2020 Free Software Foundation, Inc. - -This file is part of GCC. - -GCC 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, or (at your option) -any later version. - -GCC 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/>. */ - -#include "config.h" -#include "system.h" -#include "coretypes.h" -#include "tm.h" -#include "output.h" -#include "linux-common.h" - -void -file_end_indicate_exec_stack_and_cet (void) -{ - file_end_indicate_exec_stack (); - - if (flag_cf_protection == CF_NONE) - return; - - unsigned int feature_1 = 0; - - if (flag_cf_protection & CF_BRANCH) - /* GNU_PROPERTY_X86_FEATURE_1_IBT. */ - feature_1 |= 0x1; - - if (flag_cf_protection & CF_RETURN) - /* GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ - feature_1 |= 0x2; - - if (feature_1) - { - int p2align = ptr_mode == SImode ? 2 : 3; - - /* Generate GNU_PROPERTY_X86_FEATURE_1_XXX. */ - switch_to_section (get_section (".note.gnu.property", - SECTION_NOTYPE, NULL)); - - ASM_OUTPUT_ALIGN (asm_out_file, p2align); - /* name length. */ - fprintf (asm_out_file, ASM_LONG " 1f - 0f\n"); - /* data length. */ - fprintf (asm_out_file, ASM_LONG " 4f - 1f\n"); - /* note type: NT_GNU_PROPERTY_TYPE_0. */ - fprintf (asm_out_file, ASM_LONG " 5\n"); - fprintf (asm_out_file, "0:\n"); - /* vendor name: "GNU". */ - fprintf (asm_out_file, STRING_ASM_OP " \"GNU\"\n"); - fprintf (asm_out_file, "1:\n"); - ASM_OUTPUT_ALIGN (asm_out_file, p2align); - /* pr_type: GNU_PROPERTY_X86_FEATURE_1_AND. */ - fprintf (asm_out_file, ASM_LONG " 0xc0000002\n"); - /* pr_datasz. */\ - fprintf (asm_out_file, ASM_LONG " 3f - 2f\n"); - fprintf (asm_out_file, "2:\n"); - /* GNU_PROPERTY_X86_FEATURE_1_XXX. */ - fprintf (asm_out_file, ASM_LONG " 0x%x\n", feature_1); - fprintf (asm_out_file, "3:\n"); - ASM_OUTPUT_ALIGN (asm_out_file, p2align); - fprintf (asm_out_file, "4:\n"); - } -} diff --git a/gcc/config/i386/gnu-property.c b/gcc/config/i386/gnu-property.c new file mode 100644 index 00000000000..128832561e2 --- /dev/null +++ b/gcc/config/i386/gnu-property.c @@ -0,0 +1,124 @@ +/* Functions for x86 GNU property. + Copyright (C) 2017-2020 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC 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, or (at your option) +any later version. + +GCC 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/>. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "output.h" +#include "linux-common.h" + +static void +emit_gnu_property (unsigned int type, unsigned int data) +{ + int p2align = ptr_mode == SImode ? 2 : 3; + + switch_to_section (get_section (".note.gnu.property", + SECTION_NOTYPE, NULL)); + + ASM_OUTPUT_ALIGN (asm_out_file, p2align); + /* name length. */ + fprintf (asm_out_file, ASM_LONG "1f - 0f\n"); + /* data length. */ + fprintf (asm_out_file, ASM_LONG "4f - 1f\n"); + /* note type: NT_GNU_PROPERTY_TYPE_0. */ + fprintf (asm_out_file, ASM_LONG "5\n"); + fprintf (asm_out_file, "0:\n"); + /* vendor name: "GNU". */ + fprintf (asm_out_file, STRING_ASM_OP "\"GNU\"\n"); + fprintf (asm_out_file, "1:\n"); + ASM_OUTPUT_ALIGN (asm_out_file, p2align); + /* pr_type. */ + fprintf (asm_out_file, ASM_LONG "0x%x\n", type); + /* pr_datasz. */ + fprintf (asm_out_file, ASM_LONG "3f - 2f\n"); + fprintf (asm_out_file, "2:\n"); + fprintf (asm_out_file, ASM_LONG "0x%x\n", data); + fprintf (asm_out_file, "3:\n"); + ASM_OUTPUT_ALIGN (asm_out_file, p2align); + fprintf (asm_out_file, "4:\n"); +} + +void +file_end_indicate_exec_stack_and_gnu_property (void) +{ + file_end_indicate_exec_stack (); + + if (flag_cf_protection == CF_NONE && !ix86_needed) + return; + + unsigned int feature_1 = 0; + + if (flag_cf_protection & CF_BRANCH) + /* GNU_PROPERTY_X86_FEATURE_1_IBT. */ + feature_1 |= 0x1; + + if (flag_cf_protection & CF_RETURN) + /* GNU_PROPERTY_X86_FEATURE_1_SHSTK. */ + feature_1 |= 0x2; + + /* Generate GNU_PROPERTY_X86_FEATURE_1_AND. */ + if (feature_1) + emit_gnu_property (0xc0000002, feature_1); + + unsigned int isa_1 = 0; + if (ix86_needed) + { + /* GNU_PROPERTY_X86_ISA_1_BASELINE. */ + if (TARGET_64BIT + || TARGET_FXSR + || TARGET_80387 + || TARGET_MMX + || TARGET_SSE + || TARGET_SSE2) + isa_1 |= 1 << 0; + + /* GNU_PROPERTY_X86_ISA_1_V2. */ + if (TARGET_CMPXCHG16B + || (TARGET_64BIT && TARGET_SAHF) + || TARGET_POPCNT + || TARGET_SSE3 + || TARGET_SSSE3 + || TARGET_SSE4_1 + || TARGET_SSE4_2) + isa_1 |= 1 << 1; + + /* GNU_PROPERTY_X86_ISA_1_V3. */ + if (TARGET_AVX + || TARGET_AVX2 + || TARGET_F16C + || TARGET_FMA + || TARGET_LZCNT + || TARGET_MOVBE + || TARGET_XSAVE) + isa_1 |= 1 << 2; + + /* GNU_PROPERTY_X86_ISA_1_V4. */ + if (TARGET_AVX512F + || TARGET_AVX512BW + || TARGET_AVX512CD + || TARGET_AVX512DQ + || TARGET_AVX512VL) + isa_1 |= 1 << 3; + } + + /* Generate GNU_PROPERTY_X86_ISA_1_NEEDED. */ + if (isa_1) + emit_gnu_property (0xc0008002, isa_1); +} diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 029cacb38e0..11b027e0fbb 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -1143,3 +1143,7 @@ Support KL built-in functions and code generation. mwidekl Target Report Mask(ISA2_WIDEKL) Var(ix86_isa_flags2) Save Support WIDEKL built-in functions and code generation. + +mneeded +Target Report Var(ix86_needed) Save +Emit GNU_PROPERTY_X86_ISA_1_NEEDED GNU property diff --git a/gcc/config/i386/linux-common.h b/gcc/config/i386/linux-common.h index 982390d7f3e..da0fabbb398 100644 --- a/gcc/config/i386/linux-common.h +++ b/gcc/config/i386/linux-common.h @@ -65,7 +65,7 @@ along with GCC; see the file COPYING3. If not see #define MPX_LD_AS_NEEDED_GUARD_POP "" #endif -extern void file_end_indicate_exec_stack_and_cet (void); +extern void file_end_indicate_exec_stack_and_gnu_property (void); #undef TARGET_ASM_FILE_END -#define TARGET_ASM_FILE_END file_end_indicate_exec_stack_and_cet +#define TARGET_ASM_FILE_END file_end_indicate_exec_stack_and_gnu_property diff --git a/gcc/config/i386/t-cet b/gcc/config/i386/t-gnu-property similarity index 93% rename from gcc/config/i386/t-cet rename to gcc/config/i386/t-gnu-property index d685d31ebcd..fd8bbce73c9 100644 --- a/gcc/config/i386/t-cet +++ b/gcc/config/i386/t-gnu-property @@ -16,6 +16,6 @@ # along with GCC; see the file COPYING3. If not see # <http://www.gnu.org/licenses/>. -cet.o: $(srcdir)/config/i386/cet.c +gnu-property.o: $(srcdir)/config/i386/gnu-property.c $(COMPILE) $< $(POSTCOMPILE) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index d01beb248e1..9593f0365e7 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1389,7 +1389,7 @@ See RS/6000 and PowerPC Options. -mstack-protector-guard-symbol=@var{symbol} @gol -mgeneral-regs-only -mcall-ms2sysv-xlogues @gol -mindirect-branch=@var{choice} -mfunction-return=@var{choice} @gol --mindirect-branch-register} +-mindirect-branch-register -mneeded} @emph{x86 Windows Options} @gccoptlist{-mconsole -mcygwin -mno-cygwin -mdll @gol @@ -31161,6 +31161,12 @@ environments. Generate code for short address mode. This is only supported for 32-bit and x32 environments. It is the default address mode for 32-bit and x32 environments. + +@item -mneeded +@itemx -mno-needed +@opindex mneeded +Emit GNU_PROPERTY_X86_ISA_1_NEEDED GNU property for Linux target to +indicate the micro-architecture ISA level required to execute the binary. @end table @node x86 Windows Options diff --git a/gcc/testsuite/gcc.target/i386/x86-needed-1.c b/gcc/testsuite/gcc.target/i386/x86-needed-1.c new file mode 100644 index 00000000000..b4584dfaeac --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/x86-needed-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "-fcf-protection -march=x86-64 -mneeded" } */ +/* { dg-final { scan-assembler-times ".note.gnu.property" 1 } } */ +/* { dg-final { scan-assembler-times ".long 0xc0000002" 1 } } */ +/* { dg-final { scan-assembler-times ".long 0xc0008002" 1 } } */ + +extern void foo (void); + +void +bar (void) +{ + foo (); +} diff --git a/gcc/testsuite/gcc.target/i386/x86-needed-2.c b/gcc/testsuite/gcc.target/i386/x86-needed-2.c new file mode 100644 index 00000000000..2d916562e6e --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/x86-needed-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-fcf-protection=none -march=x86-64 -mno-needed" } */ +/* { dg-final { scan-assembler-not ".note.gnu.property" } } */ + +extern void foo (void); + +void +bar (void) +{ + foo (); +} diff --git a/gcc/testsuite/gcc.target/i386/x86-needed-3.c b/gcc/testsuite/gcc.target/i386/x86-needed-3.c new file mode 100644 index 00000000000..1d93726bd32 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/x86-needed-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile { target ia32 } } */ +/* { dg-options "-fcf-protection=none -march=i686 -msoft-float -mneeded" } */ +/* { dg-final { scan-assembler-not ".note.gnu.property" } } */ + +extern void foo (void); + +void +bar (void) +{ + foo (); +}