From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17558 invoked by alias); 1 Sep 2017 11:13:02 -0000 Mailing-List: contact libstdc++-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libstdc++-owner@gcc.gnu.org Received: (qmail 17537 invoked by uid 89); 1 Sep 2017 11:13:01 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.9 required=5.0 tests=BAYES_00,GIT_PATCH_2,GIT_PATCH_3,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=ham version=3.3.2 spammy=25696 X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 01 Sep 2017 11:12:58 +0000 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C0FBF13A60; Fri, 1 Sep 2017 11:12:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com C0FBF13A60 Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx05.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=jakub@redhat.com Received: from tucnak.zalov.cz (ovpn-116-33.ams2.redhat.com [10.36.116.33]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 748FC11A2B4; Fri, 1 Sep 2017 11:12:54 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.15.2/8.15.2) with ESMTP id v81BCpdw007268; Fri, 1 Sep 2017 13:12:52 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.15.2/8.15.2/Submit) id v81BCnIJ007267; Fri, 1 Sep 2017 13:12:49 +0200 Date: Fri, 01 Sep 2017 11:13:00 -0000 From: Jakub Jelinek To: Jason Merrill Cc: "Joseph S. Myers" , Marek Polacek , Jonathan Wakely , gcc-patches@gcc.gnu.org, libstdc++@gcc.gnu.org Subject: Re: [PATCH] Improve -Ofast vectorization of std::sin etc. (PR libstdc++/81706) Message-ID: <20170901111249.GD2323@tucnak> Reply-To: Jakub Jelinek References: <20170807090825.GK2123@tucnak> <20170807152742.GM2123@tucnak> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20170807152742.GM2123@tucnak> User-Agent: Mutt/1.7.1 (2016-10-04) X-SW-Source: 2017-09/txt/msg00001.txt.bz2 On Mon, Aug 07, 2017 at 05:27:42PM +0200, Jakub Jelinek wrote: > > This should really be a separate function. Perhaps "merge_one_attribute"? > > If it is outlined without the first 7 lines, i.e. just the body of if (b), > then it could be duplicate_one_attribute (tree *, tree, const char *); > called like if (b) duplicate_one_attribute (&DECL_ATTRIBUTES (b), s, "omp declare simd"); > If it is duplicated as whole, it should be called > duplicate_one_attr_to_builtin or something similar. > In any case, it could be in tree.c or attribs.c. > > The primary question is if we want this behavior, or if we should go the > libstdc++ patch routine (and for Jonathan the question is if he knows > why __builtin_XXXf has been used there rather than the ::XXXf). Here is updated patch that commonizes big part of that into duplicate_one_attribute. Bootstrapped/regtested on x86_64-linux and i686-linux. The question stands, do we want to go this way or using some libstdc++ solution? 2017-09-01 Jakub Jelinek PR libstdc++/81706 * attribs.c (attribute_value_equal): Use omp_declare_simd_clauses_equal for comparison of OMP_CLAUSEs regardless of flag_openmp{,_simd}. (duplicate_one_attribute): New function. * attribs.h (duplicate_one_attribute): New declaration. * c-decl.c (merge_decls): Copy "omp declare simd" attributes from newdecl to corresponding __builtin_ if any. * decl.c (duplicate_decls): Copy "omp declare simd" attributes from newdecl to corresponding __builtin_ if any. * gcc.target/i386/pr81706.c: New test. * g++.dg/ext/pr81706.C: New test. --- gcc/attribs.c.jj 2017-09-01 09:25:37.000000000 +0200 +++ gcc/attribs.c 2017-09-01 09:54:28.581146071 +0200 @@ -1116,9 +1116,9 @@ attribute_value_equal (const_tree attr1, TREE_VALUE (attr2)) == 1); } - if ((flag_openmp || flag_openmp_simd) - && TREE_VALUE (attr1) && TREE_VALUE (attr2) + if (TREE_VALUE (attr1) && TREE_CODE (TREE_VALUE (attr1)) == OMP_CLAUSE + && TREE_VALUE (attr2) && TREE_CODE (TREE_VALUE (attr2)) == OMP_CLAUSE) return omp_declare_simd_clauses_equal (TREE_VALUE (attr1), TREE_VALUE (attr2)); @@ -1310,6 +1310,31 @@ merge_decl_attributes (tree olddecl, tre DECL_ATTRIBUTES (newdecl)); } +/* Duplicate all attributes with name NAME in ATTR list to *ATTRS if + they are missing there. */ + +void +duplicate_one_attribute (tree *attrs, tree attr, const char *name) +{ + if (!attr) + return; + tree a = lookup_attribute (name, *attrs); + while (attr) + { + tree a2; + for (a2 = a; a2; a2 = lookup_attribute (name, TREE_CHAIN (a2))) + if (attribute_value_equal (attr, a2)) + break; + if (!a2) + { + a2 = copy_node (attr); + TREE_CHAIN (a2) = *attrs; + *attrs = a2; + } + attr = lookup_attribute (name, TREE_CHAIN (attr)); + } +} + #if TARGET_DLLIMPORT_DECL_ATTRIBUTES /* Specialization of merge_decl_attributes for various Windows targets. --- gcc/attribs.h.jj 2017-09-01 09:25:37.000000000 +0200 +++ gcc/attribs.h 2017-09-01 09:54:57.366809765 +0200 @@ -77,6 +77,11 @@ extern tree remove_attribute (const char extern tree merge_attributes (tree, tree); +/* Duplicate all attributes with name NAME in ATTR list to *ATTRS if + they are missing there. */ + +extern void duplicate_one_attribute (tree *, tree, const char *); + /* Given two Windows decl attributes lists, possibly including dllimport, return a list of their union . */ extern tree merge_dllimport_decl_attributes (tree, tree); --- gcc/c/c-decl.c.jj 2017-09-01 09:25:40.707410605 +0200 +++ gcc/c/c-decl.c 2017-09-01 09:49:57.419314085 +0200 @@ -2569,6 +2569,17 @@ merge_decls (tree newdecl, tree olddecl, set_builtin_decl_declared_p (fncode, true); break; } + + tree s = lookup_attribute ("omp declare simd", + DECL_ATTRIBUTES (newdecl)); + if (s) + { + tree b + = builtin_decl_explicit (DECL_FUNCTION_CODE (newdecl)); + if (b) + duplicate_one_attribute (&DECL_ATTRIBUTES (b), s, + "omp declare simd"); + } } } else --- gcc/cp/decl.c.jj 2017-09-01 09:26:24.748892739 +0200 +++ gcc/cp/decl.c 2017-09-01 09:55:52.940160495 +0200 @@ -2470,6 +2470,16 @@ next_arg:; break; } } + + tree s = lookup_attribute ("omp declare simd", + DECL_ATTRIBUTES (newdecl)); + if (s) + { + tree b = builtin_decl_explicit (DECL_FUNCTION_CODE (newdecl)); + if (b) + duplicate_one_attribute (&DECL_ATTRIBUTES (b), s, + "omp declare simd"); + } } if (new_defines_function) /* If defining a function declared with other language --- gcc/testsuite/gcc.target/i386/pr81706.c.jj 2017-09-01 09:40:46.345761553 +0200 +++ gcc/testsuite/gcc.target/i386/pr81706.c 2017-09-01 09:40:46.345761553 +0200 @@ -0,0 +1,32 @@ +/* PR libstdc++/81706 */ +/* { dg-do compile } */ +/* { dg-options "-O3 -mavx2 -mno-avx512f" } */ +/* { dg-final { scan-assembler "call\[^\n\r]_ZGVdN4v_cos" } } */ +/* { dg-final { scan-assembler "call\[^\n\r]_ZGVdN4v_sin" } } */ + +#ifdef __cplusplus +extern "C" { +#endif +extern double cos (double) __attribute__ ((nothrow, leaf, simd ("notinbranch"))); +extern double sin (double) __attribute__ ((nothrow, leaf, simd ("notinbranch"))); +#ifdef __cplusplus +} +#endif +double p[1024] = { 1.0 }; +double q[1024] = { 1.0 }; + +void +foo (void) +{ + int i; + for (i = 0; i < 1024; i++) + p[i] = cos (q[i]); +} + +void +bar (void) +{ + int i; + for (i = 0; i < 1024; i++) + p[i] = __builtin_sin (q[i]); +} --- gcc/testsuite/g++.dg/ext/pr81706.C.jj 2017-09-01 09:40:46.345761553 +0200 +++ gcc/testsuite/g++.dg/ext/pr81706.C 2017-09-01 09:40:46.345761553 +0200 @@ -0,0 +1,32 @@ +// PR libstdc++/81706 +// { dg-do compile { target i?86-*-* x86_64-*-* } } +// { dg-options "-O3 -mavx2 -mno-avx512f" } +// { dg-final { scan-assembler "call\[^\n\r]_ZGVdN4v_cos" } } +// { dg-final { scan-assembler "call\[^\n\r]_ZGVdN4v_sin" } } + +#ifdef __cplusplus +extern "C" { +#endif +extern double cos (double) __attribute__ ((nothrow, leaf, simd ("notinbranch"))); +extern double sin (double) __attribute__ ((nothrow, leaf, simd ("notinbranch"))); +#ifdef __cplusplus +} +#endif +double p[1024] = { 1.0 }; +double q[1024] = { 1.0 }; + +void +foo (void) +{ + int i; + for (i = 0; i < 1024; i++) + p[i] = cos (q[i]); +} + +void +bar (void) +{ + int i; + for (i = 0; i < 1024; i++) + p[i] = __builtin_sin (q[i]); +} Jakub