From patchwork Mon Jan 9 13:08:49 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Li=C5=A1ka?= X-Patchwork-Id: 90440 Delivered-To: patch@linaro.org Received: by 10.140.20.99 with SMTP id 90csp72410qgi; Mon, 9 Jan 2017 05:09:16 -0800 (PST) X-Received: by 10.99.171.75 with SMTP id k11mr17060933pgp.16.1483967356636; Mon, 09 Jan 2017 05:09:16 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id g31si58107906pld.30.2017.01.09.05.09.16 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 09 Jan 2017 05:09:16 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-445680-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org; spf=pass (google.com: domain of gcc-patches-return-445680-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-445680-patch=linaro.org@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; q=dns; s=default; b=a5Os3F4hptvsIUOZB uXPxt7ExLwkRCbOakKj2dIjz1X3Ci/Mi+h3GQ5koJ+Gb2Q3C8EnVdRd4Rq/JWNYx Zt0jwRoJI8cC4tckL4McRG5TqO6fVk1P/kYj8SXVNDXNT5oAQsJg/3ZjhJYTNEGT Zn/JblqGBaurnzTdGf+bVUWFLM= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :subject:to:references:cc:from:message-id:date:mime-version :in-reply-to:content-type; s=default; bh=hykZm6ZOH9e2SNIK5X1yVSO a0KY=; b=RlVWdXVUNcRiDPr1QqeiP9n/zwgRs9YvBruuYdZPhyVFGlnWY6LEsGx lhmM9yeHPH/Lxzt72OwGZkRan1OrpRzeStnSjVXSHvxcZaI+QRxA/eE7LmIIjhgM JBn8gPvlLGiyp2Q2SjtlRxoZW6NKc94vwlvn++nOjsGtlCzifQxE= Received: (qmail 91580 invoked by alias); 9 Jan 2017 13:09:04 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 91570 invoked by uid 89); 9 Jan 2017 13:09:02 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, SPF_PASS autolearn=ham version=3.3.2 spammy=drives, 1639, symtab_node, Drives X-HELO: mx2.suse.de Received: from mx2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 09 Jan 2017 13:08:52 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id CCA94AC4E; Mon, 9 Jan 2017 13:08:49 +0000 (UTC) Subject: [RFC] [PATCH] Ignore Debug options for ICF equality. To: Richard Biener , Alexandre Oliva , Jakub Jelinek References: <20170105085729.GU21933@tucnak> <20170105220218.GF21933@tucnak> <0b1a1a91-260b-8684-8264-1fab3152246f@suse.cz> Cc: GCC Patches , Jan Hubicka From: =?UTF-8?Q?Martin_Li=c5=a1ka?= Message-ID: Date: Mon, 9 Jan 2017 14:08:49 +0100 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.5.1 MIME-Version: 1.0 In-Reply-To: <0b1a1a91-260b-8684-8264-1fab3152246f@suse.cz> X-IsSubscribed: yes Hello. Thanks Alexander for fixed the issue. In the meantime, I worked on a patch that would be more generic and would introduce cl_optimization_eq function. It's definitely stage1 material and it adds 'Debug' keyword to Optimization options (equal to PerFunction that is currently in trunk). However there are differences: - cl_optimization_hash has new argument 'ignored_flags' that specify which flags are ignored (currently only Debug is handled here). - cl_optimization_eq - new function, having the same argument For the future, if there will be consensus, I'll be happy to rename 'optimization' (Optimization) to 'per_function' (PerFunction)? I think Optimization is unlucky name. Thoughts? Martin >From 68f800b3093c6a5bf9fff86ec362af766ad5288b Mon Sep 17 00:00:00 2001 From: marxin Date: Fri, 6 Jan 2017 16:01:23 +0100 Subject: [PATCH] Ignore Debug options for ICF equality. gcc/testsuite/ChangeLog: 2017-01-09 Martin Liska * gcc.dg/ipa/ipa-icf-38.c: New test. * gcc.dg/ipa/ipa-icf-39.c: New test. gcc/ChangeLog: 2017-01-09 Martin Liska * common.opt: Add Debug attribute for debug optimization flags. * ipa-icf.c (sem_function::get_hash): Ignore CL_DEBUG options. (sem_item::ignore_attr_p): New function. (sem_item::compare_attributes): Use the function. (sem_function::equals_wpa): Fix typo. * ipa-icf.h (ignore_attr_p): Declare new function. * ipa-inline.c (can_inline_edge_p): Remove comparison of optimization flags. * opt-functions.awk (switch_opts_type_flags): New function. * optc-save-gen.awk: Add new assert. (cl_optimization_hash): Add new argument. (cl_optimization_eq): New function. * opth-gen.awk: Update declaration. * opts.h (CL_DEBUG): Define new macro. --- gcc/common.opt | 8 ++-- gcc/ipa-icf.c | 25 +++++++---- gcc/ipa-icf.h | 3 ++ gcc/ipa-inline.c | 7 ---- gcc/opt-functions.awk | 12 +++++- gcc/optc-save-gen.awk | 79 ++++++++++++++++++++--------------- gcc/opth-gen.awk | 16 +++---- gcc/opts.h | 1 + gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c | 23 ++++++++++ gcc/testsuite/gcc.dg/ipa/ipa-icf-39.c | 13 ++++++ 10 files changed, 123 insertions(+), 64 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c create mode 100644 gcc/testsuite/gcc.dg/ipa/ipa-icf-39.c diff --git a/gcc/common.opt b/gcc/common.opt index 9e751bda6be..d4a5e2461af 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2644,7 +2644,7 @@ Common Undocumented Var(flag_use_linker_plugin) ; will be set according to optimize, debug_info_level and debug_hooks ; in process_options (). fvar-tracking -Common Report Var(flag_var_tracking) Init(2) Optimization +Common Report Var(flag_var_tracking) Init(2) Optimization Debug Perform variable tracking. ; Positive if we should track variables at assignments, negative if @@ -2652,13 +2652,13 @@ Perform variable tracking. ; annotations. When flag_var_tracking_assignments == ; AUTODETECT_VALUE it will be set according to flag_var_tracking. fvar-tracking-assignments -Common Report Var(flag_var_tracking_assignments) Init(2) Optimization +Common Report Var(flag_var_tracking_assignments) Init(2) Optimization Debug Perform variable tracking by annotating assignments. ; Nonzero if we should toggle flag_var_tracking_assignments after ; processing options and computing its default. */ fvar-tracking-assignments-toggle -Common Report Var(flag_var_tracking_assignments_toggle) Optimization +Common Report Var(flag_var_tracking_assignments_toggle) Optimization Debug Toggle -fvar-tracking-assignments. ; Positive if we should track uninitialized variables, negative if @@ -2666,7 +2666,7 @@ Toggle -fvar-tracking-assignments. ; annotations. When flag_var_tracking_uninit == AUTODETECT_VALUE it ; will be set according to flag_var_tracking. fvar-tracking-uninit -Common Report Var(flag_var_tracking_uninit) Optimization +Common Report Var(flag_var_tracking_uninit) Optimization Debug Perform variable tracking and also tag variables that are uninitialized. ftree-vectorize diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c index 4c835c39e3d..94e6a9ed5a0 100644 --- a/gcc/ipa-icf.c +++ b/gcc/ipa-icf.c @@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-icf.h" #include "stor-layout.h" #include "dbgcnt.h" +#include "opts.h" using namespace ipa_icf_gimple; @@ -289,10 +290,7 @@ sem_function::get_hash (void) hstate.add_wide_int (cl_target_option_hash (TREE_TARGET_OPTION (DECL_FUNCTION_SPECIFIC_TARGET (decl)))); - if (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)) - hstate.add_wide_int - (cl_optimization_hash - (TREE_OPTIMIZATION (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (decl)))); + hstate.add_wide_int (cl_optimization_hash (opts_for_fn (decl), CL_DEBUG)); hstate.add_flag (DECL_CXX_CONSTRUCTOR_P (decl)); hstate.add_flag (DECL_CXX_DESTRUCTOR_P (decl)); @@ -302,6 +300,17 @@ sem_function::get_hash (void) return m_hash; } +bool +sem_item::ignore_attr_p (const attribute_spec *as) +{ + /* Do not allow optimization or (and) target options. */ + if (strcmp (as->name, "optimize") == 0 + || strcmp (as->name, "target") == 0) + return true; + + return false; +} + /* Return ture if A1 and A2 represent equivalent function attribute lists. Based on comp_type_attributes. */ @@ -324,7 +333,7 @@ sem_item::compare_attributes (const_tree a1, const_tree a2) For example returns_nonnull affects only references, while optimize attribute can be ignored because it is already lowered into flags representation and compared separately. */ - if (!as) + if (!as || ignore_attr_p (as)) continue; attr = lookup_attribute (as->name, CONST_CAST_TREE (a2)); @@ -338,7 +347,7 @@ sem_item::compare_attributes (const_tree a1, const_tree a2) const struct attribute_spec *as; as = lookup_attribute_spec (get_attribute_name (a)); - if (!as) + if (!as || ignore_attr_p (as)) continue; if (!lookup_attribute (as->name, CONST_CAST_TREE (a1))) @@ -652,13 +661,13 @@ sem_function::equals_wpa (sem_item *item, cl_target_option_print_diff (dump_file, 2, tar1, tar2); } - return return_false_with_msg ("Target flags are different"); + return return_false_with_msg ("target flags are different"); } cl_optimization *opt1 = opts_for_fn (decl); cl_optimization *opt2 = opts_for_fn (item->decl); - if (opt1 != opt2 && memcmp (opt1, opt2, sizeof(cl_optimization))) + if (opt1 != opt2 && !cl_optimization_eq (opt1, opt2, CL_DEBUG)) { if (dump_file && (dump_flags & TDF_DETAILS)) { diff --git a/gcc/ipa-icf.h b/gcc/ipa-icf.h index c57224c1517..9a2166ce9c9 100644 --- a/gcc/ipa-icf.h +++ b/gcc/ipa-icf.h @@ -253,6 +253,9 @@ protected: symtab_node *n2, bool address); + /* Return true when attribute specification AC should be ignored. */ + static bool ignore_attr_p (const attribute_spec *as); + /* Compare two attribute lists. */ static bool compare_attributes (const_tree list1, const_tree list2); diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index d7ea38f364f..0e7cb809cc6 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -448,13 +448,6 @@ can_inline_edge_p (struct cgraph_edge *e, bool report, /* gcc.dg/pr43564.c. Apply user-forced inline even at -O0. */ else if (always_inline) ; - /* When user added an attribute to the callee honor it. */ - else if (lookup_attribute ("optimize", DECL_ATTRIBUTES (callee->decl)) - && opts_for_fn (caller->decl) != opts_for_fn (callee->decl)) - { - e->inline_failed = CIF_OPTIMIZATION_MISMATCH; - inlinable = false; - } /* If explicit optimize attribute are not used, the mismatch is caused by different command line options used to build different units. Do not care about COMDAT functions - those are intended to be diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk index 540980ef54e..b2b5b66ea56 100644 --- a/gcc/opt-functions.awk +++ b/gcc/opt-functions.awk @@ -105,7 +105,17 @@ function switch_flags (flags) test_flag("Undocumented", flags, " | CL_UNDOCUMENTED") \ test_flag("NoDWARFRecord", flags, " | CL_NO_DWARF_RECORD") \ test_flag("Warning", flags, " | CL_WARNING") \ - test_flag("Optimization", flags, " | CL_OPTIMIZATION") + test_flag("Optimization", flags, " | CL_OPTIMIZATION") \ + test_flag("Debug", flags, " | CL_DEBUG") + sub( "^0 \\| ", "", result ) + return result +} + +function switch_opts_type_flags (flags) +{ + result = "0" + result = result \ + test_flag("Debug", flags, " | CL_DEBUG") sub( "^0 \\| ", "", result ) return result } diff --git a/gcc/optc-save-gen.awk b/gcc/optc-save-gen.awk index fb517fe034b..1d224672357 100644 --- a/gcc/optc-save-gen.awk +++ b/gcc/optc-save-gen.awk @@ -127,7 +127,7 @@ for (i = 0; i < n_opts; i++) { var_opt_range[name] = "-128, 127" } else - var_opt_other[n_opt_other++] = name; + n_opt_other++; } } @@ -137,10 +137,8 @@ for (i = 0; i < n_opt_char; i++) { print " gcc_assert (IN_RANGE (opts->x_" name ", " var_opt_range[name] "));"; } -print ""; -for (i = 0; i < n_opt_other; i++) { - print " ptr->x_" var_opt_other[i] " = opts->x_" var_opt_other[i] ";"; -} +if (n_opt_other > 0) + print "#error Unsupported type of optimization node"; for (i = 0; i < n_opt_int; i++) { print " ptr->x_" var_opt_int[i] " = opts->x_" var_opt_int[i] ";"; @@ -166,10 +164,6 @@ print "void"; print "cl_optimization_restore (struct gcc_options *opts, struct cl_optimization *ptr)"; print "{"; -for (i = 0; i < n_opt_other; i++) { - print " opts->x_" var_opt_other[i] " = ptr->x_" var_opt_other[i] ";"; -} - for (i = 0; i < n_opt_int; i++) { print " opts->x_" var_opt_int[i] " = ptr->x_" var_opt_int[i] ";"; } @@ -198,15 +192,6 @@ print " struct cl_optimization *ptr)"; print "{"; print " fputs (\"\\n\", file);"; -for (i = 0; i < n_opt_other; i++) { - print " if (ptr->x_" var_opt_other[i] ")"; - print " fprintf (file, \"%*s%s (%#lx)\\n\","; - print " indent_to, \"\","; - print " \"" var_opt_other[i] "\","; - print " (unsigned long)ptr->x_" var_opt_other[i] ");"; - print ""; -} - for (i = 0; i < n_opt_int; i++) { print " if (ptr->x_" var_opt_int[i] ")"; print " fprintf (file, \"%*s%s (%#x)\\n\","; @@ -254,16 +239,6 @@ print " struct cl_optimization *ptr2)"; print "{"; print " fputs (\"\\n\", file);"; -for (i = 0; i < n_opt_other; i++) { - print " if (ptr1->x_" var_opt_other[i] " != ptr2->x_" var_opt_other[i] ")"; - print " fprintf (file, \"%*s%s (%#lx/%#lx)\\n\","; - print " indent_to, \"\","; - print " \"" var_opt_other[i] "\","; - print " (unsigned long)ptr1->x_" var_opt_other[i] ","; - print " (unsigned long)ptr2->x_" var_opt_other[i] ");"; - print ""; -} - for (i = 0; i < n_opt_int; i++) { print " if (ptr1->x_" var_opt_int[i] " != ptr2->x_" var_opt_int[i] ")"; print " fprintf (file, \"%*s%s (%#x/%#x)\\n\","; @@ -306,7 +281,6 @@ for (i = 0; i < n_opt_char; i++) { print "}"; - print ""; print "/* Save selected option variables into a structure. */" print "void"; @@ -738,10 +712,13 @@ print "}"; n_opt_val = 3; var_opt_val[0] = "x_optimize" var_opt_val_type[0] = "char " +var_opt_type_flags[0] = "0" var_opt_val[1] = "x_optimize_size" -var_opt_val[2] = "x_optimize_debug" var_opt_val_type[1] = "char " +var_opt_type_flags[1] = "0" +var_opt_val[2] = "x_optimize_debug" var_opt_val_type[2] = "char " +var_opt_type_flags[2] = 0"" for (i = 0; i < n_opts; i++) { if (flag_set_p("Optimization", flags[i])) { name = var_name(flags[i]) @@ -755,18 +732,29 @@ for (i = 0; i < n_opts; i++) { otype = var_type_struct(flags[i]) var_opt_val_type[n_opt_val] = otype; - var_opt_val[n_opt_val++] = "x_" name; + var_opt_val[n_opt_val] = "x_" name; + var_opt_type_flags[n_opt_val++] = switch_opts_type_flags(flags[i]) } } + +print ""; +print "/* Hash optimization options, ignore flags having a flag in IGNORED flags. */"; print ""; -print "/* Hash optimization options */"; print "hashval_t"; -print "cl_optimization_hash (struct cl_optimization const *ptr ATTRIBUTE_UNUSED)"; +print "cl_optimization_hash (struct cl_optimization const *ptr ATTRIBUTE_UNUSED,"; +print " unsigned int ignored_flags ATTRIBUTE_UNUSED)"; print "{"; print " inchash::hash hstate;"; for (i = 0; i < n_opt_val; i++) { name = var_opt_val[i] - print " hstate.add_wide_int (ptr->" name");"; + f = var_opt_type_flags[i]; + padding = ""; + if (f != "0") { + print " if (!(ignored_flags & (" f ")))" + padding = " " + } + + print padding " hstate.add_wide_int (ptr->" name");"; } print " return hstate.end ();"; print "}"; @@ -794,4 +782,27 @@ for (i = 0; i < n_opt_val; i++) { print " ptr->" name" = (" var_opt_val_type[i] ") bp_unpack_value (bp, 64);"; } print "}"; + +print ""; +print "/* Compare two target options */"; +print "bool"; +print "cl_optimization_eq (struct cl_optimization const *ptr1 ATTRIBUTE_UNUSED,"; +print " struct cl_optimization const *ptr2 ATTRIBUTE_UNUSED,"; +print " unsigned int ignored_flags ATTRIBUTE_UNUSED)"; +print "{"; + +for (i = 0; i < n_opt_val; i++) { + name = var_opt_val[i] + f = var_opt_type_flags[i]; + printf " if (ptr1->" name" != ptr2->" name; + if (f != "0") + print "\n && !(ignored_flags & (" f ")))"; + else + print(")") + print " return false;"; +} + +print " return true;"; +print "}"; + } diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk index f6b3812b8be..1868b5d2e8d 100644 --- a/gcc/opth-gen.awk +++ b/gcc/opth-gen.awk @@ -136,7 +136,6 @@ n_opt_char = 3; n_opt_short = 0; n_opt_int = 0; n_opt_enum = 0; -n_opt_other = 0; var_opt_char[0] = "unsigned char x_optimize"; var_opt_char[1] = "unsigned char x_optimize_size"; var_opt_char[2] = "unsigned char x_optimize_debug"; @@ -164,15 +163,9 @@ for (i = 0; i < n_opts; i++) { else if (otype ~ ("^enum +[_" alnum "]+ *$")) var_opt_enum[n_opt_enum++] = otype "x_" name; - else - var_opt_other[n_opt_other++] = otype "x_" name; } } -for (i = 0; i < n_opt_other; i++) { - print " " var_opt_other[i] ";"; -} - for (i = 0; i < n_opt_int; i++) { print " " var_opt_int[i] ";"; } @@ -306,7 +299,10 @@ print "/* Hash option variables from a structure. */"; print "extern hashval_t cl_target_option_hash (const struct cl_target_option *);"; print ""; print "/* Hash optimization from a structure. */"; -print "extern hashval_t cl_optimization_hash (const struct cl_optimization *);"; +print "extern hashval_t cl_optimization_hash (const struct cl_optimization *, unsigned int ignored_flags = 0);"; +print ""; +print "/* Compare two optimization option variables from a structure. */"; +print "extern bool cl_optimization_eq (const struct cl_optimization *, const struct cl_optimization *, unsigned int ignored_flags = 0);"; print ""; print "/* Generator files may not have access to location_t, and don't need these. */" print "#if defined(UNKNOWN_LOCATION)" @@ -332,7 +328,7 @@ for (i = 0; i < n_langs; i++) { print "void cpp_handle_option_auto (const struct gcc_options * opts, size_t scode," print " struct cpp_options * cpp_opts);" print "void init_global_opts_from_cpp(struct gcc_options * opts, " -print " const struct cpp_options * cpp_opts);" +print " const struct cpp_options * cpp_opts);" print "#endif"; print "#endif"; print ""; @@ -436,7 +432,7 @@ print "#define CL_LANG_ALL ((1U << " n_langs ") - 1)" print "" print "enum opt_code" print "{" - + for (i = 0; i < n_opts; i++) back_chain[i] = "N_OPTS"; diff --git a/gcc/opts.h b/gcc/opts.h index 56ba9101c64..65ad93d2930 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -145,6 +145,7 @@ extern const unsigned int cl_lang_count; #define CL_UNDOCUMENTED (1U << 24) /* Do not output with --help. */ #define CL_NO_DWARF_RECORD (1U << 25) /* Do not add to producer string. */ #define CL_PCH_IGNORE (1U << 26) /* Do compare state for pch. */ +#define CL_DEBUG (1U << 27) /* Drives debug info generation. */ /* Flags for an enumerated option argument. */ #define CL_ENUM_CANONICAL (1 << 0) /* Canonical for this value. */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c new file mode 100644 index 00000000000..12f9453f5ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-38.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-ipa-icf" } */ + +int +__attribute__((optimize(("split-loops")))) +foo(void) { return 0; } + +int +__attribute__((optimize(("split-loops")))) +bar (void) { return 0; } + + +int +__attribute__ ((hot)) +foo2(void) { return 0; } + +int +__attribute__ ((hot)) +bar2(void) { return 0; } + +/* { dg-final { scan-ipa-dump "Equal symbols: 2" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:foo->bar" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:foo2->bar2" "icf" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-icf-39.c b/gcc/testsuite/gcc.dg/ipa/ipa-icf-39.c new file mode 100644 index 00000000000..890961929f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/ipa-icf-39.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-ipa-icf" } */ + +int +__attribute__((hot, no_reorder)) +foo(void) { return 0; } + +int +__attribute__((no_reorder, hot)) +bar (void) { return 0; } + +/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf" } } */ +/* { dg-final { scan-ipa-dump "Semantic equality hit:foo->bar" "icf" } } */ -- 2.11.0