diff mbox series

Backports for GCC 7 branch

Message ID 1147b9d2-91eb-508e-d70b-f8307aa1bc93@suse.cz
State New
Headers show
Series Backports for GCC 7 branch | expand

Commit Message

Martin Liška Sept. 15, 2017, 8:10 a.m. UTC
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

Comments

Martin Liška Sept. 15, 2017, 8:20 a.m. UTC | #1
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
Martin Liška Nov. 21, 2017, 3:56 p.m. UTC | #2
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
Martin Liška Nov. 21, 2017, 7 p.m. UTC | #3
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
Martin Liška Jan. 17, 2018, 11:41 a.m. UTC | #4
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
diff mbox series

Patch

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