Hi!

I've backported the following patches, bootstrapped/regtested on
x86_64-linux and i686-linux and committed to gcc-8-branch.

        Jakub
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-13  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/87898
        * omp-simd-clone.c (ipa_simd_modify_function_body): Remove debug stmts
        where the first argument was changed into a non-decl.

        * gcc.dg/gomp/pr87898.c: New test.

--- gcc/omp-simd-clone.c        (revision 266092)
+++ gcc/omp-simd-clone.c        (revision 266093)
@@ -1014,6 +1011,21 @@ ipa_simd_modify_function_body (struct cg
          if (info.modified)
            {
              update_stmt (stmt);
+             /* If the above changed the var of a debug bind into something
+                different, remove the debug stmt.  We could also for all the
+                replaced parameters add VAR_DECLs for debug info purposes,
+                add debug stmts for those to be the simd array accesses and
+                replace debug stmt var operand with that var.  Debugging of
+                vectorized loops doesn't work too well, so don't bother for
+                now.  */
+             if ((gimple_debug_bind_p (stmt)
+                  && !DECL_P (gimple_debug_bind_get_var (stmt)))
+                 || (gimple_debug_source_bind_p (stmt)
+                     && !DECL_P (gimple_debug_source_bind_get_var (stmt))))
+               {
+                 gsi_remove (&gsi, true);
+                 continue;
+               }
              if (maybe_clean_eh_stmt (stmt))
                gimple_purge_dead_eh_edges (gimple_bb (stmt));
            }
--- gcc/testsuite/gcc.dg/gomp/pr87898.c (nonexistent)
+++ gcc/testsuite/gcc.dg/gomp/pr87898.c (revision 266093)
@@ -0,0 +1,10 @@
+/* PR tree-optimization/87898 */
+/* { dg-do compile { target fgraphite } } */
+/* { dg-options "-O1 -floop-parallelize-all -fopenmp 
-ftree-parallelize-loops=2 -g" } */
+
+#pragma omp declare simd
+void
+foo (int x)
+{
+  x = 0;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-15  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/88018
        * cfgrtl.c (fixup_abnormal_edges): Guard moving insns to fallthru edge
        on the presence of fallthru edge, rather than if it is a USE or not.

        * g++.dg/tsan/pr88018.C: New test.

--- gcc/cfgrtl.c        (revision 266173)
+++ gcc/cfgrtl.c        (revision 266174)
@@ -3332,8 +3332,15 @@ fixup_abnormal_edges (void)
                         If it's placed after a trapping call (i.e. that
                         call is the last insn anyway), we have no fallthru
                         edge.  Simply delete this use and don't try to insert
-                        on the non-existent edge.  */
-                     if (GET_CODE (PATTERN (insn)) != USE)
+                        on the non-existent edge.
+                        Similarly, sometimes a call that can throw is
+                        followed in the source with __builtin_unreachable (),
+                        meaning that there is UB if the call returns rather
+                        than throws.  If there weren't any instructions
+                        following such calls before, supposedly even the ones
+                        we've deleted aren't significant and can be
+                        removed.  */
+                     if (e)
                        {
                          /* We're not deleting it, we're moving it.  */
                          insn->set_undeleted ();
--- gcc/testsuite/g++.dg/tsan/pr88018.C (nonexistent)
+++ gcc/testsuite/g++.dg/tsan/pr88018.C (revision 266236)
@@ -0,0 +1,6 @@
+// PR rtl-optimization/88018
+// { dg-do compile }
+// { dg-skip-if "" { *-*-* }  { "*" } { "-O0" } }
+// { dg-options "-fsanitize=thread -fno-ipa-pure-const -O1 
-fno-inline-functions-called-once -w" }
+
+#include "../pr69667.C"
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-16  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/87475
        * cfgrtl.c (patch_jump_insn): Allow redirection failure for
        CROSSING_JUMP_P insns.
        (cfg_layout_redirect_edge_and_branch): Don't ICE if ret is NULL.

        * g++.dg/opt/pr87475.C: New test.

--- gcc/cfgrtl.c        (revision 266218)
+++ gcc/cfgrtl.c        (revision 266219)
@@ -1268,11 +1268,13 @@ patch_jump_insn (rtx_insn *insn, rtx_ins
 
          /* If the substitution doesn't succeed, die.  This can happen
             if the back end emitted unrecognizable instructions or if
-            target is exit block on some arches.  */
+            target is exit block on some arches.  Or for crossing
+            jumps.  */
          if (!redirect_jump (as_a <rtx_jump_insn *> (insn),
                              block_label (new_bb), 0))
            {
-             gcc_assert (new_bb == EXIT_BLOCK_PTR_FOR_FN (cfun));
+             gcc_assert (new_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
+                         || CROSSING_JUMP_P (insn));
              return false;
            }
        }
@@ -4460,6 +4462,9 @@ cfg_layout_redirect_edge_and_branch (edg
   else
     ret = redirect_branch_edge (e, dest);
 
+  if (!ret)
+    return NULL;
+
   fixup_partition_crossing (ret);
   /* We don't want simplejumps in the insn stream during cfglayout.  */
   gcc_assert (!simplejump_p (BB_END (src)) || CROSSING_JUMP_P (BB_END (src)));
--- gcc/testsuite/g++.dg/opt/pr87475.C  (nonexistent)
+++ gcc/testsuite/g++.dg/opt/pr87475.C  (revision 266219)
@@ -0,0 +1,7 @@
+// PR rtl-optimization/87475
+// { dg-do compile { target freorder } }
+// { dg-options "-O2 -freorder-blocks-and-partition -fmodulo-sched" }
+
+struct A { A (); ~A (); };
+int foo (A, A);
+void bar (bool x) { x ? foo (A (), A ()) : 0; }
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-19  Jakub Jelinek  <ja...@redhat.com>

        PR debug/87039
        * omp-expand.c: Don't include debug.h.
        (adjust_context_and_scope): Add REGION argument.  Find DECL_CONTEXT
        from innermost outer parallel, task, or target that has a
        child_fn set, or, if there is no such outer region, use
        current_function_decl.  Do the DECL_CONTEXT adjustment regardless of
        whether a suitable BLOCK is found or not.
        (expand_parallel_call): Don't call adjust_context_and_scope here.
        (grid_expand_target_grid_body): Revert 2017-01-25 changes.
        (expand_omp_taskreg, expand_omp_target): Likewise.  Call
        adjust_context_and_scope.
        * dwarf2out.c (dwarf2out_early_global_decl): For
        decl_function_context recurse instead of calling dwarf2out_decl.

        * g++.dg/gomp/pr78363-4.C: New test.
        * g++.dg/gomp/pr78363-5.C: New test.
        * g++.dg/gomp/pr78363-6.C: New test.
        * g++.dg/gomp/pr78363-7.C: New test.

--- gcc/omp-expand.c    (revision 266271)
+++ gcc/omp-expand.c    (revision 266272)
@@ -56,7 +56,6 @@ along with GCC; see the file COPYING3.
 #include "gomp-constants.h"
 #include "gimple-pretty-print.h"
 #include "hsa-common.h"
-#include "debug.h"
 #include "stringpool.h"
 #include "attribs.h"
 
@@ -507,27 +506,43 @@ parallel_needs_hsa_kernel_p (struct omp_
    function will be emitted with the correct lexical scope.  */
 
 static void
-adjust_context_and_scope (tree entry_block, tree child_fndecl)
+adjust_context_and_scope (struct omp_region *region, tree entry_block,
+                         tree child_fndecl)
 {
+  tree parent_fndecl = NULL_TREE;
+  gimple *entry_stmt;
+  /* OMP expansion expands inner regions before outer ones, so if
+     we e.g. have explicit task region nested in parallel region, when
+     expanding the task region current_function_decl will be the original
+     source function, but we actually want to use as context the child
+     function of the parallel.  */
+  for (region = region->outer;
+       region && parent_fndecl == NULL_TREE; region = region->outer)
+    switch (region->type)
+      {
+      case GIMPLE_OMP_PARALLEL:
+      case GIMPLE_OMP_TASK:
+       entry_stmt = last_stmt (region->entry);
+       parent_fndecl = gimple_omp_taskreg_child_fn (entry_stmt);
+       break;
+      case GIMPLE_OMP_TARGET:
+       entry_stmt = last_stmt (region->entry);
+       parent_fndecl
+         = gimple_omp_target_child_fn (as_a <gomp_target *> (entry_stmt));
+       break;
+      default:
+       break;
+      }
+
+  if (parent_fndecl == NULL_TREE)
+    parent_fndecl = current_function_decl;
+  DECL_CONTEXT (child_fndecl) = parent_fndecl;
+
   if (entry_block != NULL_TREE && TREE_CODE (entry_block) == BLOCK)
     {
       tree b = BLOCK_SUPERCONTEXT (entry_block);
-
       if (TREE_CODE (b) == BLOCK)
         {
-         tree parent_fndecl;
-
-         /* Follow supercontext chain until the parent fndecl
-            is found.  */
-         for (parent_fndecl = BLOCK_SUPERCONTEXT (b);
-              TREE_CODE (parent_fndecl) == BLOCK;
-              parent_fndecl = BLOCK_SUPERCONTEXT (parent_fndecl))
-           ;
-
-         gcc_assert (TREE_CODE (parent_fndecl) == FUNCTION_DECL);
-
-         DECL_CONTEXT (child_fndecl) = parent_fndecl;
-
          DECL_CHAIN (child_fndecl) = BLOCK_VARS (b);
          BLOCK_VARS (b) = child_fndecl;
        }
@@ -703,8 +718,6 @@ expand_parallel_call (struct omp_region
   tree child_fndecl = gimple_omp_parallel_child_fn (entry_stmt);
   t2 = build_fold_addr_expr (child_fndecl);
 
-  adjust_context_and_scope (gimple_block (entry_stmt), child_fndecl);
-
   vec_alloc (args, 4 + vec_safe_length (ws_args));
   args->quick_push (t2);
   args->quick_push (t1);
@@ -1294,11 +1307,6 @@ expand_omp_taskreg (struct omp_region *r
       else
        block = gimple_block (entry_stmt);
 
-      /* Make sure to generate early debug for the function before
-         outlining anything.  */
-      if (! gimple_in_ssa_p (cfun))
-       (*debug_hooks->early_global_decl) (cfun->decl);
-
       new_bb = move_sese_region_to_fn (child_cfun, entry_bb, exit_bb, block);
       if (exit_bb)
        single_succ_edge (new_bb)->flags = EDGE_FALLTHRU;
@@ -1379,6 +1387,8 @@ expand_omp_taskreg (struct omp_region *r
        }
     }
 
+  adjust_context_and_scope (region, gimple_block (entry_stmt), child_fn);
+
   if (gimple_code (entry_stmt) == GIMPLE_OMP_PARALLEL)
     expand_parallel_call (region, new_bb,
                          as_a <gomp_parallel *> (entry_stmt), ws_args);
@@ -7042,11 +7052,6 @@ expand_omp_target (struct omp_region *re
          gsi_remove (&gsi, true);
        }
 
-      /* Make sure to generate early debug for the function before
-         outlining anything.  */
-      if (! gimple_in_ssa_p (cfun))
-       (*debug_hooks->early_global_decl) (cfun->decl);
-
       /* Move the offloading region into CHILD_CFUN.  */
 
       block = gimple_block (entry_stmt);
@@ -7123,6 +7128,8 @@ expand_omp_target (struct omp_region *re
          dump_function_header (dump_file, child_fn, dump_flags);
          dump_function_to_file (child_fn, dump_file, dump_flags);
        }
+
+      adjust_context_and_scope (region, gimple_block (entry_stmt), child_fn);
     }
 
   /* Emit a library call to launch the offloading region, or do data
@@ -7619,11 +7626,6 @@ grid_expand_target_grid_body (struct omp
   init_tree_ssa (cfun);
   pop_cfun ();
 
-  /* Make sure to generate early debug for the function before
-     outlining anything.  */
-  if (! gimple_in_ssa_p (cfun))
-    (*debug_hooks->early_global_decl) (cfun->decl);
-
   tree old_parm_decl = DECL_ARGUMENTS (kern_fndecl);
   gcc_assert (!DECL_CHAIN (old_parm_decl));
   tree new_parm_decl = copy_node (DECL_ARGUMENTS (kern_fndecl));
--- gcc/dwarf2out.c     (revision 266271)
+++ gcc/dwarf2out.c     (revision 266272)
@@ -26403,7 +26403,7 @@ dwarf2out_early_global_decl (tree decl)
                 enough so that it lands in its own context.  This avoids type
                 pruning issues later on.  */
              if (context_die == NULL || is_declaration_die (context_die))
-               dwarf2out_decl (context);
+               dwarf2out_early_global_decl (context);
            }
 
          /* Emit an abstract origin of a function first.  This happens
--- gcc/testsuite/g++.dg/gomp/pr78363-4.C       (nonexistent)
+++ gcc/testsuite/g++.dg/gomp/pr78363-4.C       (revision 266272)
@@ -0,0 +1,18 @@
+// { dg-do compile }
+// { dg-require-effective-target c++11 }
+// { dg-additional-options "-g" }
+
+int main()
+{
+  int n = 0;
+
+#pragma omp parallel
+#pragma omp master
+#pragma omp parallel
+#pragma omp master
+#pragma omp parallel for reduction (+: n)
+  for (int i = [](){ return 3; }(); i < 10; ++i)
+    n++;
+
+  return n;
+}
--- gcc/testsuite/g++.dg/gomp/pr78363-5.C       (nonexistent)
+++ gcc/testsuite/g++.dg/gomp/pr78363-5.C       (revision 266272)
@@ -0,0 +1,17 @@
+// { dg-do compile }
+// { dg-require-effective-target c++11 }
+// { dg-additional-options "-g" }
+
+int main()
+{
+  int n = 0;
+#pragma omp task shared(n)
+#pragma omp target map(tofrom:n)
+#pragma omp for reduction (+: n)
+  for (int i = [](){ return 3; }(); i < 10; ++i)
+    n++;
+  if (n != 7)
+    __builtin_abort ();
+#pragma omp taskwait
+  return 0;
+}
--- gcc/testsuite/g++.dg/gomp/pr78363-6.C       (nonexistent)
+++ gcc/testsuite/g++.dg/gomp/pr78363-6.C       (revision 266272)
@@ -0,0 +1,16 @@
+// { dg-do compile }
+// { dg-require-effective-target c++11 }
+// { dg-additional-options "-g" }
+
+int main()
+{
+  int n = 0;
+#pragma omp parallel
+#pragma omp master
+#pragma omp task shared (n)
+  for (int i = [](){ return 3; }(); i < 10; ++i)
+    n = i;
+#pragma omp taskwait
+  if (n != 7)
+    __builtin_abort ();
+}
--- gcc/testsuite/g++.dg/gomp/pr78363-7.C       (nonexistent)
+++ gcc/testsuite/g++.dg/gomp/pr78363-7.C       (revision 266272)
@@ -0,0 +1,15 @@
+// { dg-do compile }
+// { dg-require-effective-target c++11 }
+// { dg-additional-options "-g" }
+
+int main()
+{
+  int n = 0;
+
+#pragma omp target map(tofrom: n)
+#pragma omp parallel for reduction (+: n)
+  for (int i = [](){ return 3; }(); i < 10; ++i)
+    n++;
+
+  return n;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-19  Jakub Jelinek  <ja...@redhat.com>
 
        PR c++/60994
        * g++.dg/lookup/pr60994.C: New test.

--- gcc/testsuite/g++.dg/lookup/pr60994.C       (nonexistent)
+++ gcc/testsuite/g++.dg/lookup/pr60994.C       (revision 266275)
@@ -0,0 +1,13 @@
+// PR c++/60994
+// { dg-do compile }
+
+struct s
+{
+  static int i;
+};
+
+template <typename T>
+int s()
+{
+  return s::i; // { dg-bogus "is not a class" }
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-19  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/88071
        * tree-vect-loop.c (vectorize_fold_left_reduction): Pass true instead
        of false as last argument to gsi_remove.
        * tree-vect-stmts.c (vect_finish_replace_stmt): Pass true instead of
        false as last argument to gsi_replace.

        * gcc.dg/pr88071.c: New test.

--- gcc/tree-vect-loop.c        (revision 266275)
+++ gcc/tree-vect-loop.c        (revision 266276)
@@ -5861,7 +5861,7 @@ vectorize_fold_left_reduction (stmt_vec_
          /* Remove the statement, so that we can use the same code paths
             as for statements that we've just created.  */
          gimple_stmt_iterator tmp_gsi = gsi_for_stmt (new_stmt);
-         gsi_remove (&tmp_gsi, false);
+         gsi_remove (&tmp_gsi, true);
        }
 
       if (i == vec_num - 1)
--- gcc/tree-vect-stmts.c       (revision 266275)
+++ gcc/tree-vect-stmts.c       (revision 266276)
@@ -1637,7 +1637,7 @@ vect_finish_replace_stmt (gimple *stmt,
   gcc_assert (gimple_get_lhs (stmt) == gimple_get_lhs (vec_stmt));
 
   gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
-  gsi_replace (&gsi, vec_stmt, false);
+  gsi_replace (&gsi, vec_stmt, true);
 
   vect_finish_stmt_generation_1 (stmt, vec_stmt);
 }
--- gcc/testsuite/gcc.dg/pr88071.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr88071.c      (revision 266276)
@@ -0,0 +1,5 @@
+/* PR tree-optimization/88071 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fexceptions -fnon-call-exceptions -fopenmp-simd -ftrapv 
-ftree-loop-vectorize" } */
+
+#include "gomp/openmp-simd-2.c"
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-20  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/87895
        * omp-simd-clone.c (ipa_simd_modify_function_body): When removing
        or replacing GIMPLE_RETURN, set EDGE_FALLTHRU on the edge to EXIT.
        (simd_clone_adjust): Don't set EDGE_FALLTHRU here. In a loop that
        redirects edges to EXIT to edges to incr_bb, iterate while EXIT
        has any preds and always use EDGE_PRED (, 0).

        * gcc.dg/gomp/pr87895-1.c: New test.
        * gcc.dg/gomp/pr87895-2.c: New test.
        * gcc.dg/gomp/pr87895-3.c: New test.

--- gcc/omp-simd-clone.c        (revision 266327)
+++ gcc/omp-simd-clone.c        (revision 266328)
@@ -994,6 +994,8 @@ ipa_simd_modify_function_body (struct cg
          if (greturn *return_stmt = dyn_cast <greturn *> (stmt))
            {
              tree retval = gimple_return_retval (return_stmt);
+             edge e = find_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun));
+             e->flags |= EDGE_FALLTHRU;
              if (!retval)
                {
                  gsi_remove (&gsi, true);
@@ -1150,14 +1152,9 @@ simd_clone_adjust (struct cgraph_node *n
       incr_bb = create_empty_bb (orig_exit);
       incr_bb->count = profile_count::zero ();
       add_bb_to_loop (incr_bb, body_bb->loop_father);
-      /* The succ of orig_exit was EXIT_BLOCK_PTR_FOR_FN (cfun), with an empty
-        flag.  Set it now to be a FALLTHRU_EDGE.  */
-      gcc_assert (EDGE_COUNT (orig_exit->succs) == 1);
-      EDGE_SUCC (orig_exit, 0)->flags |= EDGE_FALLTHRU;
-      for (unsigned i = 0;
-          i < EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); ++i)
+      while (EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds))
        {
-         edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), i);
+         edge e = EDGE_PRED (EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
          redirect_edge_succ (e, incr_bb);
          incr_bb->count += e->count ();
        }
--- gcc/testsuite/gcc.dg/gomp/pr87895-1.c       (nonexistent)
+++ gcc/testsuite/gcc.dg/gomp/pr87895-1.c       (revision 266328)
@@ -0,0 +1,19 @@
+/* PR tree-optimization/87895 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O0" } */
+
+#pragma omp declare simd
+int
+foo (int x)
+{
+  if (x == 0)
+    return 0;
+}
+
+#pragma omp declare simd
+int
+bar (int *x, int y)
+{
+  if ((y == 0) ? (*x = 0) : *x)
+    return 0;
+}
--- gcc/testsuite/gcc.dg/gomp/pr87895-2.c       (nonexistent)
+++ gcc/testsuite/gcc.dg/gomp/pr87895-2.c       (revision 266328)
@@ -0,0 +1,5 @@
+/* PR tree-optimization/87895 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O1" } */
+
+#include "pr87895-1.c"
--- gcc/testsuite/gcc.dg/gomp/pr87895-3.c       (nonexistent)
+++ gcc/testsuite/gcc.dg/gomp/pr87895-3.c       (revision 266328)
@@ -0,0 +1,18 @@
+/* PR tree-optimization/87895 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O2" } */
+
+#pragma omp declare simd
+int foo (int x) __attribute__((noreturn));
+
+#pragma omp declare simd
+int
+bar (int x, int y)
+{
+  if (y == 1)
+    foo (x + 2);
+  if (y == 10)
+    foo (x + 6);
+  if (y != 25)
+    return 4;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-21  Jakub Jelinek  <ja...@redhat.com>

        PR c++/88122
        * method.c (maybe_explain_implicit_delete): If
        FUNCTION_FIRST_USER_PARMTYPE (decl) is NULL, set const_p to false
        instead of ICEing.

        * g++.dg/cpp0x/implicit15.C: New test.

--- gcc/cp/method.c     (revision 266359)
+++ gcc/cp/method.c     (revision 266360)
@@ -1821,8 +1821,12 @@ maybe_explain_implicit_delete (tree decl
       if (!informed)
        {
          tree parms = FUNCTION_FIRST_USER_PARMTYPE (decl);
-         tree parm_type = TREE_VALUE (parms);
-         bool const_p = CP_TYPE_CONST_P (non_reference (parm_type));
+         bool const_p = false;
+         if (parms)
+           {
+             tree parm_type = TREE_VALUE (parms);
+             const_p = CP_TYPE_CONST_P (non_reference (parm_type));
+           }
          tree raises = NULL_TREE;
          bool deleted_p = false;
          tree scope = push_scope (ctype);
--- gcc/testsuite/g++.dg/cpp0x/implicit15.C     (nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/implicit15.C     (revision 266360)
@@ -0,0 +1,11 @@
+// PR c++/88122
+// { dg-do compile { target c++11 } }
+
+struct A {
+  A (...);     // { dg-message "candidate" }
+  A ();                // { dg-message "candidate" }
+};
+struct B : A {
+  using A::A;  // { dg-error "is ambiguous" }
+               // { dg-message "is implicitly deleted because the default 
definition would be ill-formed" "" { target *-*-* } .-1 }
+} b{3};                // { dg-error "use of deleted function" }
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-22  Jakub Jelinek  <ja...@redhat.com>

        PR target/85644
        PR target/86832
        * config/i386/i386.c (ix86_option_override_internal): Default
        ix86_stack_protector_guard to SSP_TLS only if TARGET_THREAD_SSP_OFFSET
        is defined.
        * config/i386/i386.md (stack_protect_set, stack_protect_set_<mode>,
        stack_protect_test, stack_protect_test_<mode>): Use empty condition
        instead of TARGET_SSP_TLS_GUARD.

--- gcc/config/i386/i386.md     (revision 266369)
+++ gcc/config/i386/i386.md     (revision 266370)
@@ -19010,7 +19010,7 @@ (define_insn "*prefetch_prefetchwt1"
 (define_expand "stack_protect_set"
   [(match_operand 0 "memory_operand")
    (match_operand 1 "memory_operand")]
-  "TARGET_SSP_TLS_GUARD"
+  ""
 {
   rtx (*insn)(rtx, rtx);
 
@@ -19028,7 +19028,7 @@ (define_insn "stack_protect_set_<mode>"
                    UNSPEC_SP_SET))
    (set (match_scratch:PTR 2 "=&r") (const_int 0))
    (clobber (reg:CC FLAGS_REG))]
-  "TARGET_SSP_TLS_GUARD"
+  ""
   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, 
%2}\;xor{l}\t%k2, %k2"
   [(set_attr "type" "multi")])
 
@@ -19036,7 +19036,7 @@ (define_expand "stack_protect_test"
   [(match_operand 0 "memory_operand")
    (match_operand 1 "memory_operand")
    (match_operand 2)]
-  "TARGET_SSP_TLS_GUARD"
+  ""
 {
   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
 
@@ -19059,7 +19059,7 @@ (define_insn "stack_protect_test_<mode>"
                     (match_operand:PTR 2 "memory_operand" "m")]
                    UNSPEC_SP_TEST))
    (clobber (match_scratch:PTR 3 "=&r"))]
-  "TARGET_SSP_TLS_GUARD"
+  ""
   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
   [(set_attr "type" "multi")])
 
--- gcc/config/i386/i386.c      (revision 266369)
+++ gcc/config/i386/i386.c      (revision 266370)
@@ -4559,8 +4559,14 @@ ix86_option_override_internal (bool main
 
   /* Handle stack protector */
   if (!opts_set->x_ix86_stack_protector_guard)
-    opts->x_ix86_stack_protector_guard
-      = TARGET_HAS_BIONIC ? SSP_GLOBAL : SSP_TLS;
+    {
+#ifdef TARGET_THREAD_SSP_OFFSET
+      if (!TARGET_HAS_BIONIC)
+       opts->x_ix86_stack_protector_guard = SSP_TLS;
+      else
+#endif
+       opts->x_ix86_stack_protector_guard = SSP_GLOBAL;
+    }
 
 #ifdef TARGET_THREAD_SSP_OFFSET
   ix86_stack_protector_guard_offset = TARGET_THREAD_SSP_OFFSET;
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-22  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/85794
        * gcc.dg/vect/O3-pr85794.c: New test.

--- gcc/testsuite/gcc.dg/vect/O3-pr85794.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/vect/O3-pr85794.c      (revision 266387)
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+int a, b, *c, d;
+int *f[6];
+
+void
+foo (void)
+{
+  for (b = 1; b >= 0; b--)
+    for (d = 0; d <= 3; d++)
+      a |= f[b * 5] != c;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-26  Jakub Jelinek  <ja...@redhat.com>

        PR c++/86900
        * dwarf2out.c (secname_for_decl): For functions with
        DECL_SECTION_NAME if in_cold_section_p, try to return
        current_function_section's name if it is a named section.

        * g++.dg/debug/dwarf2/pr86900.C: New test.

--- gcc/dwarf2out.c     (revision 266484)
+++ gcc/dwarf2out.c     (revision 266485)
@@ -16742,7 +16742,15 @@ secname_for_decl (const_tree decl)
       && DECL_SECTION_NAME (decl))
     secname = DECL_SECTION_NAME (decl);
   else if (current_function_decl && DECL_SECTION_NAME (current_function_decl))
-    secname = DECL_SECTION_NAME (current_function_decl);
+    {
+      if (in_cold_section_p)
+       {
+         section *sec = current_function_section ();
+         if (sec->common.flags & SECTION_NAMED)
+           return sec->named.name;
+       }
+      secname = DECL_SECTION_NAME (current_function_decl);
+    }
   else if (cfun && in_cold_section_p)
     secname = crtl->subsections.cold_section_label;
   else
--- gcc/testsuite/g++.dg/debug/dwarf2/pr86900.C (nonexistent)
+++ gcc/testsuite/g++.dg/debug/dwarf2/pr86900.C (revision 266485)
@@ -0,0 +1,14 @@
+// PR c++/86900
+// { dg-do assemble { target function_sections } }
+// { dg-options "-O2 -gdwarf-5 -ffunction-sections" }
+
+struct A;
+struct B { B (A); };
+struct A { A (int); ~A (); };
+
+void
+foo (int x)
+{
+  A d(0);
+  B e(d);
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-27  Jakub Jelinek  <ja...@redhat.com>

        PR c++/88181
        * class.c (fixup_attribute_variants): Also propagate TYPE_PACKED
        to variants.

        * g++.dg/debug/pr88181.C: New test.

--- gcc/cp/class.c      (revision 266526)
+++ gcc/cp/class.c      (revision 266527)
@@ -1951,6 +1951,7 @@ fixup_attribute_variants (tree t)
   unsigned align = TYPE_ALIGN (t);
   bool user_align = TYPE_USER_ALIGN (t);
   bool may_alias = lookup_attribute ("may_alias", attrs);
+  bool packed = TYPE_PACKED (t);
 
   if (may_alias)
     fixup_may_alias (t);
@@ -1968,6 +1969,7 @@ fixup_attribute_variants (tree t)
       else
        TYPE_USER_ALIGN (variants) = user_align;
       SET_TYPE_ALIGN (variants, valign);
+      TYPE_PACKED (variants) = packed;
       if (may_alias)
        fixup_may_alias (variants);
     }
--- gcc/testsuite/g++.dg/debug/pr88181.C        (nonexistent)
+++ gcc/testsuite/g++.dg/debug/pr88181.C        (revision 266527)
@@ -0,0 +1,29 @@
+// PR c++/88181
+// { dg-do compile }
+// { dg-options "-fpack-struct -g -std=c++11" }
+
+template <typename T> struct A { typedef T B; };
+template <typename...> class C;
+template <typename e> struct D { constexpr D (e) {} };
+template <int, typename...> struct E;
+template <int N, typename T, typename... U>
+struct E<N, T, U...> : E<1, U...>, D<T> {
+  constexpr E (T x, U... y) : E<1, U...>(y...), D<T>(x) {}
+};
+template <int N, typename T> struct E<N, T> : D<T> {
+  constexpr E (T x) : D<T>(x) {}
+};
+template <typename T, typename U> struct C<T, U> : E<0, T, U> {
+  constexpr C (T x, U y) : E<0, T, U>(x, y) {}
+  void operator= (typename A<const C>::B);
+};
+struct F {};
+struct G {};
+
+int
+main ()
+{
+  F f;
+  G g;
+  constexpr C<F, G> c(f, g);
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-28  Jakub Jelinek  <ja...@redhat.com>

        PR c++/88215
        * c-ubsan.c: Include langhooks.h.
        (ubsan_instrument_division): Change gcc_assert that main variants
        of op0 and op1 types are equal to gcc_checking_assert that the
        main variants are compatible types.

        * c-c++-common/ubsan/pr88215.c: New test.

--- gcc/c-family/c-ubsan.c      (revision 266545)
+++ gcc/c-family/c-ubsan.c      (revision 266546)
@@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.
 #include "stringpool.h"
 #include "attribs.h"
 #include "asan.h"
+#include "langhooks.h"
 
 /* Instrument division by zero and INT_MIN / -1.  If not instrumenting,
    return NULL_TREE.  */
@@ -44,8 +45,9 @@ ubsan_instrument_division (location_t lo
   /* At this point both operands should have the same type,
      because they are already converted to RESULT_TYPE.
      Use TYPE_MAIN_VARIANT since typedefs can confuse us.  */
-  gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
-             == TYPE_MAIN_VARIANT (TREE_TYPE (op1)));
+  tree top0 = TYPE_MAIN_VARIANT (type);
+  tree top1 = TYPE_MAIN_VARIANT (TREE_TYPE (op1));
+  gcc_checking_assert (lang_hooks.types_compatible_p (top0, top1));
 
   op0 = unshare_expr (op0);
   op1 = unshare_expr (op1);
--- gcc/testsuite/c-c++-common/ubsan/pr88215.c  (nonexistent)
+++ gcc/testsuite/c-c++-common/ubsan/pr88215.c  (revision 266546)
@@ -0,0 +1,11 @@
+/* PR c++/88215 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=integer-divide-by-zero" } */
+
+int
+foo (void)
+{
+  int a = 2, __attribute__ ((__unused__)) b = 1;
+  int f = a / b;
+  return f;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-29  Jakub Jelinek  <ja...@redhat.com>

        PR c++/87539
        * g++.dg/cpp0x/pr87539.C: New test.

--- gcc/testsuite/g++.dg/cpp0x/pr87539.C        (nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/pr87539.C        (revision 266611)
@@ -0,0 +1,85 @@
+// PR c++/87539
+// { dg-do compile { target c++11 } }
+// { dg-options "-Os" }
+
+namespace a {
+template <typename b, typename = b, typename = int> class c;
+class exception {};
+template <typename d> struct e { d f; };
+struct g { g(); g(const g &); };
+}
+template <class, class, class = int> class h;
+template <typename, typename> struct i;
+template <int j> struct aa { static const int k = j; };
+struct ac { typedef a::e<int> l; };
+struct ad;
+template <int, typename m, typename> struct ae { typedef m l; };
+template <typename m, typename n> struct ae<false, m, n> { typedef n l; };
+template <typename m, typename n, typename p> struct o {
+  typedef typename ae<m::k, n, p>::l l;
+};
+struct af { af(char *); };
+template <typename> struct ag { ag(a::g = a::g()) {} };
+template <typename ah, typename ai, typename aj, typename al>
+struct i<a::c<ah, ai, aj>, al> { typedef ag<al> l; };
+namespace ak {
+template <typename am, typename an, typename ao> struct ap {
+  typedef typename o<am, an, ao>::l ::l l;
+};
+template <typename = ad> struct aq { typedef ad l; };
+}
+template <typename ar> struct as {
+  typedef char at;
+  template <typename au, typename> static decltype(au(), at()) av(int);
+  template <typename, typename> static int av(...);
+  static const bool k = sizeof(av<ar, int>(0)) == 1;
+};
+template <typename ar> struct aw { static const bool k = as<ar>::k; };
+template <class ar> struct ax { typedef aw<ar> l; };
+template <typename ar> struct ay { typedef typename ax<ar>::l l; };
+template <typename ar> struct az : ay<ar>::l {};
+template <class ar, class> struct ba : aa<az<ar>::k> {};
+template <class> struct bb : ak::ap<ba<int, int>, ak::aq<>, int> {};
+template <typename> struct q : ba<bb<int>::l, int> {};
+template <class, class, bool> class r;
+template <class s, class t> struct r<s, t, false> {
+  s operator*();
+  s operator++();
+};
+template <class, class, class, class, class>
+class bc : public r<a::e<h<int, int>>, int, q<int>::k> {};
+template <class bd, class be, class bf, class u, class v, class bg, class w,
+          class x, class bh, class bi>
+int operator!=(bc<bd, be, bf, u, v>, bc<bg, w, x, bh, bi>);
+template <class, class, class> struct h {
+  typedef af bl;
+  bc<int, int, int, ak::ap<aa<false>, int, ac>::l, int> begin();
+  bc<int, int, int, ak::ap<aa<false>, int, ac>::l, int> end();
+  template <class bm> bm bn() const;
+  template <class> int bo() const;
+  template <class bm> int bx(const bl &, const bm &) const;
+  template <class> int bp(const bl &) const;
+};
+template <class bq, class br, class am>
+template <class bm>
+bm h<bq, br, am>::bn() const { typename i<a::c<int>, bm>::l(); return bm(); }
+template <class bq, class br, class am>
+template <class>
+int h<bq, br, am>::bo() const { i<a::c<int>, int>::l(); bn<int>(); return 0; }
+template <class bq, class br, class am>
+template <class bm>
+int h<bq, br, am>::bx(const bl &bs, const bm &) const { bp<int>(bs); return 0; 
}
+template <class bq, class br, class am>
+template <class>
+int h<bq, br, am>::bp(const bl &) const { bo<int>(); return 0; }
+char bt[] = "";
+void
+d()
+{
+  h<int, int> bu;
+  for (auto bv : bu)
+    try {
+      bv.f.bx(bt, 0);
+    } catch (a::exception) {
+    }
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-29  Jakub Jelinek  <ja...@redhat.com>

        PR target/88234
        * config/rs6000/rs6000.c (rs6000_gimple_fold_builtin): For
        vec_add and vec_sub builtins, perform PLUS_EXPR or MINUS_EXPR
        in unsigned_type_for instead of vector integral type where overflow
        doesn't wrap.

        * gcc.dg/ubsan/pr88234.c: New test.

--- gcc/config/rs6000/rs6000.c  (revision 266618)
+++ gcc/config/rs6000/rs6000.c  (revision 266619)
@@ -15371,6 +15371,7 @@ rs6000_gimple_fold_builtin (gimple_stmt_
   enum rs6000_builtins fn_code
     = (enum rs6000_builtins) DECL_FUNCTION_CODE (fndecl);
   tree arg0, arg1, lhs, temp;
+  enum tree_code bcode;
   gimple *g;
 
   size_t uns_fncode = (size_t) fn_code;
@@ -15409,10 +15410,32 @@ rs6000_gimple_fold_builtin (gimple_stmt_
     case P8V_BUILTIN_VADDUDM:
     case ALTIVEC_BUILTIN_VADDFP:
     case VSX_BUILTIN_XVADDDP:
+      bcode = PLUS_EXPR;
+    do_binary:
       arg0 = gimple_call_arg (stmt, 0);
       arg1 = gimple_call_arg (stmt, 1);
       lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, PLUS_EXPR, arg0, arg1);
+      if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (lhs)))
+         && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (TREE_TYPE (lhs))))
+       {
+         /* Ensure the binary operation is performed in a type
+            that wraps if it is integral type.  */
+         gimple_seq stmts = NULL;
+         tree type = unsigned_type_for (TREE_TYPE (lhs));
+         tree uarg0 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+                                    type, arg0);
+         tree uarg1 = gimple_build (&stmts, VIEW_CONVERT_EXPR,
+                                    type, arg1);
+         tree res = gimple_build (&stmts, gimple_location (stmt), bcode,
+                                  type, uarg0, uarg1);
+         gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
+         g = gimple_build_assign (lhs, VIEW_CONVERT_EXPR,
+                                  build1 (VIEW_CONVERT_EXPR,
+                                          TREE_TYPE (lhs), res));
+         gsi_replace (gsi, g, true);
+         return true;
+       }
+      g = gimple_build_assign (lhs, bcode, arg0, arg1);
       gimple_set_location (g, gimple_location (stmt));
       gsi_replace (gsi, g, true);
       return true;
@@ -15424,13 +15447,8 @@ rs6000_gimple_fold_builtin (gimple_stmt_
     case P8V_BUILTIN_VSUBUDM:
     case ALTIVEC_BUILTIN_VSUBFP:
     case VSX_BUILTIN_XVSUBDP:
-      arg0 = gimple_call_arg (stmt, 0);
-      arg1 = gimple_call_arg (stmt, 1);
-      lhs = gimple_call_lhs (stmt);
-      g = gimple_build_assign (lhs, MINUS_EXPR, arg0, arg1);
-      gimple_set_location (g, gimple_location (stmt));
-      gsi_replace (gsi, g, true);
-      return true;
+      bcode = MINUS_EXPR;
+      goto do_binary;
     case VSX_BUILTIN_XVMULSP:
     case VSX_BUILTIN_XVMULDP:
       arg0 = gimple_call_arg (stmt, 0);
--- gcc/testsuite/gcc.dg/ubsan/pr88234.c        (nonexistent)
+++ gcc/testsuite/gcc.dg/ubsan/pr88234.c        (revision 266619)
@@ -0,0 +1,29 @@
+/* PR target/88234 */
+/* { dg-do run { target { powerpc*-*-* && vmx_hw } } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-fsanitize=signed-integer-overflow 
-fno-sanitize-recover=signed-integer-overflow -O2 -maltivec" } */
+
+#include <altivec.h>
+
+__attribute__((noipa)) vector unsigned int
+f1 (vector unsigned int x, vector unsigned int y)
+{
+  return vec_add (x, y);
+}
+
+__attribute__((noipa)) vector unsigned int
+f2 (vector unsigned int x, vector unsigned int y)
+{
+  return vec_sub (x, y);
+}
+
+int
+main ()
+{
+  vector unsigned int x = { __INT_MAX__, -__INT_MAX__, __INT_MAX__ - 3, 
-__INT_MAX__ + 4 };
+  vector unsigned int y = { 1, -1, 4, -5 };
+  vector unsigned int z = f1 (x, y);
+  f2 (z, x);
+  f2 (z, y);
+  return 0;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-11-30  Jakub Jelinek  <ja...@redhat.com>

        PR debug/85550
        * g++.dg/debug/dwarf2/pr85550.C: New test.

--- gcc/testsuite/g++.dg/debug/dwarf2/pr85550.C (nonexistent)
+++ gcc/testsuite/g++.dg/debug/dwarf2/pr85550.C (revision 266689)
@@ -0,0 +1,17 @@
+// PR debug/85550
+// { dg-do link }
+// { dg-options "-O2 -g -fdebug-types-section" }
+
+struct A {
+  int bar () const { return 0; }
+};
+template <int (A::*foo)() const>
+struct B {
+};
+
+B<&A::bar> b;
+
+int
+main ()
+{
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-03  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/71109
        * gcc.c-torture/compile/pr71109.c: New test.

--- gcc/testsuite/gcc.c-torture/compile/pr71109.c       (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr71109.c       (revision 266738)
@@ -0,0 +1,31 @@
+/* PR tree-optimization/71109 */
+
+struct S { int g, h; signed char i; int j; signed char k; int l[4]; } a, c;
+struct T { signed char g; } e;
+int *b, d;
+static void foo ();
+
+void
+bar (void)
+{
+  while (d)
+    {
+      int k;
+      struct T f[3];
+      foo (bar, a);
+      for (k = 0;; k++)
+       f[k] = e;
+    }
+}
+
+static inline void
+foo (int x, struct S y, struct T z)
+{
+  for (z.g = 2; z.g; z.g--)
+    {
+      c = a = y;
+      *b |= 6;
+      if (y.g)
+       break;
+    }
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-04  Jakub Jelinek  <ja...@redhat.com>

        PR c++/88103
        * typeck.c (build_class_member_access_expr): If unary_complex_lvalue
        turned xvalue_p into non-xvalue_p, call move on it.

        * g++.dg/cpp0x/rv-cond3.C: New test.

--- gcc/cp/typeck.c     (revision 266771)
+++ gcc/cp/typeck.c     (revision 266772)
@@ -2422,7 +2422,13 @@ build_class_member_access_expr (cp_expr
   {
     tree temp = unary_complex_lvalue (ADDR_EXPR, object);
     if (temp)
-      object = cp_build_fold_indirect_ref (temp);
+      {
+       temp = cp_build_fold_indirect_ref (temp);
+       if (xvalue_p (object) && !xvalue_p (temp))
+         /* Preserve xvalue kind.  */
+         temp = move (temp);
+       object = temp;
+      }
   }
 
   /* In [expr.ref], there is an explicit list of the valid choices for
--- gcc/testsuite/g++.dg/cpp0x/rv-cond3.C       (nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/rv-cond3.C       (revision 266772)
@@ -0,0 +1,22 @@
+// PR c++/88103
+// { dg-do compile { target c++11 } }
+
+struct A {
+  A (int);
+  A&& foo () &&;
+  int i;
+};
+void free (A&&);
+
+void test_xvalue (A a){
+  A&& ref = true ? static_cast<A&&> (a) : static_cast<A&&> (a); 
+  free (true ? static_cast<A&&> (a) : static_cast<A&&> (a));
+  (true ? static_cast<A&&> (a) : static_cast<A&&> (a)).foo ();
+  int&& k = (true ? static_cast<A&&> (a) : static_cast<A&&> (a)).i;
+}
+void test_prvalue (A a){
+  A&& ref = true ? static_cast<A&&> (a) : 1; 
+  free (true ? static_cast<A&&> (a) : 1);
+  (true ? static_cast<A&&> (a) : 1).foo ();
+  int&& k = (true ? static_cast<A&&> (a) : 1).i;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-04  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/87320
        * gcc.dg/pr87320.c: New test.

--- gcc/testsuite/gcc.dg/pr87320.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr87320.c      (revision 266805)
@@ -0,0 +1,28 @@
+/* PR tree-optimization/87320 */
+/* { dg-do run } */
+/* { dg-options "-O3" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+static void __attribute__ ((noinline))
+transpose_vector (unsigned long n)
+{
+  unsigned long data[2 * n];
+  for (unsigned long i = 0; i < 2 * n; i++)
+    data[i] = 4 * i + 2;
+
+  unsigned long transposed[n];
+  for (unsigned long i = 0; i < n; i++)
+    transposed[i] = data[2 * i];
+
+  for (unsigned long i = 0; i < n; i++)
+    if (transposed[i] != 8 * i + 2)
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  transpose_vector (4);
+  transpose_vector (120);
+  return 0;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-05  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/87360
        * gimple-loop-jam.c (tree_loop_unroll_and_jam): On failure to analyze
        data dependencies, don't return false, just continue.

        * g++.dg/opt/pr87360.C: New test.
        * gfortran.dg/pr87360.f90: New test.

--- gcc/gimple-loop-jam.c       (revision 266819)
+++ gcc/gimple-loop-jam.c       (revision 266820)
@@ -455,7 +455,7 @@ tree_loop_unroll_and_jam (void)
            fprintf (dump_file, "Cannot analyze data dependencies\n");
          free_data_refs (datarefs);
          free_dependence_relations (dependences);
-         return false;
+         continue;
        }
       if (!datarefs.length ())
        continue;
--- gcc/testsuite/g++.dg/opt/pr87360.C  (nonexistent)
+++ gcc/testsuite/g++.dg/opt/pr87360.C  (revision 266820)
@@ -0,0 +1,27 @@
+// PR tree-optimization/87360
+// { dg-do compile { target size32plus } }
+// { dg-options "-O3 -fno-tree-dce --param unroll-jam-min-percent=0" }
+
+void abort (void);
+
+void foo (int N)
+{
+  int i, j;
+  int x[1000][1000];
+
+  for (i = 0; i < N; i++)
+    for (j = 0; j < N; j++)
+      x[i][j] = i + j + 3;
+
+  for (i = 0; i < N; i++)
+    for (j = 0; j < N; j++)
+      if (x[i][j] != i + j + 3)
+       abort ();
+}
+
+int main(void)
+{
+  foo (1000);
+
+  return 0;
+}
--- gcc/testsuite/gfortran.dg/pr87360.f90       (nonexistent)
+++ gcc/testsuite/gfortran.dg/pr87360.f90       (revision 266820)
@@ -0,0 +1,5 @@
+! PR tree-optimization/87360
+! { dg-do compile }
+! { dg-options "-fno-tree-dce -O3 --param max-completely-peeled-insns=0" }
+
+include 'function_optimize_2.f90'
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-06  Jakub Jelinek  <ja...@redhat.com>

        PR target/87598
        * config/aarch64/aarch64.c (aarch64_print_address_internal): Don't
        call output_operand_lossage on VOIDmode CONST_INTs.  After
        output_operand_lossage do return false.

        * gcc.target/aarch64/asm-5.c: New test.

--- gcc/config/aarch64/aarch64.c        (revision 266851)
+++ gcc/config/aarch64/aarch64.c        (revision 266852)
@@ -7635,8 +7635,13 @@ aarch64_print_address_internal (FILE *f,
   unsigned int size;
 
   /* Check all addresses are Pmode - including ILP32.  */
-  if (GET_MODE (x) != Pmode)
-    output_operand_lossage ("invalid address mode");
+  if (GET_MODE (x) != Pmode
+      && (!CONST_INT_P (x)
+         || trunc_int_for_mode (INTVAL (x), Pmode) != INTVAL (x)))
+    {
+      output_operand_lossage ("invalid address mode");
+      return false;
+    }
 
   if (aarch64_classify_address (&addr, x, mode, true, type))
     switch (addr.type)
--- gcc/testsuite/gcc.target/aarch64/asm-5.c    (nonexistent)
+++ gcc/testsuite/gcc.target/aarch64/asm-5.c    (revision 266852)
@@ -0,0 +1,8 @@
+/* PR target/87598 */
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  __asm__ ("# %a0" : : "i" (0));
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-07  Jakub Jelinek  <ja...@redhat.com>

        PR c++/87506
        * constexpr.c (adjust_temp_type): Handle EMPTY_CLASS_EXPR.

        * g++.dg/cpp0x/constexpr-87506.C: New test.

--- gcc/cp/constexpr.c  (revision 266876)
+++ gcc/cp/constexpr.c  (revision 266877)
@@ -1281,6 +1281,8 @@ adjust_temp_type (tree type, tree temp)
   /* Avoid wrapping an aggregate value in a NOP_EXPR.  */
   if (TREE_CODE (temp) == CONSTRUCTOR)
     return build_constructor (type, CONSTRUCTOR_ELTS (temp));
+  if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
+    return build0 (EMPTY_CLASS_EXPR, type);
   gcc_assert (scalarish_type_p (type));
   return cp_fold_convert (type, temp);
 }
--- gcc/testsuite/g++.dg/cpp0x/constexpr-87506.C        (nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-87506.C        (revision 266877)
@@ -0,0 +1,12 @@
+// PR c++/87506
+// { dg-do compile { target c++11 } }
+
+struct A {};
+struct B { constexpr B (const A) {} };
+struct C : B { using B::B; };
+
+void
+foo ()
+{
+  C c (A{});
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-07  Jakub Jelinek  <ja...@redhat.com>

        PR fortran/88377
        * trans-openmp.c (gfc_omp_clause_default_ctor,
        gfc_omp_clause_copy_ctor, gfc_omp_clause_assign_op,
        gfc_omp_clause_linear_ctor, gfc_omp_clause_dtor): Only consider
        GFC_DECL_GET_SCALAR_ALLOCATABLE vars as scalar allocatables if they
        have pointer type.

        * gfortran.dg/gomp/pr88377.f90: New test.

--- gcc/fortran/trans-openmp.c  (revision 266878)
+++ gcc/fortran/trans-openmp.c  (revision 266879)
@@ -460,7 +460,8 @@ gfc_omp_clause_default_ctor (tree clause
 
   if ((! GFC_DESCRIPTOR_TYPE_P (type)
        || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
-      && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
+      && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause))
+         || !POINTER_TYPE_P (type)))
     {
       if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
        {
@@ -567,7 +568,8 @@ gfc_omp_clause_copy_ctor (tree clause, t
 
   if ((! GFC_DESCRIPTOR_TYPE_P (type)
        || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
-      && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
+      && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause))
+         || !POINTER_TYPE_P (type)))
     {
       if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
        {
@@ -667,7 +669,8 @@ gfc_omp_clause_assign_op (tree clause, t
 
   if ((! GFC_DESCRIPTOR_TYPE_P (type)
        || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
-      && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
+      && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause))
+         || !POINTER_TYPE_P (type)))
     {
       if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
        {
@@ -905,7 +908,8 @@ gfc_omp_clause_linear_ctor (tree clause,
 
   if ((! GFC_DESCRIPTOR_TYPE_P (type)
        || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
-      && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
+      && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause))
+         || !POINTER_TYPE_P (type)))
     {
       gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
       if (!TYPE_DOMAIN (type)
@@ -989,7 +993,8 @@ gfc_omp_clause_dtor (tree clause, tree d
 
   if ((! GFC_DESCRIPTOR_TYPE_P (type)
        || GFC_TYPE_ARRAY_AKIND (type) != GFC_ARRAY_ALLOCATABLE)
-      && !GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause)))
+      && (!GFC_DECL_GET_SCALAR_ALLOCATABLE (OMP_CLAUSE_DECL (clause))
+         || !POINTER_TYPE_P (type)))
     {
       if (gfc_has_alloc_comps (type, OMP_CLAUSE_DECL (clause)))
        return gfc_walk_alloc_comps (decl, NULL_TREE,
--- gcc/testsuite/gfortran.dg/gomp/pr88377.f90  (nonexistent)
+++ gcc/testsuite/gfortran.dg/gomp/pr88377.f90  (revision 266879)
@@ -0,0 +1,15 @@
+! PR fortran/88377
+! { dg-do compile }
+
+program pr88377
+  call s(3)
+contains
+  subroutine s(n)
+    integer :: n
+    character(n), allocatable :: x
+    x = 'abc'
+    !$omp task
+    print *, x, (x == 'abc')
+    !$omp end task
+  end
+end
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-07  Jakub Jelinek  <ja...@redhat.com>

        PR target/85593
        * final.c (rest_of_handle_final): Don't call collect_fn_hard_reg_usage
        for functions with naked attribute.

        * gcc.target/i386/pr85593.c: New test.

--- gcc/final.c (revision 266880)
+++ gcc/final.c (revision 266881)
@@ -4659,7 +4659,11 @@ rest_of_handle_final (void)
   final_start_function_1 (&first, asm_out_file, &seen, optimize);
   final_1 (first, asm_out_file, seen, optimize);
   if (flag_ipa_ra
-      && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl)))
+      && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl))
+      /* Functions with naked attributes are supported only with basic asm
+        statements in the body, thus for supported use cases the information
+        on clobbered registers is not available.  */
+      && !lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)))
     collect_fn_hard_reg_usage ();
   final_end_function ();
 
--- gcc/testsuite/gcc.target/i386/pr85593.c     (nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr85593.c     (revision 266881)
@@ -0,0 +1,30 @@
+/* PR target/85593 */
+/* { dg-do run { target { { i?86-*-linux* x86_64-*-linux* } && lp64 } } } */
+/* { dg-options "-O2" } */
+
+__attribute__((naked)) void
+bar (void)
+{
+  asm ("xorl %eax, %eax\n\t"
+       "xorl %edx, %edx\n\t"
+       "xorl %ecx, %ecx\n\t"
+       "xorl %esi, %esi\n\t"
+       "xorl %edi, %edi\n\t"
+       "xorl %r8d, %r8d\n\t"
+       "xorl %r9d, %r9d\n\t"
+       "xorl %r10d, %r10d\n\t"
+       "xorl %r11d, %r11d\n\t"
+       "ret");
+}
+
+int
+main ()
+{
+  int a = 42;
+  asm ("" : "+r" (a));
+  bar ();
+  asm ("" : "+r" (a));
+  if (a != 42)
+    __builtin_abort ();
+  return 0;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-07  Jakub Jelinek  <ja...@redhat.com>

        PR c++/86669
        * call.c (make_temporary_var_for_ref_to_temp): Call pushdecl even for
        automatic vars.

        * g++.dg/cpp0x/initlist105.C: New test.
        * g++.dg/cpp0x/initlist106.C: New test.
        * g++.dg/other/pr86669.C: New test.

--- gcc/cp/call.c       (revision 266892)
+++ gcc/cp/call.c       (revision 266893)
@@ -11148,14 +11148,12 @@ make_temporary_var_for_ref_to_temp (tree
       tree name = mangle_ref_init_variable (decl);
       DECL_NAME (var) = name;
       SET_DECL_ASSEMBLER_NAME (var, name);
-
-      var = pushdecl (var);
     }
   else
     /* Create a new cleanup level if necessary.  */
     maybe_push_cleanup_level (type);
 
-  return var;
+  return pushdecl (var);
 }
 
 /* EXPR is the initializer for a variable DECL of reference or
--- gcc/testsuite/g++.dg/cpp0x/initlist105.C    (nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/initlist105.C    (revision 266893)
@@ -0,0 +1,28 @@
+// PR c++/86669
+// { dg-do run { target c++11 } }
+
+#include <initializer_list>
+
+struct S { S (); };
+struct T : public S {};
+int cnt;
+void foo (int) { cnt++; }
+
+S::S ()
+{
+  int e = 1, f = 2, g = 3, h = 4;
+
+  for (auto k : { e, f, g, h })
+    foo (k);
+}
+
+int
+main ()
+{
+  S s;
+  if (cnt != 4)
+    __builtin_abort ();
+  T t;
+  if (cnt != 8)
+    __builtin_abort ();
+}
--- gcc/testsuite/g++.dg/cpp0x/initlist106.C    (nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/initlist106.C    (revision 266893)
@@ -0,0 +1,29 @@
+// PR c++/86669
+// { dg-do run { target c++11 } }
+
+#include <initializer_list>
+
+struct A { };
+struct S : virtual public A { S (); };
+struct T : public S, virtual public A {};
+int cnt;
+void foo (int) { cnt++; }
+
+S::S ()
+{
+  int e = 1, f = 2, g = 3, h = 4;
+
+  for (auto k : { e, f, g, h })
+    foo (k);
+}
+
+int
+main ()
+{
+  S s;
+  if (cnt != 4)
+    __builtin_abort ();
+  T t;
+  if (cnt != 8)
+    __builtin_abort ();
+}
--- gcc/testsuite/g++.dg/other/pr86669.C        (nonexistent)
+++ gcc/testsuite/g++.dg/other/pr86669.C        (revision 266893)
@@ -0,0 +1,10 @@
+// PR c++/86669
+// { dg-do compile }
+
+struct S { S (); };
+struct T : public S {};
+
+S::S ()
+{
+  int *p = { (int *) &p };
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-11  Jakub Jelinek  <ja...@redhat.com>

        PR sanitizer/88426
        * c-convert.c (convert): Call c_fully_fold before calling
        ubsan_instrument_float_cast.

        * c-c++-common/ubsan/float-cast-overflow-11.c: New test.

--- gcc/c/c-convert.c   (revision 267021)
+++ gcc/c/c-convert.c   (revision 267022)
@@ -115,6 +115,7 @@ convert (tree type, tree expr)
          && COMPLETE_TYPE_P (type))
        {
          expr = save_expr (expr);
+         expr = c_fully_fold (expr, false, NULL);
          tree check = ubsan_instrument_float_cast (loc, type, expr);
          expr = fold_build1 (FIX_TRUNC_EXPR, type, expr);
          if (check == NULL_TREE)
--- gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-11.c   (nonexistent)
+++ gcc/testsuite/c-c++-common/ubsan/float-cast-overflow-11.c   (revision 
267022)
@@ -0,0 +1,10 @@
+/* PR sanitizer/88426 */
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=float-cast-overflow" } */
+
+int
+foo (void)
+{
+  const float v = 0.0f;
+  return (int) (v < 0.0f ? v : 0.0f);
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-12  Jakub Jelinek  <ja...@redhat.com>

        PR fortran/88463
        * trans-openmp.c (gfc_omp_predetermined_sharing): Handle TREE_READONLY
        VAR_DECLs with DECL_EXTERNAL like those with TREE_STATIC.

        * testsuite/libgomp.fortran/pr88463-1.f90: New test.
        * testsuite/libgomp.fortran/pr88463-2.f90: New test.

--- gcc/fortran/trans-openmp.c  (revision 267068)
+++ gcc/fortran/trans-openmp.c  (revision 267069)
@@ -149,7 +149,8 @@ gfc_omp_predetermined_sharing (tree decl
      variables at all (they can't be redefined), but they can nevertheless 
appear
      in parallel/task regions and for default(none) purposes treat them as 
shared.
      For vtables likely the same handling is desirable.  */
-  if (VAR_P (decl) && TREE_READONLY (decl) && TREE_STATIC (decl))
+  if (VAR_P (decl) && TREE_READONLY (decl)
+      && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)))
     return OMP_CLAUSE_DEFAULT_SHARED;
 
   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
--- libgomp/testsuite/libgomp.fortran/pr88463-1.f90     (nonexistent)
+++ libgomp/testsuite/libgomp.fortran/pr88463-1.f90     (revision 267069)
@@ -0,0 +1,19 @@
+! PR fortran/88463
+! { dg-do compile { target { ! *-*-* } } }
+
+module pr88463_1
+  integer, parameter :: c = 1
+  real, parameter :: d(4) = (/ 2, 3, 4, 5 /)
+end module pr88463_1
+
+program pr88463
+  use pr88463_1
+  use pr88463_2
+  integer :: i
+  real :: j(4)
+  !$omp parallel default(none) private (i, j)
+    i = a + b(1) + b(4) + c + d(1) + d(4)
+    j(1:4) = b(1:4)
+    j(1:4) = d(1:4)
+  !$omp end parallel
+end program pr88463
--- libgomp/testsuite/libgomp.fortran/pr88463-2.f90     (nonexistent)
+++ libgomp/testsuite/libgomp.fortran/pr88463-2.f90     (revision 267069)
@@ -0,0 +1,9 @@
+! PR fortran/88463
+! { dg-do link }
+! { dg-options "-fopenmp" }
+! { dg-additional-sources pr88463-1.f90 }
+
+module pr88463_2
+  integer, parameter :: a = 1
+  real, parameter :: b(4) = (/ 2., 3., 4., 5. /)
+end module pr88463_2
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-13  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/88416
        * valtrack.c (cleanup_auto_inc_dec): Handle pre/post-inc/dec/modify
        even if !AUTO_INC_DEC.

        * gcc.target/i386/pr88416.c: New test.

--- gcc/valtrack.c      (revision 267104)
+++ gcc/valtrack.c      (revision 267105)
@@ -56,8 +56,6 @@ static rtx
 cleanup_auto_inc_dec (rtx src, machine_mode mem_mode ATTRIBUTE_UNUSED)
 {
   rtx x = src;
-  if (!AUTO_INC_DEC)
-    return copy_rtx (x);
 
   const RTX_CODE code = GET_CODE (x);
   int i;
--- gcc/testsuite/gcc.target/i386/pr88416.c     (nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr88416.c     (revision 267105)
@@ -0,0 +1,5 @@
+/* PR rtl-optimization/88416 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -fvar-tracking-assignments -fno-forward-propagate --param 
max-cse-insns=1" } */
+
+#include "writeeflags-1.c"
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-13  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/88470
        * cfgcleanup.c (outgoing_edges_match): If the function is
        shrink-wrapped and bb1 ends with a JUMP_INSN with a single fake
        edge to EXIT, return false.

        * gcc.target/i386/pr88470.c: New test.

--- gcc/cfgcleanup.c    (revision 267111)
+++ gcc/cfgcleanup.c    (revision 267112)
@@ -1592,10 +1592,13 @@ outgoing_edges_match (int mode, basic_bl
   if (crtl->shrink_wrapped
       && single_succ_p (bb1)
       && single_succ (bb1) == EXIT_BLOCK_PTR_FOR_FN (cfun)
-      && !JUMP_P (BB_END (bb1))
+      && (!JUMP_P (BB_END (bb1))
+         /* Punt if the only successor is a fake edge to exit, the jump
+            must be some weird one.  */
+         || (single_succ_edge (bb1)->flags & EDGE_FAKE) != 0)
       && !(CALL_P (BB_END (bb1)) && SIBLING_CALL_P (BB_END (bb1))))
     return false;
-  
+
   /* If BB1 has only one successor, we may be looking at either an
      unconditional jump, or a fake edge to exit.  */
   if (single_succ_p (bb1)
--- gcc/testsuite/gcc.target/i386/pr88470.c     (nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr88470.c     (revision 267112)
@@ -0,0 +1,16 @@
+/* PR rtl-optimization/88470 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -maccumulate-outgoing-args -ftrapv -fno-ivopts 
-fno-reorder-blocks-and-partition" } */
+
+void
+foo (long x, long *y)
+{
+  long *a = y - 64, i;
+  for (i = 0; i < x; i++)
+    {
+      long v = y[i];
+      *a++ = v;
+    }
+  register void **c __asm__ ("di");
+  goto **c;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-14  Jakub Jelinek  <ja...@redhat.com>

        PR c++/82294
        PR c++/87436
        * init.c (build_vec_init): Change num_initialized_elts type from int
        to HOST_WIDE_INT.  Build a RANGE_EXPR if e needs to be repeated more
        than once.

--- gcc/cp/init.c       (revision 267141)
+++ gcc/cp/init.c       (revision 267142)
@@ -4104,7 +4104,7 @@ build_vec_init (tree base, tree maxindex
   tree compound_stmt;
   int destroy_temps;
   tree try_block = NULL_TREE;
-  int num_initialized_elts = 0;
+  HOST_WIDE_INT num_initialized_elts = 0;
   bool is_global;
   tree obase = base;
   bool xvalue = false;
@@ -4539,10 +4539,13 @@ build_vec_init (tree base, tree maxindex
 
          if (e)
            {
-             int max = tree_to_shwi (maxindex)+1;
-             for (; num_initialized_elts < max; ++num_initialized_elts)
+             HOST_WIDE_INT last = tree_to_shwi (maxindex);
+             if (num_initialized_elts <= last)
                {
                  tree field = size_int (num_initialized_elts);
+                 if (num_initialized_elts != last)
+                   field = build2 (RANGE_EXPR, sizetype, field,
+                                   size_int (last));
                  CONSTRUCTOR_APPEND_ELT (const_vec, field, e);
                }
            }
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-14  Jakub Jelinek  <ja...@redhat.com>

        PR c++/82294
        PR c++/87436
        * expr.h (categorize_ctor_elements): Add p_unique_nz_elts argument.
        * expr.c (categorize_ctor_elements_1): Likewise.  Compute it like
        p_nz_elts, except don't multiply it by mult.  Adjust recursive call.
        Fix up COMPLEX_CST handling.
        (categorize_ctor_elements): Add p_unique_nz_elts argument, initialize
        it and pass it through to categorize_ctor_elements_1.
        (mostly_zeros_p, all_zeros_p): Adjust categorize_ctor_elements callers.
        * gimplify.c (gimplify_init_constructor): Likewise.  Don't force
        ctor into readonly data section if num_unique_nonzero_elements is
        smaller or equal to 1/8 of num_nonzero_elements and size is >= 64
        bytes.

        * g++.dg/tree-ssa/pr82294.C: New test.
        * g++.dg/tree-ssa/pr87436.C: New test.

--- gcc/expr.c  (revision 267142)
+++ gcc/expr.c  (revision 267143)
@@ -5945,10 +5945,11 @@ count_type_elements (const_tree type, bo
 
 static bool
 categorize_ctor_elements_1 (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
+                           HOST_WIDE_INT *p_unique_nz_elts,
                            HOST_WIDE_INT *p_init_elts, bool *p_complete)
 {
   unsigned HOST_WIDE_INT idx;
-  HOST_WIDE_INT nz_elts, init_elts, num_fields;
+  HOST_WIDE_INT nz_elts, unique_nz_elts, init_elts, num_fields;
   tree value, purpose, elt_type;
 
   /* Whether CTOR is a valid constant initializer, in accordance with what
@@ -5958,6 +5959,7 @@ categorize_ctor_elements_1 (const_tree c
   bool const_p = const_from_elts_p ? true : TREE_STATIC (ctor);
 
   nz_elts = 0;
+  unique_nz_elts = 0;
   init_elts = 0;
   num_fields = 0;
   elt_type = NULL_TREE;
@@ -5982,12 +5984,13 @@ categorize_ctor_elements_1 (const_tree c
        {
        case CONSTRUCTOR:
          {
-           HOST_WIDE_INT nz = 0, ic = 0;
+           HOST_WIDE_INT nz = 0, unz = 0, ic = 0;
 
-           bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &ic,
-                                                          p_complete);
+           bool const_elt_p = categorize_ctor_elements_1 (value, &nz, &unz,
+                                                          &ic, p_complete);
 
            nz_elts += mult * nz;
+           unique_nz_elts += unz;
            init_elts += mult * ic;
 
            if (const_from_elts_p && const_p)
@@ -5999,21 +6002,31 @@ categorize_ctor_elements_1 (const_tree c
        case REAL_CST:
        case FIXED_CST:
          if (!initializer_zerop (value))
-           nz_elts += mult;
+           {
+             nz_elts += mult;
+             unique_nz_elts++;
+           }
          init_elts += mult;
          break;
 
        case STRING_CST:
          nz_elts += mult * TREE_STRING_LENGTH (value);
+         unique_nz_elts += TREE_STRING_LENGTH (value);
          init_elts += mult * TREE_STRING_LENGTH (value);
          break;
 
        case COMPLEX_CST:
          if (!initializer_zerop (TREE_REALPART (value)))
-           nz_elts += mult;
+           {
+             nz_elts += mult;
+             unique_nz_elts++;
+           }
          if (!initializer_zerop (TREE_IMAGPART (value)))
-           nz_elts += mult;
-         init_elts += mult;
+           {
+             nz_elts += mult;
+             unique_nz_elts++;
+           }
+         init_elts += 2 * mult;
          break;
 
        case VECTOR_CST:
@@ -6025,7 +6038,10 @@ categorize_ctor_elements_1 (const_tree c
              {
                tree v = VECTOR_CST_ELT (value, i);
                if (!initializer_zerop (v))
-                 nz_elts += mult;
+                 {
+                   nz_elts += mult;
+                   unique_nz_elts++;
+                 }
                init_elts += mult;
              }
          }
@@ -6035,6 +6051,7 @@ categorize_ctor_elements_1 (const_tree c
          {
            HOST_WIDE_INT tc = count_type_elements (elt_type, false);
            nz_elts += mult * tc;
+           unique_nz_elts += tc;
            init_elts += mult * tc;
 
            if (const_from_elts_p && const_p)
@@ -6054,6 +6071,7 @@ categorize_ctor_elements_1 (const_tree c
     *p_complete = false;
 
   *p_nz_elts += nz_elts;
+  *p_unique_nz_elts += unique_nz_elts;
   *p_init_elts += init_elts;
 
   return const_p;
@@ -6062,6 +6080,11 @@ categorize_ctor_elements_1 (const_tree c
 /* Examine CTOR to discover:
    * how many scalar fields are set to nonzero values,
      and place it in *P_NZ_ELTS;
+   * the same, but counting RANGE_EXPRs as multiplier of 1 instead of
+     high - low + 1 (this can be useful for callers to determine ctors
+     that could be cheaply initialized with - perhaps nested - loops
+     compared to copied from huge read-only data),
+     and place it in *P_UNIQUE_NZ_ELTS;
    * how many scalar fields in total are in CTOR,
      and place it in *P_ELT_COUNT.
    * whether the constructor is complete -- in the sense that every
@@ -6073,13 +6096,16 @@ categorize_ctor_elements_1 (const_tree c
 
 bool
 categorize_ctor_elements (const_tree ctor, HOST_WIDE_INT *p_nz_elts,
+                         HOST_WIDE_INT *p_unique_nz_elts,
                          HOST_WIDE_INT *p_init_elts, bool *p_complete)
 {
   *p_nz_elts = 0;
+  *p_unique_nz_elts = 0;
   *p_init_elts = 0;
   *p_complete = true;
 
-  return categorize_ctor_elements_1 (ctor, p_nz_elts, p_init_elts, p_complete);
+  return categorize_ctor_elements_1 (ctor, p_nz_elts, p_unique_nz_elts,
+                                    p_init_elts, p_complete);
 }
 
 /* TYPE is initialized by a constructor with NUM_ELTS elements, the last
@@ -6110,17 +6136,18 @@ complete_ctor_at_level_p (const_tree typ
   return count_type_elements (type, true) == num_elts;
 }
 
-/* Return 1 if EXP contains mostly (3/4)  zeros.  */
+/* Return 1 if EXP contains mostly (3/4) zeros.  */
 
 static int
 mostly_zeros_p (const_tree exp)
 {
   if (TREE_CODE (exp) == CONSTRUCTOR)
     {
-      HOST_WIDE_INT nz_elts, init_elts;
+      HOST_WIDE_INT nz_elts, unz_elts, init_elts;
       bool complete_p;
 
-      categorize_ctor_elements (exp, &nz_elts, &init_elts, &complete_p);
+      categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
+                               &complete_p);
       return !complete_p || nz_elts < init_elts / 4;
     }
 
@@ -6134,10 +6161,11 @@ all_zeros_p (const_tree exp)
 {
   if (TREE_CODE (exp) == CONSTRUCTOR)
     {
-      HOST_WIDE_INT nz_elts, init_elts;
+      HOST_WIDE_INT nz_elts, unz_elts, init_elts;
       bool complete_p;
 
-      categorize_ctor_elements (exp, &nz_elts, &init_elts, &complete_p);
+      categorize_ctor_elements (exp, &nz_elts, &unz_elts, &init_elts,
+                               &complete_p);
       return nz_elts == 0;
     }
 
--- gcc/expr.h  (revision 267142)
+++ gcc/expr.h  (revision 267143)
@@ -309,7 +309,8 @@ extern bool can_move_by_pieces (unsigned
 extern unsigned HOST_WIDE_INT highest_pow2_factor (const_tree);
 
 extern bool categorize_ctor_elements (const_tree, HOST_WIDE_INT *,
-                                     HOST_WIDE_INT *, bool *);
+                                     HOST_WIDE_INT *, HOST_WIDE_INT *,
+                                     bool *);
 
 extern void expand_operands (tree, tree, rtx, rtx*, rtx*,
                             enum expand_modifier);
--- gcc/gimplify.c      (revision 267142)
+++ gcc/gimplify.c      (revision 267143)
@@ -4778,7 +4778,15 @@ gimplify_init_constructor (tree *expr_p,
       {
        struct gimplify_init_ctor_preeval_data preeval_data;
        HOST_WIDE_INT num_ctor_elements, num_nonzero_elements;
+       HOST_WIDE_INT num_unique_nonzero_elements;
        bool cleared, complete_p, valid_const_initializer;
+       /* Use readonly data for initializers of this or smaller size
+          regardless of the num_nonzero_elements / num_unique_nonzero_elements
+          ratio.  */
+       const HOST_WIDE_INT min_unique_size = 64;
+       /* If num_nonzero_elements / num_unique_nonzero_elements ratio
+          is smaller than this, use readonly data.  */
+       const int unique_nonzero_ratio = 8;
 
        /* Aggregate types must lower constructors to initialization of
           individual elements.  The exception is that a CONSTRUCTOR node
@@ -4795,6 +4803,7 @@ gimplify_init_constructor (tree *expr_p,
           can only do so if it known to be a valid constant initializer.  */
        valid_const_initializer
          = categorize_ctor_elements (ctor, &num_nonzero_elements,
+                                     &num_unique_nonzero_elements,
                                      &num_ctor_elements, &complete_p);
 
        /* If a const aggregate variable is being initialized, then it
@@ -4803,7 +4812,15 @@ gimplify_init_constructor (tree *expr_p,
            && num_nonzero_elements > 1
            && TREE_READONLY (object)
            && VAR_P (object)
-           && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object)))
+           && (flag_merge_constants >= 2 || !TREE_ADDRESSABLE (object))
+           /* For ctors that have many repeated nonzero elements
+              represented through RANGE_EXPRs, prefer initializing
+              those through runtime loops over copies of large amounts
+              of data from readonly data section.  */
+           && (num_unique_nonzero_elements
+               > num_nonzero_elements / unique_nonzero_ratio
+               || ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
+                   <= (unsigned HOST_WIDE_INT) min_unique_size)))
          {
            if (notify_temp_creation)
              return GS_ERROR;
@@ -4896,6 +4913,13 @@ gimplify_init_constructor (tree *expr_p,
               is so large as to make individual moves inefficient.  */
            if (size > 0
                && num_nonzero_elements > 1
+               /* For ctors that have many repeated nonzero elements
+                  represented through RANGE_EXPRs, prefer initializing
+                  those through runtime loops over copies of large amounts
+                  of data from readonly data section.  */
+               && (num_unique_nonzero_elements
+                   > num_nonzero_elements / unique_nonzero_ratio
+                   || size <= min_unique_size)
                && (size < num_nonzero_elements
                    || !can_move_by_pieces (size, align)))
              {
--- gcc/testsuite/g++.dg/tree-ssa/pr82294.C     (nonexistent)
+++ gcc/testsuite/g++.dg/tree-ssa/pr82294.C     (revision 267143)
@@ -0,0 +1,13 @@
+// PR c++/82294
+// { dg-do compile { target c++11 } }
+// { dg-options "-O2 -fdump-tree-gimple" }
+
+// Verify we don't "optimize" the ctor as copying a 1KB .rodata
+// object into the variable.  It is better to initialize it through
+// a loop.
+// { dg-final { scan-tree-dump-not "this->arr = " "gimple" } }
+
+struct S { int x; explicit constexpr S (); };
+constexpr S::S () : x{7} {}
+struct T { S arr[256]; explicit T (); };
+T::T () {}
--- gcc/testsuite/g++.dg/tree-ssa/pr87436.C     (nonexistent)
+++ gcc/testsuite/g++.dg/tree-ssa/pr87436.C     (revision 267143)
@@ -0,0 +1,25 @@
+// PR c++/87436
+// { dg-do compile { target { c++11 && size32plus } } }
+// { dg-options "-O2 -fdump-tree-gimple" }
+
+// Verify we don't "optimize" the ctor as copying a 384MB .rodata
+// object into the variable.  It is better to initialize it through
+// two nested loops.
+// { dg-final { scan-tree-dump-not "this->arr = " "gimple" } }
+
+struct S {
+  int a = -1;
+  short b = 3;
+  int x = 0;
+  int y = 1;
+  int z = 42;
+  float f = 0.123f;
+};
+
+struct T { S arr[4096][4096]; };
+
+T *
+foo ()
+{
+  return new T;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-17  Jakub Jelinek  <ja...@redhat.com>

        PR c++/88410
        * cp-gimplify.c (cp_fold) <case ADDR_EXPR>: For offsetof-like folding,
        call maybe_constant_value on val to see if it is INTEGER_CST.

        * g++.dg/cpp0x/pr88410.C: New test.

--- gcc/cp/cp-gimplify.c        (revision 267219)
+++ gcc/cp/cp-gimplify.c        (revision 267220)
@@ -2317,6 +2317,7 @@ cp_fold (tree x)
            {
              val = TREE_OPERAND (val, 0);
              STRIP_NOPS (val);
+             val = maybe_constant_value (val);
              if (TREE_CODE (val) == INTEGER_CST)
                return fold_offsetof (op0, TREE_TYPE (x));
            }
--- gcc/testsuite/g++.dg/cpp0x/pr88410.C        (nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/pr88410.C        (revision 267220)
@@ -0,0 +1,7 @@
+// PR c++/88410
+// { dg-do compile { target c++11 } }
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+const uintptr_t a = 32;
+struct C { int b; int c; };
+uintptr_t d { uintptr_t (&reinterpret_cast<C *>(a)->c) - a };
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-19  Jakub Jelinek  <ja...@redhat.com>

        PR c++/87934
        * constexpr.c (cxx_eval_constant_expression) <case CONSTRUCTOR>: Do
        re-process TREE_CONSTANT CONSTRUCTORs if they aren't reduced constant
        expressions.

        * g++.dg/cpp0x/constexpr-87934.C: New test.

--- gcc/cp/constexpr.c  (revision 267252)
+++ gcc/cp/constexpr.c  (revision 267253)
@@ -4681,7 +4681,7 @@ cxx_eval_constant_expression (const cons
       break;
 
     case CONSTRUCTOR:
-      if (TREE_CONSTANT (t))
+      if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
        {
          /* Don't re-process a constant CONSTRUCTOR, but do fold it to
             VECTOR_CST if applicable.  */
--- gcc/testsuite/g++.dg/cpp0x/constexpr-87934.C        (nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-87934.C        (revision 267253)
@@ -0,0 +1,9 @@
+// PR c++/87934
+// { dg-do compile { target c++11 } }
+
+struct Foo
+{
+  enum { BAR } bar = BAR;
+};
+
+constexpr Foo foo{};
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-19  Jakub Jelinek  <ja...@redhat.com>

        PR target/88541
        * config/i386/vpclmulqdqintrin.h (_mm256_clmulepi64_epi128): Enable
        for -mavx -mvpclmulqdq rather than just for -mavx512vl -mvpclmulqdq.

        * gcc.target/i386/avx-vpclmulqdq-1.c: New test.

--- gcc/config/i386/vpclmulqdqintrin.h  (revision 267253)
+++ gcc/config/i386/vpclmulqdqintrin.h  (revision 267254)
@@ -53,9 +53,9 @@ _mm512_clmulepi64_epi128 (__m512i __A, _
 #pragma GCC pop_options
 #endif /* __DISABLE_VPCLMULQDQF__ */
 
-#if !defined(__VPCLMULQDQ__) || !defined(__AVX512VL__)
+#if !defined(__VPCLMULQDQ__) || !defined(__AVX__)
 #pragma GCC push_options
-#pragma GCC target("vpclmulqdq,avx512vl")
+#pragma GCC target("vpclmulqdq,avx")
 #define __DISABLE_VPCLMULQDQ__
 #endif /* __VPCLMULQDQ__ */
 
@@ -78,6 +78,4 @@ _mm256_clmulepi64_epi128 (__m256i __A, _
 #pragma GCC pop_options
 #endif /* __DISABLE_VPCLMULQDQ__ */
 
-
 #endif /* _VPCLMULQDQINTRIN_H_INCLUDED */
-
--- gcc/testsuite/gcc.target/i386/avx-vpclmulqdq-1.c    (nonexistent)
+++ gcc/testsuite/gcc.target/i386/avx-vpclmulqdq-1.c    (revision 267254)
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx -mvpclmulqdq" } */
+
+#include <x86intrin.h>
+
+__m256i
+foo (__m256i x, __m256i y)
+{
+  return _mm256_clmulepi64_epi128 (x, y, 0);
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-20  Jakub Jelinek  <ja...@redhat.com>

        PR c++/88180
        * parser.c (cp_parser_class_specifier_1): If
        cp_parser_check_type_definition fails, skip default arguments, NSDMIs,
        etc. like for erroneous template args.

        * g++.dg/parse/pr88180.C: New test.
        * g++.dg/pr85039-1.C: Don't expect diagnostics inside of the type
        definition's NSDMIs.

--- gcc/cp/parser.c     (revision 267305)
+++ gcc/cp/parser.c     (revision 267306)
@@ -23167,7 +23167,7 @@ cp_parser_class_specifier_1 (cp_parser*
   cp_ensure_no_oacc_routine (parser);
 
   /* Issue an error message if type-definitions are forbidden here.  */
-  cp_parser_check_type_definition (parser);
+  bool type_definition_ok_p = cp_parser_check_type_definition (parser);
   /* Remember that we are defining one more class.  */
   ++parser->num_classes_being_defined;
   /* Inside the class, surrounding template-parameter-lists do not
@@ -23362,7 +23362,7 @@ cp_parser_class_specifier_1 (cp_parser*
       cp_default_arg_entry *e;
       tree save_ccp, save_ccr;
 
-      if (any_erroneous_template_args_p (type))
+      if (!type_definition_ok_p || any_erroneous_template_args_p (type))
        {
          /* Skip default arguments, NSDMIs, etc, in order to improve
             error recovery (c++/71169, c++/71832).  */
--- gcc/testsuite/g++.dg/pr85039-1.C    (revision 267305)
+++ gcc/testsuite/g++.dg/pr85039-1.C    (revision 267306)
@@ -5,9 +5,9 @@ constexpr int a() {
   __builtin_offsetof(struct { // { dg-error "types may not be defined" }
     int i;
     short b {
-      __builtin_offsetof(struct { // { dg-error "types may not be defined" }
+      __builtin_offsetof(struct {
        int j;
-        struct c { // { dg-error "types may not be defined" }
+        struct c {
           void d() {
           }
         };
--- gcc/testsuite/g++.dg/parse/pr88180.C        (nonexistent)
+++ gcc/testsuite/g++.dg/parse/pr88180.C        (revision 267306)
@@ -0,0 +1,12 @@
+// PR c++/88180
+// { dg-do compile }
+// { dg-options "--param ggc-min-heapsize=1024" }
+
+struct d {
+  static d *b;
+} * d::b(__builtin_offsetof(struct { // { dg-error "types may not be defined" }
+  int i;
+  struct a { // { dg-error "types may not be defined" }
+    int c() { return .1f; }
+  };
+}, i));
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-21  Jakub Jelinek  <ja...@redhat.com>

        PR rtl-optimization/88563
        * expr.c (expand_expr_real_2) <case WIDEN_MULT_EXPR>: Swap innermode
        and mode arguments to convert_modes.  Likewise swap mode and word_mode
        arguments.  Handle both arguments with VOIDmode before convert_modes
        of one of them.  Formatting fixes.

        * gcc.dg/pr88563.c: New test.

--- gcc/expr.c  (revision 267325)
+++ gcc/expr.c  (revision 267326)
@@ -8775,8 +8775,8 @@ expand_expr_real_2 (sepops ops, rtx targ
                 != INTEGER_CST check.  Handle it.  */
              if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
                {
-                 op0 = convert_modes (innermode, mode, op0, true);
-                 op1 = convert_modes (innermode, mode, op1, false);
+                 op0 = convert_modes (mode, innermode, op0, true);
+                 op1 = convert_modes (mode, innermode, op1, false);
                  return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
                                                        target, unsignedp));
                }
@@ -8798,7 +8798,7 @@ expand_expr_real_2 (sepops ops, rtx targ
          if (TREE_CODE (treeop0) != INTEGER_CST)
            {
              if (find_widening_optab_handler (this_optab, mode, innermode)
-                   != CODE_FOR_nothing)
+                 != CODE_FOR_nothing)
                {
                  expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
                                   EXPAND_NORMAL);
@@ -8807,9 +8807,9 @@ expand_expr_real_2 (sepops ops, rtx targ
                  if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
                    {
                     widen_mult_const:
-                     op0 = convert_modes (innermode, mode, op0, zextend_p);
+                     op0 = convert_modes (mode, innermode, op0, zextend_p);
                      op1
-                       = convert_modes (innermode, mode, op1,
+                       = convert_modes (mode, innermode, op1,
                                         TYPE_UNSIGNED (TREE_TYPE (treeop1)));
                      return REDUCE_BIT_FIELD (expand_mult (mode, op0, op1,
                                                            target,
@@ -8820,21 +8820,19 @@ expand_expr_real_2 (sepops ops, rtx targ
                  return REDUCE_BIT_FIELD (temp);
                }
              if (find_widening_optab_handler (other_optab, mode, innermode)
-                   != CODE_FOR_nothing
+                 != CODE_FOR_nothing
                  && innermode == word_mode)
                {
                  rtx htem, hipart;
                  op0 = expand_normal (treeop0);
-                 if (TREE_CODE (treeop1) == INTEGER_CST)
-                   op1 = convert_modes (word_mode, mode,
-                                        expand_normal (treeop1),
-                                        TYPE_UNSIGNED (TREE_TYPE (treeop1)));
-                 else
-                   op1 = expand_normal (treeop1);
-                 /* op0 and op1 might still be constant, despite the above
+                 op1 = expand_normal (treeop1);
+                 /* op0 and op1 might be constants, despite the above
                     != INTEGER_CST check.  Handle it.  */
                  if (GET_MODE (op0) == VOIDmode && GET_MODE (op1) == VOIDmode)
                    goto widen_mult_const;
+                 if (TREE_CODE (treeop1) == INTEGER_CST)
+                   op1 = convert_modes (mode, word_mode, op1,
+                                        TYPE_UNSIGNED (TREE_TYPE (treeop1)));
                  temp = expand_binop (mode, other_optab, op0, op1, target,
                                       unsignedp, OPTAB_LIB_WIDEN);
                  hipart = gen_highpart (word_mode, temp);
--- gcc/testsuite/gcc.dg/pr88563.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr88563.c      (revision 267326)
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/88563 */
+/* { dg-do run { target int128 } } */
+/* { dg-options "-O2 -fno-code-hoisting -fno-tree-ccp -fno-tree-dominator-opts 
-fno-tree-forwprop -fno-tree-fre -fno-tree-pre -fno-tree-vrp" } */
+
+int
+main ()
+{
+#if __SIZEOF_LONG_LONG__ == 8 && __SIZEOF_INT128__ == 16 && __CHAR_BIT__ == 8
+  unsigned __int128 a = 5;
+  __builtin_mul_overflow (0xffffffffffffffffULL, (unsigned long long) a, &a);
+  if (a != ((unsigned __int128)4 << 64 | 0xfffffffffffffffb))
+    __builtin_abort ();
+#endif
+  return 0;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-21  Jakub Jelinek  <ja...@redhat.com>

        PR target/88522
        * config/i386/sse.md (*avx512pf_gatherpf<mode>sf_mask,
        *avx512pf_gatherpf<mode>df_mask, *avx512pf_scatterpf<mode>sf_mask,
        *avx512pf_scatterpf<mode>df_mask): Use %X5 instead of %5 for
        -masm=intel.
        (gatherq_mode): Remove mode iterator.
        (*avx512f_gathersi<mode>, *avx512f_gathersi<mode>_2): Use X instead
        of <xtg_mode>.
        (*avx512f_gatherdi<mode>): Use X instead of <gatherq_mode>.
        (*avx512f_gatherdi<mode>_2, *avx512f_scattersi<mode>,
        *avx512f_scatterdi<mode>): Use %X5 for -masm=intel.

--- gcc/config/i386/sse.md      (revision 267326)
+++ gcc/config/i386/sse.md      (revision 267327)
@@ -17269,9 +17269,11 @@ (define_insn "*avx512pf_gatherpf<mode>sf
   switch (INTVAL (operands[4]))
     {
     case 3:
-      return "vgatherpf0<ssemodesuffix>ps\t{%5%{%0%}|%5%{%0%}}";
+      /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+        gas changed what it requires incompatibly.  */
+      return "vgatherpf0<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
-      return "vgatherpf1<ssemodesuffix>ps\t{%5%{%0%}|%5%{%0%}}";
+      return "vgatherpf1<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
@@ -17314,9 +17316,11 @@ (define_insn "*avx512pf_gatherpf<mode>df
   switch (INTVAL (operands[4]))
     {
     case 3:
-      return "vgatherpf0<ssemodesuffix>pd\t{%5%{%0%}|%5%{%0%}}";
+      /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+        gas changed what it requires incompatibly.  */
+      return "vgatherpf0<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
-      return "vgatherpf1<ssemodesuffix>pd\t{%5%{%0%}|%5%{%0%}}";
+      return "vgatherpf1<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
@@ -17360,10 +17364,12 @@ (define_insn "*avx512pf_scatterpf<mode>s
     {
     case 3:
     case 7:
-      return "vscatterpf0<ssemodesuffix>ps\t{%5%{%0%}|%5%{%0%}}";
+      /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+        gas changed what it requires incompatibly.  */
+      return "vscatterpf0<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
     case 6:
-      return "vscatterpf1<ssemodesuffix>ps\t{%5%{%0%}|%5%{%0%}}";
+      return "vscatterpf1<ssemodesuffix>ps\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
@@ -17407,10 +17413,12 @@ (define_insn "*avx512pf_scatterpf<mode>d
     {
     case 3:
     case 7:
-      return "vscatterpf0<ssemodesuffix>pd\t{%5%{%0%}|%5%{%0%}}";
+      /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+        gas changed what it requires incompatibly.  */
+      return "vscatterpf0<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     case 2:
     case 6:
-      return "vscatterpf1<ssemodesuffix>pd\t{%5%{%0%}|%5%{%0%}}";
+      return "vscatterpf1<ssemodesuffix>pd\t{%5%{%0%}|%X5%{%0%}}";
     default:
       gcc_unreachable ();
     }
@@ -20290,12 +20298,6 @@ (define_insn "*avx2_gatherdi<mode>_4"
    (set_attr "prefix" "vex")
    (set_attr "mode" "<sseinsnmode>")])
 
-;; Memory operand override for -masm=intel of the v*gatherq* patterns.
-(define_mode_attr gatherq_mode
-  [(V4SI "q") (V2DI "x") (V4SF "q") (V2DF "x")
-   (V8SI "x") (V4DI "t") (V8SF "x") (V4DF "t")
-   (V16SI "t") (V8DI "g") (V16SF "t") (V8DF "g")])
-
 (define_expand "<avx512>_gathersi<mode>"
   [(parallel [(set (match_operand:VI48F 0 "register_operand")
                   (unspec:VI48F
@@ -20329,7 +20331,9 @@ (define_insn "*avx512f_gathersi<mode>"
          UNSPEC_GATHER))
    (clobber (match_scratch:<avx512fmaskmode> 2 "=&Yk"))]
   "TARGET_AVX512F"
-  "v<sseintprefix>gatherd<ssemodesuffix>\t{%6, %0%{%2%}|%0%{%2%}, 
%<xtg_mode>6}"
+;; %X6 so that we don't emit any *WORD PTR for -masm=intel, as
+;; gas changed what it requires incompatibly.
+  "v<sseintprefix>gatherd<ssemodesuffix>\t{%6, %0%{%2%}|%0%{%2%}, %X6}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
@@ -20348,7 +20352,9 @@ (define_insn "*avx512f_gathersi<mode>_2"
          UNSPEC_GATHER))
    (clobber (match_scratch:<avx512fmaskmode> 1 "=&Yk"))]
   "TARGET_AVX512F"
-  "v<sseintprefix>gatherd<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, 
%<xtg_mode>5}"
+;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+;; gas changed what it requires incompatibly.
+  "v<sseintprefix>gatherd<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, %X5}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
@@ -20387,9 +20393,9 @@ (define_insn "*avx512f_gatherdi<mode>"
          UNSPEC_GATHER))
    (clobber (match_scratch:QI 2 "=&Yk"))]
   "TARGET_AVX512F"
-{
-  return "v<sseintprefix>gatherq<ssemodesuffix>\t{%6, %1%{%2%}|%1%{%2%}, 
%<gatherq_mode>6}";
-}
+;; %X6 so that we don't emit any *WORD PTR for -masm=intel, as
+;; gas changed what it requires incompatibly.
+  "v<sseintprefix>gatherq<ssemodesuffix>\t{%6, %1%{%2%}|%1%{%2%}, %X6}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
@@ -20409,14 +20415,16 @@ (define_insn "*avx512f_gatherdi<mode>_2"
    (clobber (match_scratch:QI 1 "=&Yk"))]
   "TARGET_AVX512F"
 {
+  /* %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+     gas changed what it requires incompatibly.  */
   if (<MODE>mode != <VEC_GATHER_SRCDI>mode)
     {
       if (<MODE_SIZE> != 64)
-       return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, 
%x0%{%1%}|%x0%{%1%}, %<gatherq_mode>5}";
+       return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, 
%x0%{%1%}|%x0%{%1%}, %X5}";
       else
-       return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, 
%t0%{%1%}|%t0%{%1%}, %t5}";
+       return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, 
%t0%{%1%}|%t0%{%1%}, %X5}";
     }
-  return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, 
%<gatherq_mode>5}";
+  return "v<sseintprefix>gatherq<ssemodesuffix>\t{%5, %0%{%1%}|%0%{%1%}, %X5}";
 }
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
@@ -20453,7 +20461,9 @@ (define_insn "*avx512f_scattersi<mode>"
          UNSPEC_SCATTER))
    (clobber (match_scratch:<avx512fmaskmode> 1 "=&Yk"))]
   "TARGET_AVX512F"
-  "v<sseintprefix>scatterd<ssemodesuffix>\t{%3, %5%{%1%}|%5%{%1%}, %3}"
+;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+;; gas changed what it requires incompatibly.
+  "v<sseintprefix>scatterd<ssemodesuffix>\t{%3, %5%{%1%}|%X5%{%1%}, %3}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
@@ -20489,11 +20499,9 @@ (define_insn "*avx512f_scatterdi<mode>"
          UNSPEC_SCATTER))
    (clobber (match_scratch:QI 1 "=&Yk"))]
   "TARGET_AVX512F"
-{
-  if (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) == 8)
-    return "v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%5%{%1%}, 
%3}";
-  return "v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%t5%{%1%}, 
%3}";
-}
+;; %X5 so that we don't emit any *WORD PTR for -masm=intel, as
+;; gas changed what it requires incompatibly.
+  "v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%X5%{%1%}, %3}"
   [(set_attr "type" "ssemov")
    (set_attr "prefix" "evex")
    (set_attr "mode" "<sseinsnmode>")])
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2018-12-21  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/85594
        PR middle-end/88553
        * omp-expand.c (extract_omp_for_update_vars): Regimplify the condition
        if needed.
        (expand_omp_for_generic): Don't clobber t temporary for ordered loops.

        * gcc.dg/gomp/pr85594.c: New test.
        * gcc.dg/gomp/pr88553.c: New test.

--- gcc/omp-expand.c    (revision 267338)
+++ gcc/omp-expand.c    (revision 267339)
@@ -2076,6 +2076,11 @@ extract_omp_for_update_vars (struct omp_
          t = fold_build2 (fd->loops[i].cond_code, boolean_type_node, v, t);
          stmt = gimple_build_cond_empty (t);
          gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+         if (walk_tree (gimple_cond_lhs_ptr (as_a <gcond *> (stmt)),
+                        expand_omp_regimplify_p, NULL, NULL)
+             || walk_tree (gimple_cond_rhs_ptr (as_a <gcond *> (stmt)),
+                           expand_omp_regimplify_p, NULL, NULL))
+           gimple_regimplify_operands (stmt, &gsi);
          e = make_edge (bb, body_bb, EDGE_TRUE_VALUE);
          e->probability = profile_probability::guessed_always ().apply_scale 
(7, 8);
        }
@@ -3209,20 +3214,21 @@ expand_omp_for_generic (struct omp_regio
 
          if (fd->ordered && counts[fd->collapse - 1] == NULL_TREE)
            {
+             tree tem;
              if (fd->collapse > 1)
-               t = fd->loop.v;
+               tem = fd->loop.v;
              else
                {
-                 t = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->loops[0].v),
-                                  fd->loops[0].v, fd->loops[0].n1);
-                 t = fold_convert (fd->iter_type, t);
+                 tem = fold_build2 (MINUS_EXPR, TREE_TYPE (fd->loops[0].v),
+                                    fd->loops[0].v, fd->loops[0].n1);
+                 tem = fold_convert (fd->iter_type, tem);
                }
              tree aref = build4 (ARRAY_REF, fd->iter_type,
                                  counts[fd->ordered], size_zero_node,
                                  NULL_TREE, NULL_TREE);
-             t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
-                                           true, GSI_SAME_STMT);
-             expand_omp_build_assign (&gsi, aref, t);
+             tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE,
+                                             true, GSI_SAME_STMT);
+             expand_omp_build_assign (&gsi, aref, tem);
            }
 
          t = build2 (fd->loop.cond_code, boolean_type_node,
--- gcc/testsuite/gcc.dg/gomp/pr85594.c (nonexistent)
+++ gcc/testsuite/gcc.dg/gomp/pr85594.c (revision 267339)
@@ -0,0 +1,5 @@
+/* PR middle-end/85594 */
+/* { dg-do compile } */
+/* { dg-additional-options "-fwrapv" } */
+
+#include "pr81768-2.c"
--- gcc/testsuite/gcc.dg/gomp/pr88553.c (nonexistent)
+++ gcc/testsuite/gcc.dg/gomp/pr88553.c (revision 267339)
@@ -0,0 +1,5 @@
+/* PR middle-end/88553 */
+/* { dg-do compile } */
+/* { dg-additional-options "-O1 -ftree-loop-vectorize -fwrapv" } */
+
+#include "pr81768-2.c"
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-01-03  Jakub Jelinek  <ja...@redhat.com>

        PR debug/88644
        * dwarf2out.c (modified_type_die): If type is equal to sizetype,
        change it to qualified_type.

        * gcc.dg/debug/dwarf2/pr88644.c: New test.

        2019-01-03  Iain Sandoe  <i...@sandoe.co.uk>

        * gcc.dg/pubtypes-2.c: Adjust expected pubtypes length.
        * gcc.dg/pubtypes-3.c: Likewise.
        * gcc.dg/pubtypes-4.c: Likewise.

--- gcc/dwarf2out.c     (revision 267549)
+++ gcc/dwarf2out.c     (revision 267550)
@@ -13152,6 +13152,8 @@ modified_type_die (tree type, int cv_qua
               && TYPE_PRECISION (sizetype) == TYPE_PRECISION (size_type_node)
               && TYPE_UNSIGNED (sizetype) == TYPE_UNSIGNED (size_type_node))
        qualified_type = size_type_node;
+      if (type == sizetype)
+       type = qualified_type;
     }
 
   /* If we do, then we can just use its DIE, if it exists.  */
--- gcc/testsuite/gcc.dg/debug/dwarf2/pr88644.c (nonexistent)
+++ gcc/testsuite/gcc.dg/debug/dwarf2/pr88644.c (revision 267550)
@@ -0,0 +1,7 @@
+/* PR debug/88644 */
+/* { dg-do compile } */
+/* { dg-options "-gdwarf-4 -dA -gpubnames" } */
+
+char array[1];
+
+/* { dg-final { scan-assembler-not {\msizetype} } } */
--- gcc/testsuite/gcc.dg/pubtypes-2.c   (revision 267549)
+++ gcc/testsuite/gcc.dg/pubtypes-2.c   (revision 267550)
@@ -2,7 +2,7 @@
 /* { dg-options "-O0 -gdwarf-2 -dA" } */
 /* { dg-skip-if "Unmatchable assembly" { mmix-*-* } } */
 /* { dg-final { scan-assembler "__debug_pubtypes" } } */
-/* { dg-final { scan-assembler "long+\[ \t\]+0x13b+\[ \t\]+\[#;]+\[ \t\]+Pub 
Info Length" } } */
+/* { dg-final { scan-assembler "long+\[ \t\]+0x12e+\[ \t\]+\[#;]+\[ \t\]+Pub 
Info Length" } } */
 /* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ 
\t\]+external name" } } */
 /* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ 
\t\]+external name" } } */
 
--- gcc/testsuite/gcc.dg/pubtypes-3.c   (revision 267549)
+++ gcc/testsuite/gcc.dg/pubtypes-3.c   (revision 267550)
@@ -2,7 +2,7 @@
 /* { dg-options "-O0 -gdwarf-2 -dA" } */
 /* { dg-skip-if "Unmatchable assembly" { mmix-*-* } } */
 /* { dg-final { scan-assembler "__debug_pubtypes" } } */
-/* { dg-final { scan-assembler "long+\[ \t\]+0x13b+\[ \t\]+\[#;]+\[ \t\]+Pub 
Info Length" } } */
+/* { dg-final { scan-assembler "long+\[ \t\]+0x12e+\[ \t\]+\[#;]+\[ \t\]+Pub 
Info Length" } } */
 /* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ 
\t\]+external name" } } */
 /* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ 
\t\]+external name" } } */
 /* { dg-final { scan-assembler-not "\"list_name_type\\\\0\"+\[ \t\]+\[#;]+\[ 
\t\]+external name" } } */
--- gcc/testsuite/gcc.dg/pubtypes-4.c   (revision 267549)
+++ gcc/testsuite/gcc.dg/pubtypes-4.c   (revision 267550)
@@ -2,7 +2,7 @@
 /* { dg-options "-O0 -gdwarf-2 -dA" } */
 /* { dg-skip-if "Unmatchable assembly" { mmix-*-* } } */
 /* { dg-final { scan-assembler "__debug_pubtypes" } } */
-/* { dg-final { scan-assembler "long+\[ \t\]+0x172+\[ \t\]+\[#;]+\[ \t\]+Pub 
Info Length" } } */
+/* { dg-final { scan-assembler "long+\[ \t\]+0x165+\[ \t\]+\[#;]+\[ \t\]+Pub 
Info Length" } } */
 /* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ 
\t\]+external name" } } */
 /* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ 
\t\]+external name" } } */
 /* { dg-final { scan-assembler "\"list_name_type\\\\0\"+\[ \t\]+\[#;]+\[ 
\t\]+external name" } } */
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-01-04  Jakub Jelinek  <ja...@redhat.com>

        PR target/88594
        * config/i386/i386.c (ix86_expand_divmod_libfunc): Use mode instead
        of GET_MODE (opN) as modes of the libcall arguments.

        * gcc.dg/pr88594.c: New test.

--- gcc/config/i386/i386.c      (revision 267570)
+++ gcc/config/i386/i386.c      (revision 267571)
@@ -51014,9 +51014,7 @@ ix86_expand_divmod_libfunc (rtx libfunc,
   rtx rem = assign_386_stack_local (mode, SLOT_TEMP);
 
   rtx quot = emit_library_call_value (libfunc, NULL_RTX, LCT_NORMAL,
-                                     mode,
-                                     op0, GET_MODE (op0),
-                                     op1, GET_MODE (op1),
+                                     mode, op0, mode, op1, mode,
                                      XEXP (rem, 0), Pmode);
   *quot_p = quot;
   *rem_p = rem;
--- gcc/testsuite/gcc.dg/pr88594.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr88594.c      (revision 267571)
@@ -0,0 +1,16 @@
+/* PR target/88594 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -fno-tree-dominator-opts -fno-tree-forwprop 
-fno-tree-vrp" } */
+
+__int128
+foo (__int128 x, __int128 *y)
+{
+  int a;
+  __int128 z, r;
+  for (a = 0; a < 17; ++a)
+    ;
+  z = x / a;
+  r = x % a;
+  *y = z;
+  return r;
+}
2019-01-08  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2019-01-05  Jakub Jelinek  <ja...@redhat.com>

        PR middle-end/82564
        PR target/88620
        * expr.c (expand_assignment): For calls returning VLA structures
        if to_rtx is not a MEM, force it into a stack temporary.

        * gcc.dg/nested-func-12.c: New test.
        * gcc.c-torture/compile/pr82564.c: New test.

--- gcc/expr.c  (revision 267594)
+++ gcc/expr.c  (revision 267595)
@@ -5254,6 +5254,21 @@ expand_assignment (tree to, tree from, b
              emit_move_insn (XEXP (to_rtx, 1), read_complex_part (temp, true));
            }
        }
+      /* For calls to functions returning variable length structures, if TO_RTX
+        is not a MEM, go through a MEM because we must not create temporaries
+        of the VLA type.  */
+      else if (!MEM_P (to_rtx)
+              && TREE_CODE (from) == CALL_EXPR
+              && COMPLETE_TYPE_P (TREE_TYPE (from))
+              && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) != INTEGER_CST)
+       {
+         rtx temp = assign_stack_temp (GET_MODE (to_rtx),
+                                       GET_MODE_SIZE (GET_MODE (to_rtx)));
+         result = store_field (temp, bitsize, bitpos, bitregion_start,
+                               bitregion_end, mode1, from, get_alias_set (to),
+                               nontemporal, reversep);
+         emit_move_insn (to_rtx, temp);
+       }
       else
        {
          if (MEM_P (to_rtx))
--- gcc/testsuite/gcc.c-torture/compile/pr82564.c       (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr82564.c       (revision 267595)
@@ -0,0 +1,15 @@
+/* PR middle-end/82564 */
+/* { dg-require-effective-target alloca } */
+
+int
+main ()
+{
+  int t = 8, i;
+  typedef struct { char v[t]; } B; 
+  B a, b;
+  B __attribute__ ((noinline)) f () { return b; }
+  for (i = 0; i < 8; i++)
+    b.v[i] = i;
+  a = f ();
+  return 0;
+}
--- gcc/testsuite/gcc.dg/nested-func-12.c       (nonexistent)
+++ gcc/testsuite/gcc.dg/nested-func-12.c       (revision 267595)
@@ -0,0 +1,48 @@
+/* PR target/88620 */
+/* { dg-do run } */
+/* { dg-options "-Ofast --param ipa-cp-eval-threshold=0 
-fno-guess-branch-probability -fno-inline-small-functions" } */
+/* { dg-require-effective-target alloca } */
+
+void
+foo (int n)
+{
+  struct S { int a[n]; };
+
+  struct S
+  fn (void)
+  {
+    struct S s;
+    s.a[0] = 42;
+    return s;
+  }
+
+  auto struct S
+  fn2 (void)
+  {
+    return fn ();
+  }
+
+  struct S x;
+  fn ();
+  fn2 ();
+  x = fn ();
+
+  if (x.a[0] != 42)
+    __builtin_abort ();
+
+  if (fn ().a[0] != 42)
+    __builtin_abort ();
+
+  __typeof__ (fn ()) *p = &x;
+  if (p->a[0] != 42)
+    __builtin_abort ();
+
+  if (fn2 ().a[0] != 42)
+    __builtin_abort ();
+}
+
+int
+main (void)
+{
+  foo (1);
+}

Reply via email to