Message ID | 1147b9d2-91eb-508e-d70b-f8307aa1bc93@suse.cz |
---|---|
State | New |
Headers | show |
Series | Backports for GCC 7 branch | expand |
On 09/15/2017 10:10 AM, Martin Liška wrote: > Hello. > > I'm going to install following backports. Last patch fixes wrongly backported patch > in gcc/gimple-ssa-strength-reduction.c. > > Patches can bootstrap on ppc64le-redhat-linux and survives regression tests. > > Martin > Forgot to add one patch. Martin From 98102386fdf336139f9eafd40dace4e72fa27115 Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Tue, 29 Aug 2017 07:46:10 +0000 Subject: Backport r251400 gcc/ChangeLog: 2017-08-29 Martin Liska <mliska@suse.cz> PR other/39851 * gcc.c (driver_handle_option): Add new argument. * opts-common.c (handle_option): Pass target_option_override_hook. * opts-global.c (lang_handle_option): Add new option. (set_default_handlers): Add new argument. (decode_options): Likewise. * opts.c (target_handle_option): Likewise. (common_handle_option): Call target_option_override_hook. * opts.h (struct cl_option_handler_func): Add hook for target option override. (struct cl_option_handlers): Likewise. (set_default_handlers): Add new argument. (decode_options): Likewise. (common_handle_option): Likewise. (target_handle_option): Likewise. * toplev.c (toplev::main): Pass targetm.target_option.override hook. gcc/c-family/ChangeLog: 2017-08-29 Martin Liska <mliska@suse.cz> PR other/39851 * c-common.c (parse_optimize_options): Add argument to function call. * c-pragma.c (handle_pragma_diagnostic): Likewise. --- diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 156c89d0294..f4f2819aece 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -5497,7 +5497,7 @@ parse_optimize_options (tree args, bool attr_p) /* And apply them. */ decode_options (&global_options, &global_options_set, decoded_options, decoded_options_count, - input_location, global_dc); + input_location, global_dc, NULL); targetm.override_options_after_change(); diff --git a/gcc/c-family/c-pragma.c b/gcc/c-family/c-pragma.c index 48b02b88bb5..3b49aefc6ff 100644 --- a/gcc/c-family/c-pragma.c +++ b/gcc/c-family/c-pragma.c @@ -815,7 +815,7 @@ handle_pragma_diagnostic(cpp_reader *ARG_UNUSED(dummy)) } struct cl_option_handlers handlers; - set_default_handlers (&handlers); + set_default_handlers (&handlers, NULL); const char *arg = NULL; if (cl_options[option_index].flags & CL_JOINED) arg = option_string + 1 + cl_options[option_index].opt_len; diff --git a/gcc/gcc.c b/gcc/gcc.c index 6fa523140e7..f1aad1f23b6 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -3769,7 +3769,8 @@ driver_handle_option (struct gcc_options *opts, unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, location_t loc, const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED, - diagnostic_context *dc) + diagnostic_context *dc, + void (*) (void)) { size_t opt_index = decoded->opt_index; const char *arg = decoded->arg; diff --git a/gcc/opts-common.c b/gcc/opts-common.c index 0cab42a021c..d7568145768 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -993,7 +993,8 @@ handle_option (struct gcc_options *opts, { if (!handlers->handlers[i].handler (opts, opts_set, decoded, lang_mask, kind, loc, - handlers, dc)) + handlers, dc, + handlers->target_option_override_hook)) return false; } diff --git a/gcc/opts-global.c b/gcc/opts-global.c index fc55512e554..343dbd3ac2c 100644 --- a/gcc/opts-global.c +++ b/gcc/opts-global.c @@ -169,7 +169,8 @@ lang_handle_option (struct gcc_options *opts, unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, location_t loc, const struct cl_option_handlers *handlers, - diagnostic_context *dc) + diagnostic_context *dc, + void (*) (void)) { gcc_assert (opts == &global_options); gcc_assert (opts_set == &global_options_set); @@ -269,10 +270,12 @@ decode_cmdline_options_to_array_default_mask (unsigned int argc, /* Set *HANDLERS to the default set of option handlers for use in the compilers proper (not the driver). */ void -set_default_handlers (struct cl_option_handlers *handlers) +set_default_handlers (struct cl_option_handlers *handlers, + void (*target_option_override_hook) (void)) { handlers->unknown_option_callback = unknown_option_callback; handlers->wrong_lang_callback = complain_wrong_lang; + handlers->target_option_override_hook = target_option_override_hook; handlers->num_handlers = 3; handlers->handlers[0].handler = lang_handle_option; handlers->handlers[0].mask = initial_lang_mask; @@ -290,7 +293,8 @@ void decode_options (struct gcc_options *opts, struct gcc_options *opts_set, struct cl_decoded_option *decoded_options, unsigned int decoded_options_count, - location_t loc, diagnostic_context *dc) + location_t loc, diagnostic_context *dc, + void (*target_option_override_hook) (void)) { struct cl_option_handlers handlers; @@ -298,7 +302,7 @@ decode_options (struct gcc_options *opts, struct gcc_options *opts_set, lang_mask = initial_lang_mask; - set_default_handlers (&handlers); + set_default_handlers (&handlers, target_option_override_hook); default_options_optimization (opts, opts_set, decoded_options, decoded_options_count, diff --git a/gcc/opts.c b/gcc/opts.c index 19e8c7fb7d4..a7f926b587f 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -217,7 +217,7 @@ target_handle_option (struct gcc_options *opts, unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, location_t loc, const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED, - diagnostic_context *dc) + diagnostic_context *dc, void (*) (void)) { gcc_assert (dc == global_dc); gcc_assert (kind == DK_UNSPECIFIED); @@ -1716,7 +1716,8 @@ common_handle_option (struct gcc_options *opts, unsigned int lang_mask, int kind ATTRIBUTE_UNUSED, location_t loc, const struct cl_option_handlers *handlers, - diagnostic_context *dc) + diagnostic_context *dc, + void (*target_option_override_hook) (void)) { size_t scode = decoded->opt_index; const char *arg = decoded->arg; @@ -1743,6 +1744,7 @@ common_handle_option (struct gcc_options *opts, undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings) ? 0 : CL_UNDOCUMENTED); + target_option_override_hook (); /* First display any single language specific options. */ for (i = 0; i < cl_lang_count; i++) print_specific_help @@ -1762,6 +1764,7 @@ common_handle_option (struct gcc_options *opts, if (lang_mask == CL_DRIVER) break; + target_option_override_hook (); print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask); opts->x_exit_after_options = true; break; @@ -1888,8 +1891,11 @@ common_handle_option (struct gcc_options *opts, } if (include_flags) - print_specific_help (include_flags, exclude_flags, 0, opts, - lang_mask); + { + target_option_override_hook (); + print_specific_help (include_flags, exclude_flags, 0, opts, + lang_mask); + } opts->x_exit_after_options = true; break; } diff --git a/gcc/opts.h b/gcc/opts.h index 5599711cc76..2774e2c8b40 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -272,7 +272,8 @@ struct cl_option_handler_func const struct cl_decoded_option *decoded, unsigned int lang_mask, int kind, location_t loc, const struct cl_option_handlers *handlers, - diagnostic_context *dc); + diagnostic_context *dc, + void (*target_option_override_hook) (void)); /* The mask that must have some bit in common with the flags for the option for this particular handler to be used. */ @@ -294,6 +295,9 @@ struct cl_option_handlers void (*wrong_lang_callback) (const struct cl_decoded_option *decoded, unsigned int lang_mask); + /* Target option override hook. */ + void (*target_option_override_hook) (void); + /* The number of individual handlers. */ size_t num_handlers; @@ -338,13 +342,15 @@ extern void decode_cmdline_options_to_array_default_mask (unsigned int argc, const char **argv, struct cl_decoded_option **decoded_options, unsigned int *decoded_options_count); -extern void set_default_handlers (struct cl_option_handlers *handlers); +extern void set_default_handlers (struct cl_option_handlers *handlers, + void (*target_option_override_hook) (void)); extern void decode_options (struct gcc_options *opts, struct gcc_options *opts_set, struct cl_decoded_option *decoded_options, unsigned int decoded_options_count, location_t loc, - diagnostic_context *dc); + diagnostic_context *dc, + void (*target_option_override_hook) (void)); extern int option_enabled (int opt_idx, void *opts); extern bool get_option_state (struct gcc_options *, int, struct cl_option_state *); @@ -391,14 +397,16 @@ extern bool common_handle_option (struct gcc_options *opts, unsigned int lang_mask, int kind, location_t loc, const struct cl_option_handlers *handlers, - diagnostic_context *dc); + diagnostic_context *dc, + void (*target_option_override_hook) (void)); extern bool target_handle_option (struct gcc_options *opts, struct gcc_options *opts_set, const struct cl_decoded_option *decoded, unsigned int lang_mask, int kind, location_t loc, const struct cl_option_handlers *handlers, - diagnostic_context *dc); + diagnostic_context *dc, + void (*target_option_override_hook) (void)); extern void finish_options (struct gcc_options *opts, struct gcc_options *opts_set, location_t loc); diff --git a/gcc/toplev.c b/gcc/toplev.c index d23714c4773..7d2b8fffa0b 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -2149,7 +2149,8 @@ toplev::main (int argc, char **argv) enough to default flags appropriately. */ decode_options (&global_options, &global_options_set, save_decoded_options, save_decoded_options_count, - UNKNOWN_LOCATION, global_dc); + UNKNOWN_LOCATION, global_dc, + targetm.target_option.override); handle_common_deferred_options (); -- 2.14.1
Hi.
There's another bunch of backports to GCC 7 branch I've just tested
and bootstrapped.
Martin
From 6a918e72d251dd4e2aa8b2c9643f857ceef3997d Mon Sep 17 00:00:00 2001
From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 31 Oct 2017 11:55:19 +0000
Subject: [PATCH 4/7] Backport r254257
gcc/ChangeLog:
2017-10-31 Martin Liska <mliska@suse.cz>
PR gcov-profile/82633
* doc/gcov.texi: Document -fkeep-{static,inline}-functions and
their interaction with GCOV infrastructure.
---
gcc/configure | 4 ++--
gcc/configure.ac | 4 ++--
gcc/doc/gcov.texi | 7 +++++++
3 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
index 706aa6cf0b0..88b8d6d9071 100644
--- a/gcc/doc/gcov.texi
+++ b/gcc/doc/gcov.texi
@@ -328,6 +328,13 @@ handlers, respectively. Given @samp{-a} option, unexecuted blocks are
marked @samp{$$$$$} or @samp{%%%%%}, depending on whether a basic block
is reachable via non-exceptional or exceptional paths.
+Note that GCC can completely remove the bodies of functions that are
+not needed -- for instance if they are inlined everywhere. Such functions
+are marked with @samp{-}, which can be confusing.
+Use the @option{-fkeep-inline-functions} and @option{-fkeep-static-functions}
+options to retain these functions and
+allow gcov to properly show their @var{execution_count}.
+
Some lines of information at the start have @var{line_number} of zero.
These preamble lines are of the form
I'm going to install one more patch.
Martin
From e58dd9f5b28468e2afb928c767041e5a3fef057f Mon Sep 17 00:00:00 2001
From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Fri, 27 Oct 2017 08:34:56 +0000
Subject: [PATCH] Backport r254137
gcc/ChangeLog:
2017-10-27 Martin Liska <mliska@suse.cz>
PR gcov-profile/82457
* doc/invoke.texi: Document that one needs a non-strict ISO mode
for fork-like functions to be properly instrumented.
---
gcc/doc/invoke.texi | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index a0fb09eb9e1..6d0283298c6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -10648,9 +10648,9 @@ Link your object files with @option{-lgcov} or @option{-fprofile-arcs}
Run the program on a representative workload to generate the arc profile
information. This may be repeated any number of times. You can run
concurrent instances of your program, and provided that the file system
-supports locking, the data files will be correctly updated. Also
-@code{fork} calls are detected and correctly handled (double counting
-will not happen).
+supports locking, the data files will be correctly updated. Unless
+a strict ISO C dialect option is in effect, @code{fork} calls are
+detected and correctly handled without double counting.
@item
For profile-directed optimizations, compile the source files again with
Hello. Another 4 patches that I've just tests and bootsrapped. Martin From af6233cb16c9dc174ef4e45da06c43bfd5442d4e Mon Sep 17 00:00:00 2001 From: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Thu, 4 Jan 2018 21:13:17 +0000 Subject: Backport r256266 gcc/testsuite/ChangeLog: 2018-01-04 Jakub Jelinek <jakub@redhat.com> PR ipa/82352 * g++.dg/ipa/pr82352.C (size_t): Define to __SIZE_TYPE__ instead of long unsigned int. --- diff --git a/gcc/testsuite/g++.dg/ipa/pr82352.C b/gcc/testsuite/g++.dg/ipa/pr82352.C index c044345a486..08516da0c8a 100644 --- a/gcc/testsuite/g++.dg/ipa/pr82352.C +++ b/gcc/testsuite/g++.dg/ipa/pr82352.C @@ -2,7 +2,7 @@ // { dg-do compile } // { dg-options "-O2" } -typedef long unsigned int size_t; +typedef __SIZE_TYPE__ size_t; class A { -- 2.14.3 From 6ed5216d2b8b2be5c9373a9f9dc0c38ef09abce7 Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Thu, 4 Jan 2018 08:54:17 +0000 Subject: Backport r256226 gcc/ChangeLog: 2018-01-04 Martin Liska <mliska@suse.cz> PR ipa/82352 * ipa-icf.c (sem_function::merge): Do not cross comdat boundary. gcc/testsuite/ChangeLog: 2018-01-04 Martin Liska <mliska@suse.cz> PR ipa/82352 * g++.dg/ipa/pr82352.C: New test. --- diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index edb0b7896cd..b9f2bf30744 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -1113,6 +1113,17 @@ sem_function::merge (sem_item *alias_item) return false; } + if (!original->in_same_comdat_group_p (alias) + || original->comdat_local_p ()) + { + if (dump_file) + fprintf (dump_file, + "Not unifying; alias nor wrapper cannot be created; " + "across comdat group boundary\n\n"); + + return false; + } + /* See if original is in a section that can be discarded if the main symbol is not used. */ diff --git a/gcc/testsuite/g++.dg/ipa/pr82352.C b/gcc/testsuite/g++.dg/ipa/pr82352.C new file mode 100644 index 00000000000..c044345a486 --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr82352.C @@ -0,0 +1,93 @@ +// PR ipa/82352 +// { dg-do compile } +// { dg-options "-O2" } + +typedef long unsigned int size_t; + +class A +{ +public : + typedef enum { Zero = 0, One = 1 } tA; + A(tA a) { m_a = a; } + +private : + tA m_a; +}; + +class B +{ +public : + void *operator new(size_t t) { return (void*)(42); }; +}; + +class C +{ +public: + virtual void ffff () = 0; +}; + +class D +{ + public : + virtual void g() = 0; + virtual void h() = 0; +}; + +template<class T> class IIII: public T, public D +{ +public: + void ffff() + { + if (!m_i2) throw A(A::One); + }; + + void h() + { + if (m_i2) throw A(A::Zero); + } + +protected: + virtual void g() + { + if (m_i1 !=0) throw A(A::Zero); + }; + +private : + int m_i1; + void *m_i2; +}; + +class E +{ +private: + size_t m_e; + static const size_t Max; + +public: + E& i(size_t a, size_t b, size_t c) + { + if ((a > Max) || (c > Max)) throw A(A::Zero ); + if (a + b > m_e) throw A(A::One ); + return (*this); + } + + inline E& j(const E &s) + { + return i(0,0,s.m_e); + } +}; + +class F : public C { }; +class G : public C { }; +class HHHH : public B, public F, public G { }; + +void k() +{ + new IIII<HHHH>(); +} + +void l() +{ + E e1, e2; + e1.j(e2); +} -- 2.14.3 From f7491b347eed2606bcaf8ae8497f8fae3738ec6e Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Wed, 3 Jan 2018 14:15:58 +0000 Subject: Backport r256177 gcc/ChangeLog: 2018-01-03 Martin Liska <mliska@suse.cz> PR ipa/83549 * cif-code.def (VARIADIC_THUNK): New enum value. * ipa-fnsummary.c (compute_fn_summary): Do not inline variadic thunks. gcc/testsuite/ChangeLog: 2018-01-03 Martin Liska <mliska@suse.cz> PR ipa/83549 * g++.dg/ipa/pr83549.C: New test. --- diff --git a/gcc/cif-code.def b/gcc/cif-code.def index 6d7e2b4070b..19a76213943 100644 --- a/gcc/cif-code.def +++ b/gcc/cif-code.def @@ -95,6 +95,10 @@ DEFCIFCODE(MISMATCHED_ARGUMENTS, CIF_FINAL_ERROR, DEFCIFCODE(LTO_MISMATCHED_DECLARATIONS, CIF_FINAL_ERROR, N_("mismatched declarations during linktime optimization")) +/* Caller is variadic thunk. */ +DEFCIFCODE(VARIADIC_THUNK, CIF_FINAL_ERROR, + N_("variadic thunk call")) + /* Call was originally indirect. */ DEFCIFCODE(ORIGINALLY_INDIRECT_CALL, CIF_FINAL_NORMAL, N_("originally indirect function call not considered for inlining")) diff --git a/gcc/ipa-fnsummary.c b/gcc/ipa-fnsummary.c index fc18518d48f..e9f76d5cdac 100644 --- a/gcc/ipa-fnsummary.c +++ b/gcc/ipa-fnsummary.c @@ -2422,6 +2422,11 @@ compute_fn_summary (struct cgraph_node *node, bool early) info->inlinable = false; node->callees->inline_failed = CIF_CHKP; } + else if (stdarg_p (TREE_TYPE (node->decl))) + { + info->inlinable = false; + node->callees->inline_failed = CIF_VARIADIC_THUNK; + } else info->inlinable = true; } diff --git a/gcc/testsuite/g++.dg/ipa/pr83549.C b/gcc/testsuite/g++.dg/ipa/pr83549.C new file mode 100644 index 00000000000..90cf8fe7e0d --- /dev/null +++ b/gcc/testsuite/g++.dg/ipa/pr83549.C @@ -0,0 +1,8 @@ +// PR ipa/83549 +// { dg-do compile } +// { dg-options "-O2" } + +struct A { virtual ~A (); }; +struct B { virtual void foo (...); }; +struct C : A, B { void foo (...) {} }; +C c; -- 2.14.3 From 1abfa5b17a752895ddcfde4aa6e3931142d27a26 Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Wed, 27 Dec 2017 09:30:14 +0000 Subject: Backport r256009 gcc/ChangeLog: 2017-12-27 Martin Liska <mliska@suse.cz> PR tree-optimization/83552 * tree-ssa-strlen.c (fold_strstr_to_strncmp): Assign result of get_string_lenth to a SSA_NAME if not a GIMPLE value. gcc/testsuite/ChangeLog: 2017-12-27 Martin Liska <mliska@suse.cz> PR tree-optimization/83552 * gcc.dg/pr83552.c: New test. --- diff --git a/gcc/testsuite/gcc.dg/pr83552.c b/gcc/testsuite/gcc.dg/pr83552.c new file mode 100644 index 00000000000..993cdd26581 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr83552.c @@ -0,0 +1,13 @@ +/* PR tree-optimization/83364 */ +/* { dg-options "-O2" } */ + +char *b; +char d[100]; +void a (); +void +c (void) +{ + __builtin_strcat (d, "12345"); + if (__builtin_strstr (b, d) == b) + a (); +} diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index e812bd1e735..be6ab9f1e1b 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -3005,6 +3005,16 @@ fold_strstr_to_strncmp (tree rhs1, tree rhs2, gimple *stmt) { gimple_stmt_iterator gsi = gsi_for_stmt (call_stmt); tree strncmp_decl = builtin_decl_explicit (BUILT_IN_STRNCMP); + + if (!is_gimple_val (arg1_len)) + { + tree arg1_len_tmp = make_ssa_name (TREE_TYPE (arg1_len)); + gassign *arg1_stmt = gimple_build_assign (arg1_len_tmp, + arg1_len); + gsi_insert_before (&gsi, arg1_stmt, GSI_SAME_STMT); + arg1_len = arg1_len_tmp; + } + gcall *strncmp_call = gimple_build_call (strncmp_decl, 3, arg0, arg1, arg1_len); tree strncmp_lhs = make_ssa_name (integer_type_node); -- 2.14.3
From f075fe82a3e4244de9fe9728180dd4325c6e466e Mon Sep 17 00:00:00 2001 From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4> Date: Wed, 28 Jun 2017 12:47:24 +0000 Subject: [PATCH 1/8] Backport r249735 gcc/ChangeLog: 2017-06-28 Martin Liska <mliska@suse.cz> PR ipa/81128 * ipa-visibility.c (non_local_p): Handle visibility. gcc/c-family/ChangeLog: 2017-06-28 Martin Liska <mliska@suse.cz> PR ipa/81128 * c-attribs.c (handle_alias_ifunc_attribute): Append ifunc alias to a function declaration. gcc/testsuite/ChangeLog: 2017-06-28 Martin Liska <mliska@suse.cz> PR ipa/81128 * gcc.target/i386/pr81128.c: New test. --- gcc/c-family/c-attribs.c | 11 ++++-- gcc/ipa-visibility.c | 3 +- gcc/testsuite/gcc.target/i386/pr81128.c | 65 +++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr81128.c diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c index f2a88e147ba..90b17bc00d2 100644 --- a/gcc/c-family/c-attribs.c +++ b/gcc/c-family/c-attribs.c @@ -1764,9 +1764,14 @@ handle_alias_ifunc_attribute (bool is_alias, tree *node, tree name, tree args, TREE_STATIC (decl) = 1; if (!is_alias) - /* ifuncs are also aliases, so set that attribute too. */ - DECL_ATTRIBUTES (decl) - = tree_cons (get_identifier ("alias"), args, DECL_ATTRIBUTES (decl)); + { + /* ifuncs are also aliases, so set that attribute too. */ + DECL_ATTRIBUTES (decl) + = tree_cons (get_identifier ("alias"), args, + DECL_ATTRIBUTES (decl)); + DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("ifunc"), + NULL, DECL_ATTRIBUTES (decl)); + } } else { diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c index d5a3ae56c46..da4a22e7329 100644 --- a/gcc/ipa-visibility.c +++ b/gcc/ipa-visibility.c @@ -97,7 +97,8 @@ non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) && !DECL_EXTERNAL (node->decl) && !node->externally_visible && !node->used_from_other_partition - && !node->in_other_partition); + && !node->in_other_partition + && node->get_availability () >= AVAIL_AVAILABLE); } /* Return true when function can be marked local. */ diff --git a/gcc/testsuite/gcc.target/i386/pr81128.c b/gcc/testsuite/gcc.target/i386/pr81128.c new file mode 100644 index 00000000000..90a567ad690 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr81128.c @@ -0,0 +1,65 @@ +/* PR ipa/81128 */ +/* { dg-do run } */ +/* { dg-options "-O3" } */ +/* { dg-require-ifunc "" } */ + + +#include <stdio.h> +#include <stdlib.h> +#include <time.h> + +int resolver_fn = 0; +int resolved_fn = 0; + +static inline void +do_it_right_at_runtime_A () +{ + resolved_fn++; +} + +static inline void +do_it_right_at_runtime_B () +{ + resolved_fn++; +} + +static inline void do_it_right_at_runtime (void); + +void do_it_right_at_runtime (void) + __attribute__ ((ifunc ("resolve_do_it_right_at_runtime"))); + +static void (*resolve_do_it_right_at_runtime (void)) (void) +{ + srand (time (NULL)); + int r = rand (); + resolver_fn++; + + /* Use intermediate variable to get a warning for non-matching + * prototype. */ + typeof(do_it_right_at_runtime) *func; + if (r & 1) + func = do_it_right_at_runtime_A; + else + func = do_it_right_at_runtime_B; + + return (void *) func; +} + +int +main (void) +{ + const unsigned int ITERS = 10; + + for (int i = ITERS; i > 0; i--) + { + do_it_right_at_runtime (); + } + + if (resolver_fn != 1) + __builtin_abort (); + + if (resolved_fn != 10) + __builtin_abort (); + + return 0; +} -- 2.14.1