On 09/15/2017 10:26 AM, Martin Liška wrote:
> Hello.
> 
> I'm going to install following backports.
> 
> Patches can bootstrap on ppc64le-redhat-linux and survives regression tests.
> 
> Martin
> 

Small correction as gcc/c-family/c-attribs.c file was created in time of GCC 6.
Thus there's updated version of patches I've just tested.

Martin
>From ab3e0619b82c0033c8c65417ffa796e6731e6d0f Mon Sep 17 00:00:00 2001
From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Wed, 30 Aug 2017 12:38:31 +0000
Subject: [PATCH 7/7] Backport r251530

gcc/ChangeLog:

2017-08-30  Martin Liska  <mli...@suse.cz>

	PR inline-asm/82001
	* ipa-icf-gimple.c (func_checker::compare_tree_list_operand):
	Rename to ...
	(func_checker::compare_asm_inputs_outputs): ... this function.
	(func_checker::compare_gimple_asm): Use the function to compare
	also ASM constrains.
	* ipa-icf-gimple.h: Rename the function.

gcc/testsuite/ChangeLog:

2017-08-30  Martin Liska  <mli...@suse.cz>

	PR inline-asm/82001
	* gcc.dg/ipa/pr82001.c: New test.
---
 gcc/ipa-icf-gimple.c               | 19 +++++++++++++------
 gcc/ipa-icf-gimple.h               |  6 +++---
 gcc/testsuite/gcc.dg/ipa/pr82001.c | 21 +++++++++++++++++++++
 3 files changed, 37 insertions(+), 9 deletions(-)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/pr82001.c

diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index 1c5aebf00ca..9a9012c6983 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -543,11 +543,8 @@ func_checker::compare_operand (tree t1, tree t2)
     }
 }
 
-/* Compares two tree list operands T1 and T2 and returns true if these
-   two trees are semantically equivalent.  */
-
 bool
-func_checker::compare_tree_list_operand (tree t1, tree t2)
+func_checker::compare_asm_inputs_outputs (tree t1, tree t2)
 {
   gcc_assert (TREE_CODE (t1) == TREE_LIST);
   gcc_assert (TREE_CODE (t2) == TREE_LIST);
@@ -560,6 +557,16 @@ func_checker::compare_tree_list_operand (tree t1, tree t2)
       if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2)))
 	return return_false ();
 
+      tree p1 = TREE_PURPOSE (t1);
+      tree p2 = TREE_PURPOSE (t2);
+
+      gcc_assert (TREE_CODE (p1) == TREE_LIST);
+      gcc_assert (TREE_CODE (p2) == TREE_LIST);
+
+      if (strcmp (TREE_STRING_POINTER (TREE_VALUE (p1)),
+		  TREE_STRING_POINTER (TREE_VALUE (p2))) != 0)
+	return return_false ();
+
       t2 = TREE_CHAIN (t2);
     }
 
@@ -1008,7 +1015,7 @@ func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
       tree input1 = gimple_asm_input_op (g1, i);
       tree input2 = gimple_asm_input_op (g2, i);
 
-      if (!compare_tree_list_operand (input1, input2))
+      if (!compare_asm_inputs_outputs (input1, input2))
 	return return_false_with_msg ("ASM input is different");
     }
 
@@ -1017,7 +1024,7 @@ func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2)
       tree output1 = gimple_asm_output_op (g1, i);
       tree output2 = gimple_asm_output_op (g2, i);
 
-      if (!compare_tree_list_operand (output1, output2))
+      if (!compare_asm_inputs_outputs (output1, output2))
 	return return_false_with_msg ("ASM output is different");
     }
 
diff --git a/gcc/ipa-icf-gimple.h b/gcc/ipa-icf-gimple.h
index 9530a8ed55c..c572a181736 100644
--- a/gcc/ipa-icf-gimple.h
+++ b/gcc/ipa-icf-gimple.h
@@ -215,9 +215,9 @@ public:
      is returned.  */
   bool compare_operand (tree t1, tree t2);
 
-  /* Compares two tree list operands T1 and T2 and returns true if these
-     two trees are semantically equivalent.  */
-  bool compare_tree_list_operand (tree t1, tree t2);
+  /* Compares GIMPLE ASM inputs (or outputs) where we iterate tree chain
+     and compare both TREE_PURPOSEs and TREE_VALUEs.  */
+  bool compare_asm_inputs_outputs (tree t1, tree t2);
 
   /* Verifies that trees T1 and T2, representing function declarations
      are equivalent from perspective of ICF.  */
diff --git a/gcc/testsuite/gcc.dg/ipa/pr82001.c b/gcc/testsuite/gcc.dg/ipa/pr82001.c
new file mode 100644
index 00000000000..05e32b10ef5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr82001.c
@@ -0,0 +1,21 @@
+/* { dg-do compile { target i?86-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fdump-ipa-icf-details"  } */
+
+int
+mullo (int a, int b)
+{
+  asm("mul %%edx   # %%1 was %1"
+      : "+"
+	"a"(a),
+	"+d"(b));
+  return a;
+}
+
+int
+mulhi (int a, int b)
+{
+  asm("mul %%edx   # %%1 was %1" : "+d"(a), "+a"(b));
+  return a;
+}
+
+/* { dg-final { scan-ipa-dump "Equal symbols: 0" "icf"  } } */
-- 
2.14.1

>From dbe394036c46f5f97d23b93b526991c018f6f8d9 Mon Sep 17 00:00:00 2001
From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 29 Aug 2017 08:35:46 +0000
Subject: [PATCH 6/7] Backport r251406

gcc/ada/ChangeLog:

2017-08-29  Martin Liska  <mli...@suse.cz>

	PR other/39851
	* gcc-interface/trans.c (Pragma_to_gnu): Set argument to NULL.
---
 gcc/ada/gcc-interface/trans.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 592d005ad89..8a4924c9f28 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -1469,7 +1469,7 @@ Pragma_to_gnu (Node_Id gnat_node)
 	else
 	  option_index = 0;
 
-	set_default_handlers (&handlers);
+	set_default_handlers (&handlers, NULL);
 	control_warning_option (option_index, (int) kind, arg, imply, location,
 				lang_mask, &handlers, &global_options,
 				&global_options_set, global_dc);
-- 
2.14.1

>From 2f0dead62377a3b2b776bb81013d78d99a7f8670 Mon Sep 17 00:00:00 2001
From: marxin <mli...@suse.cz>
Date: Fri, 15 Sep 2017 10:22:46 +0200
Subject: [PATCH 5/7] Backport r251400

gcc/ChangeLog:

2017-08-29  Martin Liska  <mli...@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  <mli...@suse.cz>

	PR other/39851
	* c-common.c (parse_optimize_options): Add argument to function
	call.
	* c-pragma.c (handle_pragma_diagnostic): Likewise.
---
 gcc/c-family/c-common.c |  2 +-
 gcc/c-family/c-pragma.c |  2 +-
 gcc/gcc.c               |  3 ++-
 gcc/opts-common.c       |  3 ++-
 gcc/opts-global.c       | 12 ++++++++----
 gcc/opts.c              | 14 ++++++++++----
 gcc/opts.h              | 18 +++++++++++++-----
 gcc/toplev.c            |  3 ++-
 8 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index e769053a3ba..b214f374601 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -9601,7 +9601,7 @@ parse_optimize_options (tree args, bool attr_p)
 						&decoded_options_count);
   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 c73aa822104..660f28673e6 100644
--- a/gcc/c-family/c-pragma.c
+++ b/gcc/c-family/c-pragma.c
@@ -813,7 +813,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 896d9af4acb..85ea19bd3a0 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -3702,7 +3702,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 900c580019e..0d7f93d5545 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -986,7 +986,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 b7e52323a21..23dd7fb5579 100644
--- a/gcc/opts-global.c
+++ b/gcc/opts-global.c
@@ -167,7 +167,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);
@@ -267,10 +268,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;
@@ -288,7 +291,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;
 
@@ -296,7 +300,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 0f9431a0b32..8f9862db57c 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -216,7 +216,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);
@@ -1543,7 +1543,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;
@@ -1570,6 +1571,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
@@ -1589,6 +1591,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;
@@ -1710,8 +1713,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 25d32c1ad49..52887b6a32c 100644
--- a/gcc/opts.h
+++ b/gcc/opts.h
@@ -267,7 +267,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.  */
@@ -289,6 +290,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;
 
@@ -333,13 +337,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 *);
@@ -384,14 +390,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 3d4137b7c7b..d6f6c74ffbc 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -2100,7 +2100,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

>From 718e8d5a01aaf1a78d0c5bd6ab773b69f1f7ccc5 Mon Sep 17 00:00:00 2001
From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Thu, 10 Aug 2017 07:43:49 +0000
Subject: [PATCH 4/7] Backport r251020

gcc/ChangeLog:

2017-08-10  Martin Liska  <mli...@suse.cz>

	PR c++/81355
	* c-attribs.c (handle_target_attribute):
	Report warning for an empty string argument of target attribute.

gcc/testsuite/ChangeLog:

2017-08-10  Martin Liska  <mli...@suse.cz>

	PR c++/81355
	* g++.dg/other/pr81355.C: New test.
---
 gcc/c-family/c-common.c              | 13 +++++++++++++
 gcc/testsuite/g++.dg/other/pr81355.C | 14 ++++++++++++++
 2 files changed, 27 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/other/pr81355.C

diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index dec1acbeb5a..e769053a3ba 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -9439,6 +9439,19 @@ handle_target_attribute (tree *node, tree name, tree args, int flags,
 						      flags))
     *no_add_attrs = true;
 
+  /* Check that there's no empty string in values of the attribute.  */
+  for (tree t = args; t != NULL_TREE; t = TREE_CHAIN (t))
+    {
+      tree value = TREE_VALUE (t);
+      if (TREE_CODE (value) == STRING_CST
+	  && TREE_STRING_LENGTH (value) == 1
+	  && TREE_STRING_POINTER (value)[0] == '\0')
+	{
+	  warning (OPT_Wattributes, "empty string in attribute %<target%>");
+	  *no_add_attrs = true;
+	}
+    }
+
   return NULL_TREE;
 }
 
diff --git a/gcc/testsuite/g++.dg/other/pr81355.C b/gcc/testsuite/g++.dg/other/pr81355.C
new file mode 100644
index 00000000000..89d1b419581
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/pr81355.C
@@ -0,0 +1,14 @@
+/* { dg-do compile { target x86_64-*-* } } */
+
+__attribute__((target("default")))
+int foo() {return 1;}
+
+__attribute__((target("arch=core2", "")))
+int foo2() {return 2;} /* { dg-warning "empty string in attribute .target." } */
+
+__attribute__((target("sse4.2", "", "")))
+int foo3() {return 2;} /* { dg-warning "empty string in attribute .target." } */
+
+int main() {
+    return foo() + foo2() + foo3();
+}
-- 
2.14.1

>From 28f5aa544b9a352e9acd1928f6725c707284cfd9 Mon Sep 17 00:00:00 2001
From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Tue, 8 Aug 2017 11:59:23 +0000
Subject: [PATCH 3/7] Backport r250951

gcc/ChangeLog:

2017-08-08  Martin Liska  <mli...@suse.cz>

	PR tree-opt/81696
	* ipa-icf-gimple.c (func_checker::compare_cst_or_decl): Consider
	LABEL_DECLs that can be from a different function.

gcc/testsuite/ChangeLog:

2017-08-08  Martin Liska  <mli...@suse.cz>

	PR tree-opt/81696
	* gcc.dg/ipa/pr81696.c: New test.
---
 gcc/ipa-icf-gimple.c               |  6 +++++-
 gcc/testsuite/gcc.dg/ipa/pr81696.c | 26 ++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/pr81696.c

diff --git a/gcc/ipa-icf-gimple.c b/gcc/ipa-icf-gimple.c
index 9e3c862339b..1c5aebf00ca 100644
--- a/gcc/ipa-icf-gimple.c
+++ b/gcc/ipa-icf-gimple.c
@@ -361,10 +361,14 @@ func_checker::compare_cst_or_decl (tree t1, tree t2)
       }
     case LABEL_DECL:
       {
+	if (t1 == t2)
+	  return true;
+
 	int *bb1 = m_label_bb_map.get (t1);
 	int *bb2 = m_label_bb_map.get (t2);
 
-	return return_with_debug (*bb1 == *bb2);
+	/* Labels can point to another function (non-local GOTOs).  */
+	return return_with_debug (bb1 != NULL && bb2 != NULL && *bb1 == *bb2);
       }
     case PARM_DECL:
     case RESULT_DECL:
diff --git a/gcc/testsuite/gcc.dg/ipa/pr81696.c b/gcc/testsuite/gcc.dg/ipa/pr81696.c
new file mode 100644
index 00000000000..2d3d63ff0bb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr81696.c
@@ -0,0 +1,26 @@
+/* { dg-options "-O2 -fdump-ipa-icf-details"  } */
+
+int
+main (int argc, char **argv)
+{
+  __label__ lab4, lab5, lab6;
+
+  void foo (void) { goto lab4; }
+  void foo2 (void) { goto lab4; }
+  void bar (void) { goto lab5; }
+  void baz (void) { goto lab6; }
+
+  if (argc)
+    foo ();
+  else
+    foo2 ();
+
+ lab4:;
+  bar ();
+ lab5:;
+  baz ();
+ lab6:;
+  return 0;
+}
+
+/* { dg-final { scan-ipa-dump "Equal symbols: 1" "icf"  } } */
-- 
2.14.1

>From 22f12a7536789b6ecff0eaa8ca7e94411d978303 Mon Sep 17 00:00:00 2001
From: marxin <marxin@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Wed, 19 Jul 2017 06:50:34 +0000
Subject: [PATCH 2/7] Backport r250336

gcc/testsuite/ChangeLog:

2017-07-19  Martin Liska  <mli...@suse.cz>

	PR sanitizer/63361
	* c-c++-common/ubsan/float-cast-overflow-1.c: Add either
	-ffloat-store or -mieee for targets that need it.
---
 gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-1.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-1.c b/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-1.c
index cd6941c9d30..aae88aa3180 100644
--- a/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-1.c
+++ b/gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-1.c
@@ -1,6 +1,7 @@
 /* { dg-do run { target { lp64 || ilp32 } } } */
 /* { dg-options "-fsanitize=float-cast-overflow" } */
-/* { dg-additional-options "-msse2 -mfpmath=sse" { target { sse2_runtime && ia32 } } } */
+/* { dg-additional-options "-ffloat-store" { target { ia32 } } } */
+/* { dg-additional-options "-mieee" { target { { alpha*-*-* } || { sh*-*-* } } } } */
 
 #include <limits.h>
 #include "float-cast.h"
-- 
2.14.1

>From 652b1cb2cf3cbc18ec7a2a2cb20d84ad10eaca11 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/7] Backport r249735

gcc/ChangeLog:

2017-06-28  Martin Liska  <mli...@suse.cz>

	PR ipa/81128
	* ipa-visibility.c (non_local_p): Handle visibility.

gcc/c-family/ChangeLog:

2017-06-28  Martin Liska  <mli...@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  <mli...@suse.cz>

	PR ipa/81128
	* gcc.target/i386/pr81128.c: New test.
---
 gcc/c-family/c-common.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-common.c b/gcc/c-family/c-common.c
index 6cf8c610b4e..dec1acbeb5a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -7989,9 +7989,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 adc4426e6be..520c659899e 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

Reply via email to