From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-out2.suse.de (smtp-out2.suse.de [195.135.220.29]) by sourceware.org (Postfix) with ESMTPS id 8D2813853C13 for ; Thu, 12 Aug 2021 14:40:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 8D2813853C13 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.cz Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=suse.cz Received: from imap1.suse-dmz.suse.de (imap1.suse-dmz.suse.de [192.168.254.73]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by smtp-out2.suse.de (Postfix) with ESMTPS id 3AD761FF51; Thu, 12 Aug 2021 14:39:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_rsa; t=1628779199; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Uth4sMmc8x3mZcOsnTABS6mbFJnbEE+lWYWSXA8XzxE=; b=nc4A932V9a04ae2aE5BsFdOZnrYVNbfuJXCj+FJpBZn+xbG3LkTt34AzePE6OaaJyE3WMQ thKGsdu6lGxAeHQSq42D1h/amLZp1/VuRbfSZESWPzJxls5A5mIdmT6Et76qwUJOH4vDLf /j32JsTvh44gZT3to6O003PwUc/yNH8= DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=suse.cz; s=susede2_ed25519; t=1628779199; h=from:from:reply-to:date:date:message-id:message-id:to:to:cc:cc: mime-version:mime-version:content-type:content-type: in-reply-to:in-reply-to:references:references; bh=Uth4sMmc8x3mZcOsnTABS6mbFJnbEE+lWYWSXA8XzxE=; b=x9mWKiMOprAd/5hsGf9HgNZijRqNmJUX6lk4l85mPJzUr4bbM9LNWCeuheSP6mR8nq8F/t FjnH2ZlqirQJCGDw== Received: from imap1.suse-dmz.suse.de (imap1.suse-dmz.suse.de [192.168.254.73]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-521) server-digest SHA512) (No client certificate requested) by imap1.suse-dmz.suse.de (Postfix) with ESMTPS id 1BDD613846; Thu, 12 Aug 2021 14:39:59 +0000 (UTC) Received: from dovecot-director2.suse.de ([192.168.254.65]) by imap1.suse-dmz.suse.de with ESMTPSA id 3ha3Bb8yFWHEZgAAGKfGzw (envelope-from ); Thu, 12 Aug 2021 14:39:59 +0000 Subject: Re: [PATCH] i386: support micro-levels in target{,_clone} attrs [PR101696] To: "H.J. Lu" Cc: GCC Patches References: From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Message-ID: <09e4b2bd-2055-f0f8-e339-b1aeeff5176a@suse.cz> Date: Thu, 12 Aug 2021 16:39:58 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.12.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------3448499906261912CE60A0BC" Content-Language: en-US X-Spam-Status: No, score=-10.7 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, NICE_REPLY_A, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 12 Aug 2021 14:40:11 -0000 This is a multi-part message in MIME format. --------------3448499906261912CE60A0BC Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit On 8/12/21 4:25 PM, H.J. Lu wrote: > Please send out the v2 patch with the enclosed patch. I added some tests. Thanks, there's patch which includes your changes. Martin --------------3448499906261912CE60A0BC Content-Type: text/x-patch; charset=UTF-8; name="0001-i386-support-micro-levels-in-target-_clone-attrs-PR1.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-i386-support-micro-levels-in-target-_clone-attrs-PR1.pa"; filename*1="tch" >From 22ab27eab643d99addd00c11f62eca891e11ac08 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Thu, 12 Aug 2021 15:20:43 +0200 Subject: [PATCH] i386: support micro-levels in target{,_clone} attrs [PR101696] As mentioned in the PR, we do miss supports target micro-architectures in target and target_clone attribute. While the levels x86-64 x86-64-v2 x86-64-v3 x86-64-v4 are supported values by -march option, they are actually only aliases for k8 CPU. That said, they are more closer to __builtin_cpu_supports function and we decided to implement it there. PR target/101696 gcc/ChangeLog: * common/config/i386/cpuinfo.h (cpu_indicator_init): Add support for x86-64 micro levels for __builtin_cpu_supports. * common/config/i386/i386-cpuinfo.h (enum feature_priority): Add priorities for the micro-arch levels. (enum processor_features): Add new features. * common/config/i386/i386-isas.h: Add micro-arch features. * config/i386/i386-builtins.c (get_builtin_code_for_version): Support the micro-arch levels by callsing __builtin_cpu_supports. * doc/extend.texi: Document that the levels are support by __builtin_cpu_supports. gcc/testsuite/ChangeLog: * g++.target/i386/mv30.C: New test. * gcc.target/i386/mvc16.c: New test. * gcc.target/i386/builtin_target.c (CHECK___builtin_cpu_supports): New. Co-Authored-By: H.J. Lu --- gcc/common/config/i386/cpuinfo.h | 48 ++++++++++++++++++ gcc/common/config/i386/i386-cpuinfo.h | 8 +++ gcc/common/config/i386/i386-isas.h | 4 ++ gcc/config/i386/i386-builtins.c | 22 ++++++-- gcc/doc/extend.texi | 12 +++++ gcc/testsuite/g++.target/i386/mv30.C | 50 +++++++++++++++++++ .../gcc.target/i386/builtin_target.c | 2 + gcc/testsuite/gcc.target/i386/mvc16.c | 15 ++++++ 8 files changed, 158 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.target/i386/mv30.C create mode 100644 gcc/testsuite/gcc.target/i386/mvc16.c diff --git a/gcc/common/config/i386/cpuinfo.h b/gcc/common/config/i386/cpuinfo.h index 458f41de776..89158597c1f 100644 --- a/gcc/common/config/i386/cpuinfo.h +++ b/gcc/common/config/i386/cpuinfo.h @@ -46,6 +46,10 @@ struct __processor_model2 # define CHECK___builtin_cpu_is(cpu) #endif +#ifndef CHECK___builtin_cpu_supports +# define CHECK___builtin_cpu_supports(isa) +#endif + /* Return non-zero if the processor has feature F. */ static inline int @@ -931,6 +935,50 @@ cpu_indicator_init (struct __processor_model *cpu_model, else cpu_model->__cpu_vendor = VENDOR_OTHER; + if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_LM) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE2)) + { + CHECK___builtin_cpu_supports ("x86-64"); + set_cpu_feature (cpu_model, cpu_features2, + FEATURE_X86_64_BASELINE); + if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_CMPXCHG16B) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_POPCNT) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_LAHF_LM) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_SSE4_2)) + { + CHECK___builtin_cpu_supports ("x86-64-v2"); + set_cpu_feature (cpu_model, cpu_features2, + FEATURE_X86_64_V2); + if (has_cpu_feature (cpu_model, cpu_features2, FEATURE_AVX2) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_BMI2) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_F16C) + && has_cpu_feature (cpu_model, cpu_features2, FEATURE_FMA) + && has_cpu_feature (cpu_model, cpu_features2, + FEATURE_LZCNT) + && has_cpu_feature (cpu_model, cpu_features2, + FEATURE_MOVBE)) + { + CHECK___builtin_cpu_supports ("x86-64-v3"); + set_cpu_feature (cpu_model, cpu_features2, + FEATURE_X86_64_V3); + if (has_cpu_feature (cpu_model, cpu_features2, + FEATURE_AVX512BW) + && has_cpu_feature (cpu_model, cpu_features2, + FEATURE_AVX512CD) + && has_cpu_feature (cpu_model, cpu_features2, + FEATURE_AVX512DQ) + && has_cpu_feature (cpu_model, cpu_features2, + FEATURE_AVX512VL)) + { + CHECK___builtin_cpu_supports ("x86-64-v4"); + set_cpu_feature (cpu_model, cpu_features2, + FEATURE_X86_64_V4); + } + } + } + } + gcc_assert (cpu_model->__cpu_vendor < VENDOR_MAX); gcc_assert (cpu_model->__cpu_type < CPU_TYPE_MAX); gcc_assert (cpu_model->__cpu_subtype < CPU_SUBTYPE_MAX); diff --git a/gcc/common/config/i386/i386-cpuinfo.h b/gcc/common/config/i386/i386-cpuinfo.h index e68dd656046..1b1846d59b8 100644 --- a/gcc/common/config/i386/i386-cpuinfo.h +++ b/gcc/common/config/i386/i386-cpuinfo.h @@ -102,6 +102,7 @@ enum feature_priority P_MMX, P_SSE, P_SSE2, + P_X86_64_BASELINE, P_SSE3, P_SSSE3, P_PROC_SSSE3, @@ -111,6 +112,7 @@ enum feature_priority P_SSE4_2, P_PROC_SSE4_2, P_POPCNT, + P_X86_64_V2, P_AES, P_PCLMUL, P_AVX, @@ -125,8 +127,10 @@ enum feature_priority P_BMI2, P_AVX2, P_PROC_AVX2, + P_X86_64_V3, P_AVX512F, P_PROC_AVX512F, + P_X86_64_V4, P_PROC_DYNAMIC }; @@ -228,6 +232,10 @@ enum processor_features FEATURE_AESKLE, FEATURE_WIDEKL, FEATURE_AVXVNNI, + FEATURE_X86_64_BASELINE, + FEATURE_X86_64_V2, + FEATURE_X86_64_V3, + FEATURE_X86_64_V4, CPU_FEATURE_MAX }; diff --git a/gcc/common/config/i386/i386-isas.h b/gcc/common/config/i386/i386-isas.h index 898c18f3dda..cd9523b8fbc 100644 --- a/gcc/common/config/i386/i386-isas.h +++ b/gcc/common/config/i386/i386-isas.h @@ -169,4 +169,8 @@ ISA_NAMES_TABLE_START ISA_NAMES_TABLE_ENTRY("aeskle", FEATURE_AESKLE, P_NONE, NULL) ISA_NAMES_TABLE_ENTRY("widekl", FEATURE_WIDEKL, P_NONE, "-mwidekl") ISA_NAMES_TABLE_ENTRY("avxvnni", FEATURE_AVXVNNI, P_NONE, "-mavxvnni") + ISA_NAMES_TABLE_ENTRY("x86-64", FEATURE_X86_64_BASELINE, P_NONE, NULL) + ISA_NAMES_TABLE_ENTRY("x86-64-v2", FEATURE_X86_64_V2, P_NONE, NULL) + ISA_NAMES_TABLE_ENTRY("x86-64-v3", FEATURE_X86_64_V3, P_NONE, NULL) + ISA_NAMES_TABLE_ENTRY("x86-64-v4", FEATURE_X86_64_V4, P_NONE, NULL) ISA_NAMES_TABLE_END diff --git a/gcc/config/i386/i386-builtins.c b/gcc/config/i386/i386-builtins.c index 204e2903126..492873bb076 100644 --- a/gcc/config/i386/i386-builtins.c +++ b/gcc/config/i386/i386-builtins.c @@ -1904,8 +1904,24 @@ get_builtin_code_for_version (tree decl, tree *predicate_list) return 0; new_target = TREE_TARGET_OPTION (target_node); gcc_assert (new_target); - - if (new_target->arch_specified && new_target->arch > 0) + enum ix86_builtins builtin_fn = IX86_BUILTIN_CPU_IS; + + /* Special case x86-64 micro-level architectures. */ + const char *arch_name = attrs_str + strlen ("arch="); + if (startswith (arch_name, "x86-64")) + { + arg_str = arch_name; + builtin_fn = IX86_BUILTIN_CPU_SUPPORTS; + if (strcmp (arch_name, "x86-64") == 0) + priority = P_X86_64_BASELINE; + else if (strcmp (arch_name, "x86-64-v2") == 0) + priority = P_X86_64_V2; + else if (strcmp (arch_name, "x86-64-v3") == 0) + priority = P_X86_64_V3; + else if (strcmp (arch_name, "x86-64-v4") == 0) + priority = P_X86_64_V4; + } + else if (new_target->arch_specified && new_target->arch > 0) for (i = 0; i < pta_size; i++) if (processor_alias_table[i].processor == new_target->arch) { @@ -1975,7 +1991,7 @@ get_builtin_code_for_version (tree decl, tree *predicate_list) if (predicate_list) { - predicate_decl = ix86_builtins [(int) IX86_BUILTIN_CPU_IS]; + predicate_decl = ix86_builtins [(int) builtin_fn]; /* For a C string literal the length includes the trailing NULL. */ predicate_arg = build_string_literal (strlen (arg_str) + 1, arg_str); predicate_chain = tree_cons (predicate_decl, predicate_arg, diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index 49df8e6dc38..d2c695f8dab 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -21644,6 +21644,18 @@ AMD Family 19h CPU. @item znver3 AMD Family 19h Zen version 3. + +@item x86-64 +Baseline x86-64 microarchitecture level (as defined in x86-64 psABI). + +@item x86-64-v2 +x86-64-v2 microarchitecture level. + +@item x86-64-v3 +x86-64-v3 microarchitecture level. + +@item x86-64-v4 +x86-64-v4 microarchitecture level. @end table Here is an example: diff --git a/gcc/testsuite/g++.target/i386/mv30.C b/gcc/testsuite/g++.target/i386/mv30.C new file mode 100644 index 00000000000..b4947f0b481 --- /dev/null +++ b/gcc/testsuite/g++.target/i386/mv30.C @@ -0,0 +1,50 @@ +// PR target/101696 +// Test that dispatching can choose the right multiversion +// for x86-64 microarchitecture levels. + +// { dg-do run } +// { dg-require-ifunc "" } +// { dg-options "-O2" } + +#include + +int __attribute__ ((target("default"))) +foo () +{ + return 0; +} + +int __attribute__ ((target("arch=x86-64"))) foo () { + return 1; +} + +int __attribute__ ((target("arch=x86-64-v2"))) foo () { + return 2; +} + +int __attribute__ ((target("arch=x86-64-v3"))) foo () { + return 3; +} + +int __attribute__ ((target("arch=x86-64-v4"))) foo () { + return 4; +} + + +int main () +{ + int val = foo (); + + if (__builtin_cpu_supports ("x86-64-v4")) + assert (val == 4); + else if (__builtin_cpu_supports ("x86-64-v3")) + assert (val == 3); + else if (__builtin_cpu_supports ("x86-64-v2")) + assert (val == 2); + else if (__builtin_cpu_supports ("x86-64")) + assert (val == 1); + else + assert (val == 0); + + return 0; +} diff --git a/gcc/testsuite/gcc.target/i386/builtin_target.c b/gcc/testsuite/gcc.target/i386/builtin_target.c index aa9680544d8..3e7505a8c3a 100644 --- a/gcc/testsuite/gcc.target/i386/builtin_target.c +++ b/gcc/testsuite/gcc.target/i386/builtin_target.c @@ -10,6 +10,8 @@ #include #include "cpuid.h" #define CHECK___builtin_cpu_is(cpu) assert (__builtin_cpu_is (cpu)) +#define CHECK___builtin_cpu_supports(isa) \ + assert (__builtin_cpu_supports (isa)) #define gcc_assert(a) assert (a) #define gcc_unreachable() abort () #define inline diff --git a/gcc/testsuite/gcc.target/i386/mvc16.c b/gcc/testsuite/gcc.target/i386/mvc16.c new file mode 100644 index 00000000000..def6581f7e7 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/mvc16.c @@ -0,0 +1,15 @@ +/* { dg-do run } */ +/* { dg-require-ifunc "" } */ + +__attribute__((target_clones("arch=x86-64", "arch=x86-64-v2", "arch=x86-64-v3", "arch=x86-64-v4", "default"))) +int +foo () +{ + return 0; +} + +int +main () +{ + return foo (); +} -- 2.32.0 --------------3448499906261912CE60A0BC--