This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: RFA (make_dispatcher_decl): PATCH for c++/83911, ICE with multiversioned constructor
- From: Jason Merrill <jason at redhat dot com>
- Cc: gcc-patches List <gcc-patches at gcc dot gnu dot org>
- Date: Fri, 16 Mar 2018 08:38:10 -0400
- Subject: Re: RFA (make_dispatcher_decl): PATCH for c++/83911, ICE with multiversioned constructor
- References: <CADzB+2mJ9yJZ83o5_KhSFkikbqoUrqsjutVcy=+7eToDVkg2_Q@mail.gmail.com> <CADzB+2kKWMi9NpBq_RKWGqW1WPjg3c-gHY8UWg0TDDp=TAgQPw@mail.gmail.com> <CAFiYyc0Z5_iov3Q=qWazx0FtQmC-ZArRMz5TiFMG2m6KGvG2BQ@mail.gmail.com>
On Thu, Mar 15, 2018 at 4:50 AM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Wed, Mar 14, 2018 at 8:57 PM, Jason Merrill <jason@redhat.com> wrote:
>> Ping
>>
>> On Fri, Mar 2, 2018 at 1:23 PM, Jason Merrill <jason@redhat.com> wrote:
>>> As I mentioned in the PR, the problem here is that we're replacing a
>>> constructor with a dispatcher function which doesn't look much like a
>>> constructor. This patch adjusts make_dispatcher_decl to make it look
>>> more like the functions it dispatches to, but other things are certain
>>> to break for similar reasons down the road. A proper solution should
>>> be more transparent, like thunks.
>>>
>>> Tested x86_64-pc-linux-gnu. Does this seem worth applying to fix the
>>> regression?
>
> The patch looks reasonable to me, you probably know best whether
> the cp/ parts are risky or not ;)
>
> So - OK from my POV.
>
> And yes, thunks may be a better representation for the dispatcher.
It occurred to me that I could handle this more locally by deferring
the function substitution until genericization time, so this is what
I'm checking in:
commit 05dda93e56e02859c65f93bd541dc7793bc7305c
Author: Jason Merrill <jason@redhat.com>
Date: Fri Feb 16 16:53:47 2018 -0500
PR c++/83911 - ICE with multiversioned constructor.
* cp-gimplify.c (cp_genericize_r): Replace versioned function with
dispatchere here.
* call.c (build_over_call): Not here.
PR c++/83911 - ICE with multiversioned constructor.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 45c22aaa312..67438ff2e94 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -8204,23 +8204,6 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
}
}
- /* For calls to a multi-versioned function, overload resolution
- returns the function with the highest target priority, that is,
- the version that will checked for dispatching first. If this
- version is inlinable, a direct call to this version can be made
- otherwise the call should go through the dispatcher. */
-
- if (DECL_FUNCTION_VERSIONED (fn)
- && (current_function_decl == NULL
- || !targetm.target_option.can_inline_p (current_function_decl, fn)))
- {
- fn = get_function_version_dispatcher (fn);
- if (fn == NULL)
- return NULL;
- if (!already_used)
- mark_versions_used (fn);
- }
-
if (!already_used
&& !mark_used (fn, complain))
return error_mark_node;
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 0ddd435454c..653d1dcee26 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -1513,6 +1513,29 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
== REFERENCE_TYPE))
*walk_subtrees = 0;
}
+ /* Fall through. */
+ case AGGR_INIT_EXPR:
+ /* For calls to a multi-versioned function, overload resolution
+ returns the function with the highest target priority, that is,
+ the version that will checked for dispatching first. If this
+ version is inlinable, a direct call to this version can be made
+ otherwise the call should go through the dispatcher. */
+ {
+ tree fn = cp_get_callee_fndecl (stmt);
+ if (fn && DECL_FUNCTION_VERSIONED (fn)
+ && (current_function_decl == NULL
+ || !targetm.target_option.can_inline_p (current_function_decl,
+ fn)))
+ if (tree dis = get_function_version_dispatcher (fn))
+ {
+ mark_versions_used (dis);
+ dis = build_address (dis);
+ if (TREE_CODE (stmt) == CALL_EXPR)
+ CALL_EXPR_FN (stmt) = dis;
+ else
+ AGGR_INIT_EXPR_FN (stmt) = dis;
+ }
+ }
break;
default:
diff --git a/gcc/testsuite/g++.dg/ext/mv27.C b/gcc/testsuite/g++.dg/ext/mv27.C
new file mode 100644
index 00000000000..443a54be765
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/mv27.C
@@ -0,0 +1,18 @@
+// PR c++/83911
+// { dg-do compile { target i?86-*-* x86_64-*-* } }
+// { dg-require-ifunc "" }
+
+class SimdFloat
+{
+public:
+ __attribute__ ((target ("default")))
+ SimdFloat(float x) {}
+
+ __attribute__ ((target ("avx2")))
+ SimdFloat(float x) {}
+};
+
+SimdFloat foo()
+{
+ return 1;
+}