Hi Uros, Sorry for my misunderstanding. The test is for the correctness check of intrinsic header. I have add -muintr to x86gprintrin-{1,2,3,4,5}.c.
UINTR is 64bit only, so I add them with dg-additional-option. Updated patch. If you agree, we will check-in the attached patch. Thanks for your help. H.J. Lu <hjl.to...@gmail.com> 于2020年10月14日周三 下午9:35写道: > > On Wed, Oct 14, 2020 at 6:31 AM Hongyu Wang via Gcc-patches > <gcc-patches@gcc.gnu.org> wrote: > > > > Uros Bizjak <ubiz...@gmail.com> 于2020年10月14日周三 下午7:19写道: > > > > > > > > Please also add -muintr to g++.dg/other/i386-{2,3}.C and > > > > > >> > > gcc.target/i386-sse-{12,13,14,22,23}.c. This will test new > > intrinsics > > > > > >> > > header. > > > > > >> > > > > > > > >> > > > > > > >> > Thanks for your review. We found that without adding -muintr, > > the intrinsics header could also be tested. Make-check for these file all > > get passed. > > > > > >> > > > > > > >> > And there is no intrinsic/builtin with const int parameter. So > > we remove -muintr from these files. > > > > > >> > > > > > >> Can your double check that relevant instructions are indeed > > generated? > > > > > >> Without -muintr, relevant patterns in i386.md are effectively > > blocked, > > > > > >> and perhaps a call to __builtin_ia32_* is generated instead. > > > > > > > > > > > > > > > > > > Yes, in sse-14.s we have > > > > > > > > > > > > _clui: > > > > > > .LFB136: > > > > > > .cfi_startproc > > > > > > pushq %rbp > > > > > > .cfi_def_cfa_offset 16 > > > > > > .cfi_offset 6, -16 > > > > > > movq %rsp, %rbp > > > > > > .cfi_def_cfa_register 6 > > > > > > clui > > > > > > nop > > > > > > popq %rbp > > > > > > .cfi_def_cfa 7, 8 > > > > > > ret > > > > > > .cfi_endproc > > > > > > > > > > Strange, without -muintr, it should not be generated, and some error > > > > > about failed inlining due to target specific option mismatch shoul be > > > > > emitted. > > > > > > > > > > Can you please investigate this a bit more? > > > > > > > > > > > > > Because of function target attribute? > > > > > > I don't think so. Please consider this similar testcase: > > > > > > --cut here-- > > > #ifndef __SSE2__ > > > #pragma GCC push_options > > > #pragma GCC target("sse2") > > > #define __DISABLE_SSE2__ > > > #endif /* __SSE2__ */ > > > > > > typedef double __v2df __attribute__ ((__vector_size__ (16))); > > > typedef double __m128d __attribute__ ((__vector_size__ (16), > > __may_alias__)); > > > > > > extern __inline __m128d __attribute__((__gnu_inline__, > > > __always_inline__, __artificial__)) > > > _mm_add_sd (__m128d __A, __m128d __B) > > > { > > > return (__m128d)__builtin_ia32_addsd ((__v2df)__A, (__v2df)__B); > > > } > > > > > > #ifdef __DISABLE_SSE2__ > > > #undef __DISABLE_SSE2__ > > > #pragma GCC pop_options > > > #endif /* __DISABLE_SSE2__ */ > > > > > > > > > __v2df foo (__v2df a, __v2df b) > > > { > > > return _mm_add_sd (a, b); > > > } > > > --cut here-- > > > > > > $ gcc -O2 -mno-sse2 -S -dp sse2.c > > > sse2.c: In function ‘foo’: > > > sse2.c:11:1: error: inlining failed in call to ‘always_inline’ > > > ‘_mm_add_sd’: target specific option mismatch > > > 11 | _mm_add_sd (__m128d __A, __m128d __B) > > > | ^~~~~~~~~~ > > > sse2.c:24:10: note: called from here > > > 24 | return _mm_add_sd (a, b); > > > | ^~~~~~~~~~~~~~~~~ > > > > > > I'd expect some similar warning from missing -mumip. > > > > > > > For this case, I can confirm uintr could generate similar warning without > > -muintr. But > > sse-{12,13,14,22,23}.c will not test intrinsic call for uintr, since it > > doesn't have const > > int parameter intrinsics. > > > > sse-{13,14,22,23}.c has > > > > #define extern > > #define __inline > > > > So intrinsic will be treated as common call to builtin, then > > > > #pragma GCC push_options > > #pragma GCC target("uintr") > > > > ensures the builtin could be expanded correctly. > > > > I think the intrinsic call test should be in uintr-1.c, so it is redundant > > to add -muintr in sse-{12,13,14,22,23}.c > > or x86gprintrin-*.c. > > Please add UINTR intrinsic tests to x86gprintrin-*.c to cover such > usages. > > > > > > > Uros. > > > > -- > H.J.
From 7b5ba74517bf58b9f985bfe7591372c64a313ad7 Mon Sep 17 00:00:00 2001 From: liuhongt <hongtao....@intel.com> Date: Mon, 20 May 2019 17:56:41 +0800 Subject: [PATCH] Enable gcc support for UINTR 2020-05-20 Hongtao Liu <hongtao....@intel.com> gcc/ * common/config/i386/cpuinfo.h (get_available_features): Detect UINTR. * common/config/i386/i386-common.c (OPTION_MASK_ISA2_UINTR_SET OPTION_MASK_ISA2_UINTR_UNSET): New. (ix86_handle_option): Handle -muintr. * common/config/i386/i386-cpuinfo.h (enum processor_features): Add FEATURE_UINTR. * common/config/i386/i386-isas.h: Add ISA_NAMES_TABLE_ENTRY for uintr. * config.gcc: Add uintrintrin.h to extra_headers. * config/i386/uintrintrin.h: New. * config/i386/cpuid.h (bit_UINTR): New. * config/i386/driver-i386.c (host_detect_local_cpu): Detect UINTR. * config/i386/i386-builtin-types.def: Add new types. * config/i386/i386-builtin.def: Add new builtins. * config/i386/i386-builtins.c (ix86_init_mmx_sse_builtins): Add __builtin_ia32_testui. * config/i386/i386-builtins.h (ix86_builtins): Add IX86_BUILTIN_TESTUI. * config/i386/i386-c.c (ix86_target_macros_internal): Define __UINTR__. * config/i386/i386-expand.c (ix86_expand_special_args_builtin): Handle UINT8_FTYPE_VOID. (ix86_expand_builtin): Handle IX86_BUILTIN_TESTUI. * config/i386/i386-options.c (isa2_opts): Add -muintr. (ix86_valid_target_attribute_inner_p): Handle UINTR. (ix86_option_override_internal): Add TARGET_64BIT check for UINTR. * config/i386/i386.h (TARGET_UINTR, TARGET_UINTR_P, PTA_UINTR): New. (PTA_SAPPHIRRAPIDS): Add PTA_UINTR. * config/i386/i386.opt: Add -muintr. * config/i386/i386.md (define_int_iterator UINTR_UNSPECV): New. (define_int_attr uintr_unspecv): New. (uintr_<uintr_unspecv>, uintr_senduipi, testui): New define_insn patterns. * config/i386/x86gprintrin.h: Include uintrintrin.h * doc/invoke.texi: Document -muintr. * doc/extend.texi: Document uintr. gcc/testsuite/ * gcc.target/i386/funcspec-56.inc: Add new target attribute. * gcc.target/i386/uintr-1.c: New test. * gcc.target/i386/uintr-2.c: Ditto. * gcc.target/i386/uintr-3.c: Ditto. * gcc.target/i386/uintr-4.c: Ditto. * gcc.target/i386/uintr-5.c: Ditto. * gcc.target/i386/x86gprintrin-1.c: Add -muintr for 64bit target. * gcc.target/i386/x86gprintrin-2.c: Ditto. * gcc.target/i386/x86gprintrin-3.c: Ditto. * gcc.target/i386/x86gprintrin-4.c: Add muintr for 64bit target. * gcc.target/i386/x86gprintrin-5.c: Ditto. --- gcc/common/config/i386/cpuinfo.h | 2 + gcc/common/config/i386/i386-common.c | 15 ++++ gcc/common/config/i386/i386-cpuinfo.h | 1 + gcc/common/config/i386/i386-isas.h | 1 + gcc/config.gcc | 4 +- gcc/config/i386/cpuid.h | 1 + gcc/config/i386/i386-builtin-types.def | 1 + gcc/config/i386/i386-builtin.def | 5 ++ gcc/config/i386/i386-builtins.c | 5 ++ gcc/config/i386/i386-builtins.h | 1 + gcc/config/i386/i386-c.c | 2 + gcc/config/i386/i386-expand.c | 14 +++ gcc/config/i386/i386-options.c | 7 +- gcc/config/i386/i386.h | 6 +- gcc/config/i386/i386.md | 36 +++++++- gcc/config/i386/i386.opt | 4 + gcc/config/i386/uintrintrin.h | 87 +++++++++++++++++++ gcc/config/i386/x86gprintrin.h | 2 + gcc/doc/extend.texi | 5 ++ gcc/doc/invoke.texi | 8 +- gcc/testsuite/gcc.target/i386/funcspec-56.inc | 2 + gcc/testsuite/gcc.target/i386/uintr-1.c | 21 +++++ gcc/testsuite/gcc.target/i386/uintr-2.c | 17 ++++ gcc/testsuite/gcc.target/i386/uintr-3.c | 9 ++ gcc/testsuite/gcc.target/i386/uintr-4.c | 9 ++ gcc/testsuite/gcc.target/i386/uintr-5.c | 10 +++ .../gcc.target/i386/x86gprintrin-1.c | 1 + .../gcc.target/i386/x86gprintrin-2.c | 1 + .../gcc.target/i386/x86gprintrin-3.c | 1 + .../gcc.target/i386/x86gprintrin-4.c | 4 + .../gcc.target/i386/x86gprintrin-5.c | 4 + 31 files changed, 278 insertions(+), 8 deletions(-) create mode 100644 gcc/config/i386/uintrintrin.h create mode 100644 gcc/testsuite/gcc.target/i386/uintr-1.c create mode 100644 gcc/testsuite/gcc.target/i386/uintr-2.c create mode 100644 gcc/testsuite/gcc.target/i386/uintr-3.c create mode 100644 gcc/testsuite/gcc.target/i386/uintr-4.c create mode 100644 gcc/testsuite/gcc.target/i386/uintr-5.c diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index c96455ce64f..0e63db271f6 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -701,6 +701,8 @@ get_available_features (struct __processor_model *cpu_model, set_feature (FEATURE_AVX5124FMAPS); if (edx & bit_AVX512VP2INTERSECT) set_feature (FEATURE_AVX512VP2INTERSECT); + if (edx & bit_UINTR) + set_feature (FEATURE_UINTR); __cpuid_count (7, 1, eax, ebx, ecx, edx); if (eax & bit_AVX512BF16) diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c index 62a620b4430..6a06383ef0d 100644 --- a/gcc/common/config/i386/i386-common.c +++ b/gcc/common/config/i386/i386-common.c @@ -163,6 +163,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_ENQCMD_SET OPTION_MASK_ISA2_ENQCMD #define OPTION_MASK_ISA2_SERIALIZE_SET OPTION_MASK_ISA2_SERIALIZE #define OPTION_MASK_ISA2_TSXLDTRK_SET OPTION_MASK_ISA2_TSXLDTRK +#define OPTION_MASK_ISA2_UINTR_SET OPTION_MASK_ISA2_UINTR /* Define a set of ISAs which aren't available when a given ISA is disabled. MMX and SSE ISAs are handled separately. */ @@ -254,6 +255,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA2_AMX_TILE_UNSET OPTION_MASK_ISA2_AMX_TILE #define OPTION_MASK_ISA2_AMX_INT8_UNSET OPTION_MASK_ISA2_AMX_INT8 #define OPTION_MASK_ISA2_AMX_BF16_UNSET OPTION_MASK_ISA2_AMX_BF16 +#define OPTION_MASK_ISA2_UINTR_UNSET OPTION_MASK_ISA2_UINTR /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same as -mno-sse4.1. */ @@ -702,6 +704,19 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_muintr: + if (value) + { + opts->x_ix86_isa_flags2 |= OPTION_MASK_ISA2_UINTR_SET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_UINTR_SET; + } + else + { + opts->x_ix86_isa_flags2 &= ~OPTION_MASK_ISA2_UINTR_UNSET; + opts->x_ix86_isa_flags2_explicit |= OPTION_MASK_ISA2_UINTR_UNSET; + } + return true; + case OPT_mavx5124fmaps: if (value) { diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index 5b94b1f1df7..3fc2af5c3b1 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -219,6 +219,7 @@ enum processor_features FEATURE_AMX_TILE, FEATURE_AMX_INT8, FEATURE_AMX_BF16, + FEATURE_UINTR, CPU_FEATURE_MAX }; diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h index 3c830ea08ff..c2dc74171bf 100644 --- a/gcc/common/config/i386/i386-isas.h +++ b/gcc/common/config/i386/i386-isas.h @@ -163,4 +163,5 @@ ISA_NAMES_TABLE_START ISA_NAMES_TABLE_ENTRY("amx-tile", FEATURE_AMX_TILE, P_NONE, "-mamx-tile") ISA_NAMES_TABLE_ENTRY("amx-int8", FEATURE_AMX_INT8, P_NONE, "-mamx-int8") ISA_NAMES_TABLE_ENTRY("amx-bf16", FEATURE_AMX_BF16, P_NONE, "-mamx-bf16") + ISA_NAMES_TABLE_ENTRY("uintr", FEATURE_UINTR, P_NONE, "-muintr") ISA_NAMES_TABLE_END diff --git a/gcc/config.gcc b/gcc/config.gcc index d5634b043e2..c02bdddab69 100644 --- a/gcc/config.gcc +++ b/gcc/config.gcc @@ -413,7 +413,7 @@ i[34567]86-*-*) avx512bf16intrin.h enqcmdintrin.h serializeintrin.h avx512vp2intersectintrin.h avx512vp2intersectvlintrin.h tsxldtrkintrin.h amxtileintrin.h amxint8intrin.h - amxbf16intrin.h x86gprintrin.h" + amxbf16intrin.h x86gprintrin.h uintrintrin.h" ;; x86_64-*-*) cpu_type=i386 @@ -449,7 +449,7 @@ x86_64-*-*) avx512bf16intrin.h enqcmdintrin.h serializeintrin.h avx512vp2intersectintrin.h avx512vp2intersectvlintrin.h tsxldtrkintrin.h amxtileintrin.h amxint8intrin.h - amxbf16intrin.h x86gprintrin.h" + amxbf16intrin.h x86gprintrin.h uintrintrin.h" ;; ia64-*-*) extra_headers=ia64intrin.h diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h index 4598434fd02..fbc8ca245bd 100644 --- a/gcc/config/i386/cpuid.h +++ b/gcc/config/i386/cpuid.h @@ -124,6 +124,7 @@ #define bit_AVX5124FMAPS (1 << 3) #define bit_AVX512VP2INTERSECT (1 << 8) #define bit_IBT (1 << 20) +#define bit_UINTR (1 << 5) #define bit_PCONFIG (1 << 18) #define bit_SERIALIZE (1 << 14) #define bit_TSXLDTRK (1 << 16) diff --git a/gcc/config/i386/i386-builtin-types.def b/gcc/config/i386/i386-builtin-types.def index 1adf7c44f4a..6d585f2280c 100644 --- a/gcc/config/i386/i386-builtin-types.def +++ b/gcc/config/i386/i386-builtin-types.def @@ -194,6 +194,7 @@ DEF_FUNCTION_TYPE (UNSIGNED) DEF_FUNCTION_TYPE (UINT) DEF_FUNCTION_TYPE (USHORT) DEF_FUNCTION_TYPE (INT) +DEF_FUNCTION_TYPE (UINT8) DEF_FUNCTION_TYPE (VOID) DEF_FUNCTION_TYPE (PVOID) diff --git a/gcc/config/i386/i386-builtin.def b/gcc/config/i386/i386-builtin.def index fec5cef0b55..9f2d4cc0406 100644 --- a/gcc/config/i386/i386-builtin.def +++ b/gcc/config/i386/i386-builtin.def @@ -452,6 +452,11 @@ BDESC (0, OPTION_MASK_ISA2_SERIALIZE, CODE_FOR_serialize, "__builtin_ia32_serial BDESC (0, OPTION_MASK_ISA2_TSXLDTRK, CODE_FOR_xsusldtrk, "__builtin_ia32_xsusldtrk", IX86_BUILTIN_XSUSLDTRK, UNKNOWN, (int) VOID_FTYPE_VOID) BDESC (0, OPTION_MASK_ISA2_TSXLDTRK, CODE_FOR_xresldtrk, "__builtin_ia32_xresldtrk", IX86_BUILTIN_XRESLDTRK, UNKNOWN, (int) VOID_FTYPE_VOID) +/* UINTR. */ +BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_UINTR, CODE_FOR_clui, "__builtin_ia32_clui", IX86_BUILTIN_CLUI, UNKNOWN, (int) VOID_FTYPE_VOID) +BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_UINTR, CODE_FOR_stui, "__builtin_ia32_stui", IX86_BUILTIN_STUI, UNKNOWN, (int) VOID_FTYPE_VOID) +BDESC (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_UINTR, CODE_FOR_senduipi, "__builtin_ia32_senduipi", IX86_BUILTIN_SENDUIPI, UNKNOWN, (int) VOID_FTYPE_UINT64) + BDESC_END (SPECIAL_ARGS, ARGS) /* Builtins with variable number of arguments. */ diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c index ca7a870896b..504987a5410 100644 --- a/gcc/config/i386/i386-builtins.c +++ b/gcc/config/i386/i386-builtins.c @@ -1194,6 +1194,11 @@ ix86_init_mmx_sse_builtins (void) def_builtin (0, OPTION_MASK_ISA2_WAITPKG, "__builtin_ia32_tpause", UINT8_FTYPE_UNSIGNED_UINT64, IX86_BUILTIN_TPAUSE); + /* UINTR. */ + def_builtin (OPTION_MASK_ISA_64BIT, OPTION_MASK_ISA2_UINTR, + "__builtin_ia32_testui", + UINT8_FTYPE_VOID, IX86_BUILTIN_TESTUI); + /* CLDEMOTE. */ def_builtin (0, OPTION_MASK_ISA2_CLDEMOTE, "__builtin_ia32_cldemote", VOID_FTYPE_PCVOID, IX86_BUILTIN_CLDEMOTE); diff --git a/gcc/config/i386/i386-builtins.h b/gcc/config/i386/i386-builtins.h index cc6a8ce9966..a88cc0c387e 100644 --- a/gcc/config/i386/i386-builtins.h +++ b/gcc/config/i386/i386-builtins.h @@ -40,6 +40,7 @@ enum ix86_builtins IX86_BUILTIN_UMONITOR, IX86_BUILTIN_UMWAIT, IX86_BUILTIN_TPAUSE, + IX86_BUILTIN_TESTUI, IX86_BUILTIN_CLZERO, IX86_BUILTIN_CLDEMOTE, IX86_BUILTIN_VEC_INIT_V2SI, diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c index e647fce9ad4..219e1be23e6 100644 --- a/gcc/config/i386/i386-c.c +++ b/gcc/config/i386/i386-c.c @@ -598,6 +598,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__LAHF_SAHF__"); if (isa_flag2 & OPTION_MASK_ISA2_MOVBE) def_or_undef (parse_in, "__MOVBE__"); + if (isa_flag2 & OPTION_MASK_ISA2_UINTR) + def_or_undef (parse_in, "__UINTR__"); if (TARGET_IAMCU) { diff --git a/gcc/config/i386/i386-expand.c b/gcc/config/i386/i386-expand.c index e6f8b314f18..5a9955bf8c4 100644 --- a/gcc/config/i386/i386-expand.c +++ b/gcc/config/i386/i386-expand.c @@ -10413,6 +10413,7 @@ ix86_expand_special_args_builtin (const struct builtin_description *d, case USHORT_FTYPE_VOID: case UINT64_FTYPE_VOID: case UINT_FTYPE_VOID: + case UINT8_FTYPE_VOID: case UNSIGNED_FTYPE_VOID: nargs = 0; klass = load; @@ -11203,6 +11204,19 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, return target; + case IX86_BUILTIN_TESTUI: + emit_insn (gen_testui ()); + + if (target == 0 + || !register_operand (target, QImode)) + target = gen_reg_rtx (QImode); + + pat = gen_rtx_LTU (QImode, gen_rtx_REG (CCCmode, FLAGS_REG), + const0_rtx); + emit_insn (gen_rtx_SET (target, pat)); + + return target; + case IX86_BUILTIN_CLZERO: arg0 = CALL_EXPR_ARG (exp, 0); op0 = expand_normal (arg0); diff --git a/gcc/config/i386/i386-options.c b/gcc/config/i386/i386-options.c index a59bd703880..1edc1c8a7b9 100644 --- a/gcc/config/i386/i386-options.c +++ b/gcc/config/i386/i386-options.c @@ -212,7 +212,8 @@ static struct ix86_target_opts isa2_opts[] = { "-mtsxldtrk", OPTION_MASK_ISA2_TSXLDTRK }, { "-mamx-tile", OPTION_MASK_ISA2_AMX_TILE }, { "-mamx-int8", OPTION_MASK_ISA2_AMX_INT8 }, - { "-mamx-bf16", OPTION_MASK_ISA2_AMX_BF16 } + { "-mamx-bf16", OPTION_MASK_ISA2_AMX_BF16 }, + { "-muintr", OPTION_MASK_ISA2_UINTR } }; static struct ix86_target_opts isa_opts[] = { @@ -1031,6 +1032,7 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[], IX86_ATTR_ISA ("movdir64b", OPT_mmovdir64b), IX86_ATTR_ISA ("waitpkg", OPT_mwaitpkg), IX86_ATTR_ISA ("cldemote", OPT_mcldemote), + IX86_ATTR_ISA ("uintr", OPT_muintr), IX86_ATTR_ISA ("ptwrite", OPT_mptwrite), IX86_ATTR_ISA ("avx512bf16", OPT_mavx512bf16), IX86_ATTR_ISA ("enqcmd", OPT_menqcmd), @@ -1899,6 +1901,9 @@ ix86_option_override_internal (bool main_args_p, opts->x_ix86_stringop_alg = no_stringop; } + if (TARGET_UINTR && !TARGET_64BIT) + error ("%<-muintr%> not supported for 32-bit code"); + if (!opts->x_ix86_arch_string) opts->x_ix86_arch_string = TARGET_64BIT_P (opts->x_ix86_isa_flags) diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 9a5de6a0e9c..e933b3588c2 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -209,6 +209,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define TARGET_AMX_INT8_P(x) TARGET_ISA2_AMX_INT8(x) #define TARGET_AMX_BF16 TARGET_ISA2_AMX_BF16 #define TARGET_AMX_BF16_P(x) TARGET_ISA2_AMX_BF16(x) +#define TARGET_UINTR TARGET_ISA2_UINTR +#define TARGET_UINTR_P(x) TARGET_ISA2_UINTR_P(x) #define TARGET_LP64 TARGET_ABI_64 #define TARGET_LP64_P(x) TARGET_ABI_64_P(x) @@ -2475,6 +2477,7 @@ const wide_int_bitmask PTA_TSXLDTRK (0, HOST_WIDE_INT_1U << 18); const wide_int_bitmask PTA_AMX_TILE(0, HOST_WIDE_INT_1U << 19); const wide_int_bitmask PTA_AMX_INT8(0, HOST_WIDE_INT_1U << 20); const wide_int_bitmask PTA_AMX_BF16(0, HOST_WIDE_INT_1U << 21); +const wide_int_bitmask PTA_UINTR (0, HOST_WIDE_INT_1U << 22); const wide_int_bitmask PTA_X86_64_BASELINE = PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_NO_SAHF | PTA_FXSR; @@ -2485,6 +2488,7 @@ const wide_int_bitmask PTA_X86_64_V3 = PTA_X86_64_V2 | PTA_MOVBE | PTA_XSAVE; const wide_int_bitmask PTA_X86_64_V4 = PTA_X86_64_V3 | PTA_AVX512F | PTA_AVX512BW | PTA_AVX512CD | PTA_AVX512DQ | PTA_AVX512VL; + const wide_int_bitmask PTA_CORE2 = PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_CX16 | PTA_FXSR; const wide_int_bitmask PTA_NEHALEM = PTA_CORE2 | PTA_SSE4_1 | PTA_SSE4_2 @@ -2518,7 +2522,7 @@ const wide_int_bitmask PTA_TIGERLAKE = PTA_ICELAKE_CLIENT | PTA_MOVDIRI const wide_int_bitmask PTA_SAPPHIRERAPIDS = PTA_COOPERLAKE | PTA_MOVDIRI | PTA_MOVDIR64B | PTA_AVX512VP2INTERSECT | PTA_ENQCMD | PTA_CLDEMOTE | PTA_PTWRITE | PTA_WAITPKG | PTA_SERIALIZE | PTA_TSXLDTRK | PTA_AMX_TILE - | PTA_AMX_INT8 | PTA_AMX_BF16; + | PTA_AMX_INT8 | PTA_AMX_BF16 | PTA_UINTR; const wide_int_bitmask PTA_ALDERLAKE = PTA_SKYLAKE | PTA_CLDEMOTE | PTA_PTWRITE | PTA_WAITPKG | PTA_SERIALIZE; const wide_int_bitmask PTA_KNL = PTA_BROADWELL | PTA_AVX512PF | PTA_AVX512ER diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 9dd12cf8643..b27cf53ed97 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -293,6 +293,12 @@ UNSPECV_UMONITOR UNSPECV_TPAUSE + ;; For UINTR support + UNSPECV_CLUI + UNSPECV_STUI + UNSPECV_TESTUI + UNSPECV_SENDUIPI + ;; For CLDEMOTE support UNSPECV_CLDEMOTE @@ -13666,7 +13672,7 @@ (unspec [(const_int 0)] UNSPEC_INTERRUPT_RETURN)] "reload_completed" { - return TARGET_64BIT ? "iretq" : "iret"; + return TARGET_64BIT ? (TARGET_UINTR ? "uiret" : "iretq") : "iret"; }) ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET @@ -21571,6 +21577,34 @@ "enqcmd<enqcmd_sfx>\t{%1, %0|%0, %1}" [(set_attr "type" "other")]) +;; UINTR +(define_int_iterator UINTR [UNSPECV_CLUI UNSPECV_STUI]) +(define_int_attr uintr [(UNSPECV_CLUI "clui") (UNSPECV_STUI "stui")]) + +(define_insn "<uintr>" + [(unspec_volatile [(const_int 0)] UINTR)] + "TARGET_UINTR && TARGET_64BIT" + "<uintr>" + [(set_attr "type" "other") + (set_attr "length" "4")]) + +(define_insn "testui" + [(set (reg:CCC FLAGS_REG) + (unspec_volatile:CCC [(const_int 0)] UNSPECV_TESTUI))] + "TARGET_UINTR && TARGET_64BIT" + "testui" + [(set_attr "type" "other") + (set_attr "length" "4")]) + +(define_insn "senduipi" + [(unspec_volatile + [(match_operand:DI 0 "register_operand" "r")] + UNSPECV_SENDUIPI)] + "TARGET_UINTR && TARGET_64BIT" + "senduipi\t%0" + [(set_attr "type" "other") + (set_attr "length" "4")]) + ;; WAITPKG (define_insn "umwait" diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt index 9389dc24948..68f49f53d47 100644 --- a/gcc/config/i386/i386.opt +++ b/gcc/config/i386/i386.opt @@ -788,6 +788,10 @@ mptwrite Target Report Mask(ISA2_PTWRITE) Var(ix86_isa_flags2) Save Support PTWRITE built-in functions and code generation. +muintr +Target Report Mask(ISA2_UINTR) Var(ix86_isa_flags2) Save +Support UINTR built-in functions and code generation. + msgx Target Report Mask(ISA2_SGX) Var(ix86_isa_flags2) Save Support SGX built-in functions and code generation. diff --git a/gcc/config/i386/uintrintrin.h b/gcc/config/i386/uintrintrin.h new file mode 100644 index 00000000000..991f6427971 --- /dev/null +++ b/gcc/config/i386/uintrintrin.h @@ -0,0 +1,87 @@ +/* Copyright (C) 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. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef _X86GPRINTRIN_H_INCLUDED +# error "Never use <uintrintrin.h> directly; include <x86gprintrin.h> instead." +#endif + +#ifndef _UINTRNTRIN_H_INCLUDED +#define _UINTRNTRIN_H_INCLUDED + +#ifdef __x86_64__ + +#ifndef __UINTR__ +#pragma GCC push_options +#pragma GCC target ("uintr") +#define __DISABLE_UINTR__ +#endif /* __UINTR__ */ + +struct __uintr_frame +{ + /* The position of the most significant bit set in user-interrupt + request register. */ + unsigned long long uirrv; + /* RIP of the interrupted user process. */ + unsigned long long rip; + /* RFLAGS of the interrupted user process. */ + unsigned long long rflags; + /* RSP of the interrupted user process. */ + unsigned long long rsp; +}; + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_clui (void) +{ + __builtin_ia32_clui (); +} + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_stui (void) +{ + __builtin_ia32_stui (); +} + +extern __inline void +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_senduipi (unsigned long long __R) +{ + __builtin_ia32_senduipi (__R); +} + +extern __inline unsigned char +__attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_testui (void) +{ + return __builtin_ia32_testui (); +} + +#ifdef __DISABLE_UINTR__ +#undef __DISABLE_UINTR__ +#pragma GCC pop_options +#endif /* __DISABLE_UINTR__ */ + +#endif + +#endif /* _UINTRNTRIN_H_INCLUDED. */ diff --git a/gcc/config/i386/x86gprintrin.h b/gcc/config/i386/x86gprintrin.h index ecfb1c0e67f..e35f4b65c9c 100644 --- a/gcc/config/i386/x86gprintrin.h +++ b/gcc/config/i386/x86gprintrin.h @@ -76,6 +76,8 @@ #include <tsxldtrkintrin.h> +#include <uintrintrin.h> + #include <waitpkgintrin.h> #include <wbnoinvdintrin.h> diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index b9684dc7a06..bd46ebc83cc 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -6638,6 +6638,11 @@ Enable/disable the generation of the AMX-INT8 instructions. @cindex @code{target("amx-bf16")} function attribute, x86 Enable/disable the generation of the AMX-BF16 instructions. +@item uintr +@itemx no-uintr +@cindex @code{target("uintr")} function attribute, x86 +Enable/disable the generation of the UINTR instructions. + @item cld @itemx no-cld @cindex @code{target("cld")} function attribute, x86 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 47aa69530ab..0a5e1e88d21 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1364,7 +1364,7 @@ See RS/6000 and PowerPC Options. -mvpclmulqdq -mavx512bitalg -mmovdiri -mmovdir64b -mavx512vpopcntdq @gol -mavx5124fmaps -mavx512vnni -mavx5124vnniw -mprfchw -mrdpid @gol -mrdseed -msgx -mavx512vp2intersect -mserialize -mtsxldtrk@gol --mamx-tile -mamx-int8 -mamx-bf16@gol +-mamx-tile -mamx-int8 -mamx-bf16 -muintr@gol -mcldemote -mms-bitfields -mno-align-stringops -minline-all-stringops @gol -minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol -mmemcpy-strategy=@var{strategy} -mmemset-strategy=@var{strategy} @gol @@ -30259,6 +30259,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}. @need 200 @itemx -menqcmd @opindex menqcmd +@itemx -muintr +@opindex muintr @need 200 @itemx -mtsxldtrk @opindex mtsxldtrk @@ -30300,8 +30302,8 @@ WBNOINVD, FMA4, PREFETCHW, RDPID, PREFETCHWT1, RDSEED, SGX, XOP, LWP, 3DNow!@:, enhanced 3DNow!@:, POPCNT, ABM, ADX, BMI, BMI2, LZCNT, FXSR, XSAVE, XSAVEOPT, XSAVEC, XSAVES, RTM, HLE, TBM, MWAITX, CLZERO, PKU, AVX512VBMI2, GFNI, VAES, WAITPKG, VPCLMULQDQ, AVX512BITALG, MOVDIRI, MOVDIR64B, AVX512BF16, -ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE -or CLDEMOTE extended instruction sets. Each has a corresponding +ENQCMD, AVX512VPOPCNTDQ, AVX5124FMAPS, AVX512VNNI, AVX5124VNNIW, SERIALIZE, +UINTR or CLDEMOTE extended instruction sets. Each has a corresponding @option{-mno-} option to disable use of these instructions. These extensions are also available as built-in functions: see diff --git a/gcc/testsuite/gcc.target/i386/funcspec-56.inc b/gcc/testsuite/gcc.target/i386/funcspec-56.inc index 8e669f12215..d6a2e8d2305 100644 --- a/gcc/testsuite/gcc.target/i386/funcspec-56.inc +++ b/gcc/testsuite/gcc.target/i386/funcspec-56.inc @@ -74,6 +74,7 @@ extern void test_avx512vp2intersect (void) __attribute__((__target__("avx512vp2i extern void test_amx_tile (void) __attribute__((__target__("amx-tile"))); extern void test_amx_int8 (void) __attribute__((__target__("amx-int8"))); extern void test_amx_bf16 (void) __attribute__((__target__("amx-bf16"))); +extern void test_uintr (void) __attribute__((__target__("uintr"))); extern void test_no_sgx (void) __attribute__((__target__("no-sgx"))); extern void test_no_avx5124fmaps(void) __attribute__((__target__("no-avx5124fmaps"))); @@ -149,6 +150,7 @@ extern void test_no_avx512vp2intersect (void) __attribute__((__target__("no-avx5 extern void test_no_amx_tile (void) __attribute__((__target__("no-amx-tile"))); extern void test_no_amx_int8 (void) __attribute__((__target__("no-amx-int8"))); extern void test_no_amx_bf16 (void) __attribute__((__target__("no-amx-bf16"))); +extern void test_no_uintr (void) __attribute__((__target__("no-uintr"))); extern void test_arch_nocona (void) __attribute__((__target__("arch=nocona"))); extern void test_arch_core2 (void) __attribute__((__target__("arch=core2"))); diff --git a/gcc/testsuite/gcc.target/i386/uintr-1.c b/gcc/testsuite/gcc.target/i386/uintr-1.c new file mode 100644 index 00000000000..f30f755a139 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/uintr-1.c @@ -0,0 +1,21 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -muintr" } */ +/* { dg-final { scan-assembler-times "clui" "1" } } */ +/* { dg-final { scan-assembler-times "stui" "2" } } */ +/* { dg-final { scan-assembler-times "senduipi" "1" } } */ +/* { dg-final { scan-assembler-times "setc" "1" } } */ +/* { dg-final { scan-assembler-times "testui" "1" } } */ + +#include <x86gprintrin.h> + +extern volatile unsigned char c; +extern volatile unsigned long long l; + +void +foo (void) +{ + _clui (); + _stui (); + _senduipi (l); + c = _testui (); +} diff --git a/gcc/testsuite/gcc.target/i386/uintr-2.c b/gcc/testsuite/gcc.target/i386/uintr-2.c new file mode 100644 index 00000000000..e705732c1bd --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/uintr-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -muintr -mgeneral-regs-only" } */ +/* { dg-final { scan-assembler-times "uiret" "2" } } */ + +#include <x86gprintrin.h> + +void +__attribute__((interrupt)) +foo (void *frame) +{ +} + +void +__attribute__((interrupt)) +UINTR_hanlder (struct __uintr_frame *frame) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/uintr-3.c b/gcc/testsuite/gcc.target/i386/uintr-3.c new file mode 100644 index 00000000000..d2843495158 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/uintr-3.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -muintr" } */ +/* { dg-final { scan-assembler "uiret" } } */ +#include <x86gprintrin.h> + +void __attribute__ ((target("general-regs-only"), interrupt)) +UINTR_handler (struct __uintr_frame *p) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/uintr-4.c b/gcc/testsuite/gcc.target/i386/uintr-4.c new file mode 100644 index 00000000000..f3b371b4231 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/uintr-4.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2 -muintr" } */ + +#include <x86gprintrin.h> + +void __attribute__ ((interrupt)) +UINTR_handler (struct __uintr_frame *p) +{ /* { dg-message "SSE instructions aren't allowed in an interrupt service routine" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/uintr-5.c b/gcc/testsuite/gcc.target/i386/uintr-5.c new file mode 100644 index 00000000000..ac44be0a706 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/uintr-5.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -muintr" } */ +/* { dg-error "'-muintr' not supported for 32-bit code" "" { target ia32 } 0 } */ + +#include <x86gprintrin.h> + +void +UINTR_hanlder (struct __uintr_frame *frame) +{ +} diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c index d9c759bde4e..a65e7d55bbb 100644 --- a/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c +++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-1.c @@ -1,6 +1,7 @@ /* Test that <x86gprintrin.h> is usable with -O -std=c89 -pedantic-errors. */ /* { dg-do compile } */ /* { dg-options "-O -std=c89 -pedantic-errors -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */ +/* { dg-additional-options "-muintr" { target { ! ia32 } } } */ #include <x86gprintrin.h> diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c index 5ea47726405..ae56e5e9831 100644 --- a/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c +++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-2.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-O2 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */ /* { dg-add-options bind_pic_locally } */ +/* { dg-additional-options "-muintr" { target { ! ia32 } } } */ /* Test that the intrinsics in <x86gprintrin.h> compile with optimization. All of them are defined as inline functions that reference the proper diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c index 01d3f7878b0..c826acd9f3e 100644 --- a/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c +++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-3.c @@ -1,6 +1,7 @@ /* { dg-do compile } */ /* { dg-options "-O0 -Werror-implicit-function-declaration -march=x86-64 -madx -mbmi -mbmi2 -mcldemote -mclflushopt -mclwb -mclzero -menqcmd -mfsgsbase -mfxsr -mlzcnt -mlwp -mmovdiri -mmwaitx -mpconfig -mpopcnt -mpku -mptwrite -mrdpid -mrdrnd -mrdseed -mrtm -mserialize -msgx -mshstk -mtbm -mtsxldtrk -mwaitpkg -mwbnoinvd -mxsave -mxsavec -mxsaveopt -mxsaves -mno-sse -mno-mmx" } */ /* { dg-add-options bind_pic_locally } */ +/* { dg-additional-options "-muintr" { target { ! ia32 } } } */ /* Test that the intrinsics in <x86gprintrin.h> compile without optimization. All of them are defined as inline functions that reference the proper diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c index 053f07bc17f..e0aa3a782af 100644 --- a/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c +++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-4.c @@ -14,8 +14,12 @@ #define __inline #ifndef DIFFERENT_PRAGMAS +#ifdef __x86_64__ +#pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,uintr,xsaveopt") +#else #pragma GCC target ("adx,bmi,bmi2,fsgsbase,fxsr,lwp,lzcnt,popcnt,rdrnd,rdseed,tbm,rtm,serialize,tsxldtrk,xsaveopt") #endif +#endif /* popcnintrin.h (POPCNT). */ #ifdef DIFFERENT_PRAGMAS diff --git a/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c b/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c index fe9c5c770ae..a28c16a90e3 100644 --- a/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c +++ b/gcc/testsuite/gcc.target/i386/x86gprintrin-5.c @@ -27,6 +27,10 @@ /* rtmintrin.h */ #define __builtin_ia32_xabort(M) __builtin_ia32_xabort(1) +#ifdef __x86_64__ +#pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,uintr,xsavec,xsaveopt,xsaves,wbnoinvd") +#else #pragma GCC target ("adx,bmi,bmi2,clflushopt,clwb,clzero,enqcmd,fsgsbase,fxsr,lwp,lzcnt,mwaitx,pconfig,pku,popcnt,rdpid,rdrnd,rdseed,tbm,rtm,serialize,sgx,tsxldtrk,xsavec,xsaveopt,xsaves,wbnoinvd") +#endif #include <x86gprintrin.h> -- 2.25.1