public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: "J.W. Jagersma" <jwjagersma@gmail.com>
To: gcc-patches@gcc.gnu.org
Cc: "J.W. Jagersma" <jwjagersma@gmail.com>
Subject: [PATCH] i386: Allow setting target attribute from conditional expression
Date: Mon, 17 Oct 2022 16:44:37 +0200	[thread overview]
Message-ID: <20221017144437.157424-1-jwjagersma@gmail.com> (raw)

Recently I tried to set a function's target attribute conditionally
based on template parameters, eg.:

    template<bool enable_sse>
    [[gnu::target (enable_sse ? "sse" : "")]]
    void func () { /* ... */ }

I then discovered that this is currently not possible.  This small patch
resolves that.

A possible alternative solution is to do this globally, eg. in
decl_attributes.  But doing so would trigger empty-string warnings from
handle_target_attribute, and I don't know how safe it is to remove that.
There likely isn't much use for this with other attributes, anyway.

2022-10-17  Jan W. Jagersma  <jwjagersma@gmail.com>

gcc/ChangeLog:
	* config/i386/i386-options.cc
	(ix86_valid_target_attribute_inner_p):  Dereference args string
	from ADDR_EXPR.

gcc/testsuite/ChangeLog:
	* g++.target/i386/target-attr-conditional.C: New test.
---
 gcc/config/i386/i386-options.cc               |  9 ++++
 .../g++.target/i386/target-attr-conditional.C | 53 +++++++++++++++++++
 2 files changed, 62 insertions(+)
 create mode 100644 gcc/testsuite/g++.target/i386/target-attr-conditional.C

diff --git a/gcc/config/i386/i386-options.cc b/gcc/config/i386/i386-options.cc
index acb2291e70f..915f3b0c1f0 100644
--- a/gcc/config/i386/i386-options.cc
+++ b/gcc/config/i386/i386-options.cc
@@ -1123,6 +1123,15 @@ ix86_valid_target_attribute_inner_p (tree fndecl, tree args, char *p_strings[],
     = fndecl == NULL ? UNKNOWN_LOCATION : DECL_SOURCE_LOCATION (fndecl);
   const char *attr_name = target_clone_attr ? "target_clone" : "target";
 
+  args = tree_strip_nop_conversions (args);
+
+  if (TREE_CODE (args) == ADDR_EXPR)
+    {
+      /* Attribute string is given by a constexpr function or conditional
+	 expression.  Dereference ADDR_EXPR, operand should be a STRING_CST.  */
+      args = TREE_OPERAND (args, 0);
+    }
+
   /* If this is a list, recurse to get the options.  */
   if (TREE_CODE (args) == TREE_LIST)
     {
diff --git a/gcc/testsuite/g++.target/i386/target-attr-conditional.C b/gcc/testsuite/g++.target/i386/target-attr-conditional.C
new file mode 100644
index 00000000000..2d418ed90bf
--- /dev/null
+++ b/gcc/testsuite/g++.target/i386/target-attr-conditional.C
@@ -0,0 +1,53 @@
+/* { dg-do compile } */
+/* { dg-options "-Wno-psabi -m32 -march=i386 -std=c++20" } */
+
+#pragma GCC push_options
+#pragma GCC target("sse")
+
+typedef int __m64 __attribute__ ((__vector_size__ (8), __may_alias__));
+typedef short __v4hi __attribute__ ((__vector_size__ (8)));
+
+extern __inline int __attribute__((__gnu_inline__, __always_inline__, __artificial__))
+_mm_extract_pi16 (__m64 const __A, int const __N)
+{
+  return (unsigned short) __builtin_ia32_vec_ext_v4hi ((__v4hi)__A, __N);
+}
+
+#pragma GCC pop_options
+
+consteval const char*
+target_string (bool enable_sse)
+{
+  return enable_sse ? "sse" : "";
+}
+
+// Via consteval function
+template<bool enable_sse>
+[[gnu::target (target_string (enable_sse))]]
+int
+extract1 (__m64 const src)
+{
+  if constexpr (enable_sse)
+    return _mm_extract_pi16 (src, 0);
+  else
+    return reinterpret_cast<__v4hi>(src)[1];
+}
+
+// Via ternary operator
+template<bool enable_sse>
+[[gnu::target (enable_sse ? "sse" : "")]]
+int
+extract2 (__m64 const src)
+{
+  if constexpr (enable_sse)
+    return _mm_extract_pi16 (src, 2);
+  else
+    return reinterpret_cast<__v4hi>(src)[3];
+}
+
+int
+test (__m64 const src)
+{
+  return extract1<true>(src) + extract1<false>(src)
+       + extract2<true>(src) + extract2<false>(src);
+}
-- 
2.35.1


             reply	other threads:[~2022-10-17 14:45 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-17 14:44 J.W. Jagersma [this message]
2022-11-08 21:15 ` [PING][PATCH] " J.W. Jagersma

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221017144437.157424-1-jwjagersma@gmail.com \
    --to=jwjagersma@gmail.com \
    --cc=gcc-patches@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).