Hi!

I've bootstrapped/regtested following patches on x86_64-linux and i686-linux
on gcc-6-branch and committed them to 6.x.

        Jakub
2017-02-15  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2017-01-17  Kito Cheng  <kito.ch...@gmail.com>
                    Kuan-Lin Chen  <kuanlinche...@gmail.com>

        PR target/79079
        * internal-fn.c (expand_mul_overflow): Use convert_modes instead of
        gen_lowpart.

--- gcc/internal-fn.c   (revision 244538)
+++ gcc/internal-fn.c   (revision 244539)
@@ -1483,8 +1483,8 @@ expand_mul_overflow (location_t loc, tre
          res = expand_expr_real_2 (&ops, NULL_RTX, wmode, EXPAND_NORMAL);
          rtx hipart = expand_shift (RSHIFT_EXPR, wmode, res, prec,
                                     NULL_RTX, uns);
-         hipart = gen_lowpart (mode, hipart);
-         res = gen_lowpart (mode, res);
+         hipart = convert_modes (mode, wmode, hipart, uns);
+         res = convert_modes (mode, wmode, res, uns);
          if (uns)
            /* For the unsigned multiplication, there was overflow if
               HIPART is non-zero.  */
@@ -1517,16 +1517,16 @@ expand_mul_overflow (location_t loc, tre
          unsigned int hprec = GET_MODE_PRECISION (hmode);
          rtx hipart0 = expand_shift (RSHIFT_EXPR, mode, op0, hprec,
                                      NULL_RTX, uns);
-         hipart0 = gen_lowpart (hmode, hipart0);
-         rtx lopart0 = gen_lowpart (hmode, op0);
+         hipart0 = convert_modes (hmode, mode, hipart0, uns);
+         rtx lopart0 = convert_modes (hmode, mode, op0, uns);
          rtx signbit0 = const0_rtx;
          if (!uns)
            signbit0 = expand_shift (RSHIFT_EXPR, hmode, lopart0, hprec - 1,
                                     NULL_RTX, 0);
          rtx hipart1 = expand_shift (RSHIFT_EXPR, mode, op1, hprec,
                                      NULL_RTX, uns);
-         hipart1 = gen_lowpart (hmode, hipart1);
-         rtx lopart1 = gen_lowpart (hmode, op1);
+         hipart1 = convert_modes (hmode, mode, hipart1, uns);
+         rtx lopart1 = convert_modes (hmode, mode, op1, uns);
          rtx signbit1 = const0_rtx;
          if (!uns)
            signbit1 = expand_shift (RSHIFT_EXPR, hmode, lopart1, hprec - 1,
@@ -1717,11 +1717,12 @@ expand_mul_overflow (location_t loc, tre
             if (loxhi >> (bitsize / 2) == 0             (if uns).  */
          rtx hipartloxhi = expand_shift (RSHIFT_EXPR, mode, loxhi, hprec,
                                          NULL_RTX, 0);
-         hipartloxhi = gen_lowpart (hmode, hipartloxhi);
+         hipartloxhi = convert_modes (hmode, mode, hipartloxhi, 0);
          rtx signbitloxhi = const0_rtx;
          if (!uns)
            signbitloxhi = expand_shift (RSHIFT_EXPR, hmode,
-                                        gen_lowpart (hmode, loxhi),
+                                        convert_modes (hmode, mode,
+                                                       loxhi, 0),
                                         hprec - 1, NULL_RTX, 0);
 
          do_compare_rtx_and_jump (signbitloxhi, hipartloxhi, NE, true, hmode,
@@ -1731,7 +1732,8 @@ expand_mul_overflow (location_t loc, tre
          /* res = (loxhi << (bitsize / 2)) | (hmode) lo0xlo1;  */
          rtx loxhishifted = expand_shift (LSHIFT_EXPR, mode, loxhi, hprec,
                                           NULL_RTX, 1);
-         tem = convert_modes (mode, hmode, gen_lowpart (hmode, lo0xlo1), 1);
+         tem = convert_modes (mode, hmode,
+                              convert_modes (hmode, mode, lo0xlo1, 1), 1);
 
          tem = expand_simple_binop (mode, IOR, loxhishifted, tem, res,
                                     1, OPTAB_DIRECT);
2017-02-15  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2017-01-31  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/79267
        * value-prof.c (gimple_ic): Only drop lhs for noreturn calls
        if should_remove_lhs_p is true.

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

--- gcc/value-prof.c    (revision 245052)
+++ gcc/value-prof.c    (revision 245053)
@@ -1376,7 +1376,13 @@ gimple_ic (gcall *icall_stmt, struct cgr
   gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
   dflags = flags_from_decl_or_type (direct_call->decl);
   if ((dflags & ECF_NORETURN) != 0)
-    gimple_call_set_lhs (dcall_stmt, NULL_TREE);
+    {
+      tree lhs = gimple_call_lhs (dcall_stmt);
+      if (lhs
+          && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST
+          && !TREE_ADDRESSABLE (TREE_TYPE (lhs)))
+       gimple_call_set_lhs (dcall_stmt, NULL_TREE);
+    }
   gsi_insert_before (&gsi, dcall_stmt, GSI_SAME_STMT);
 
   /* Fix CFG. */
--- gcc/testsuite/g++.dg/opt/pr79267.C  (nonexistent)
+++ gcc/testsuite/g++.dg/opt/pr79267.C  (revision 245053)
@@ -0,0 +1,69 @@
+// PR tree-optimization/79267
+// { dg-do compile }
+// { dg-options "-O3" }
+
+struct A { A (int); };
+struct B
+{
+  virtual void av () = 0;
+  void aw ();
+  void h () { av (); aw (); }
+};
+template <class T> struct G : B
+{
+  T ba;
+  G (int, T) : ba (0) {}
+  void av () { ba (0); }
+};
+struct I
+{
+  B *bc;
+  template <class j, class T> I (j, T) try { G<T> (0, 0); } catch (...) {}
+  ~I () { bc->h (); }
+};
+template <class M> struct C { typedef M *i; };
+template <class M> struct J
+{
+  J ();
+  template <class O, class T> J (O, T p2) : be (0, p2) {}
+  typename C<M>::i operator-> ();
+  I be;
+};
+struct H : A { H () : A (0) {} };
+struct D { J<int> d; void q (); };
+template <typename = int> class bs;
+int z;
+
+void
+foo (int p1, int *, int)
+{
+  if (p1 == 0)
+    throw H ();
+}
+
+D bar ();
+template <typename T> struct L
+{
+  struct K { K (int); void operator() (int *) { bar ().q (); } };
+  static J<T> bp () { bq (0); }
+  template <typename br> static void bq (br) { J<T> (0, K (0)); }
+};
+struct F
+{
+  virtual J<int> x (int) { foo (0, 0, 0); J<bs<> > (L<bs<> >::bp ()); }
+};
+
+void
+baz ()
+{
+  if (z)
+    {
+      J<F> d, e;
+      d->x (0);
+      e->x (0);
+    }
+  J<F> v, i, j;
+  v->x (0);
+  i->x (0);
+  j->x (0);
+}
2017-02-15  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2017-02-02  Jakub Jelinek  <ja...@redhat.com>

        PR target/79197
        * config/rs6000/rs6000.md (*fixuns_trunc<mode>di2_fctiduz): Rename to 
...
        (fixuns_trunc<mode>di2): ... this, remove previous expander.  Put all
        conditions on a single line.

        * gcc.target/powerpc/pr79197.c: New test.
        * gcc.c-torture/compile/pr79197.c: New test.

--- gcc/config/rs6000/rs6000.md (revision 245119)
+++ gcc/config/rs6000/rs6000.md (revision 245120)
@@ -5429,17 +5429,10 @@ (define_insn_and_split "fixuns_trunc<mod
   [(set_attr "length" "12")
    (set_attr "type" "fp")])
 
-(define_expand "fixuns_trunc<mode>di2"
-  [(set (match_operand:DI 0 "register_operand" "")
-       (unsigned_fix:DI (match_operand:SFDF 1 "register_operand" "")))]
-  "TARGET_HARD_FLOAT && (TARGET_FCTIDUZ || VECTOR_UNIT_VSX_P (<MODE>mode))"
-  "")
-
-(define_insn "*fixuns_trunc<mode>di2_fctiduz"
+(define_insn "fixuns_trunc<mode>di2"
   [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
        (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS
-    && TARGET_FCTIDUZ"
+  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ"
   "@
    fctiduz %0,%1
    xscvdpuxds %x0,%x1"
--- gcc/testsuite/gcc.target/powerpc/pr79197.c  (nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr79197.c  (revision 245120)
@@ -0,0 +1,11 @@
+/* PR target/79197 */
+/* { dg-do compile } */
+/* { dg-options "-O0 -mno-popcntd" } */
+
+unsigned a;
+
+void
+foo (void)
+{
+  a = *(double *) (__UINTPTR_TYPE__) 0x400000;
+}
--- gcc/testsuite/gcc.c-torture/compile/pr79197.c       (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr79197.c       (revision 245120)
@@ -0,0 +1,10 @@
+/* PR target/79197 */
+
+unsigned long b;
+
+unsigned long
+foo (float *a, float *x)
+{
+  __builtin_memcpy (a, x, sizeof (float));
+  return *a;
+}
2017-02-15  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2017-02-04  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/79338
        * tree-parloops.c (gather_scalar_reductions): Don't call
        vect_analyze_loop_form for loop->inner before destroying loop's
        loop_vinfo.

--- gcc/tree-parloops.c (revision 245182)
+++ gcc/tree-parloops.c (revision 245183)
@@ -2513,8 +2513,8 @@ gather_scalar_reductions (loop_p loop, r
 {
   gphi_iterator gsi;
   loop_vec_info simple_loop_info;
-  loop_vec_info simple_inner_loop_info = NULL;
-  bool allow_double_reduc = true;
+  auto_vec<gphi *, 4> double_reduc_phis;
+  auto_vec<gimple *, 4> double_reduc_stmts;
 
   if (!stmt_vec_info_vec.exists ())
     init_stmt_vec_info_vec ();
@@ -2544,43 +2544,55 @@ gather_scalar_reductions (loop_p loop, r
 
       if (double_reduc)
        {
-         if (!allow_double_reduc
-             || loop->inner->inner != NULL)
+         if (loop->inner->inner != NULL)
            continue;
 
-         if (!simple_inner_loop_info)
-           {
-             simple_inner_loop_info = vect_analyze_loop_form (loop->inner);
-             if (!simple_inner_loop_info)
-               {
-                 allow_double_reduc = false;
-                 continue;
-               }
-           }
-
-         use_operand_p use_p;
-         gimple *inner_stmt;
-         bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
-         gcc_assert (single_use_p);
-         if (gimple_code (inner_stmt) != GIMPLE_PHI)
-           continue;
-         gphi *inner_phi = as_a <gphi *> (inner_stmt);
-         if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
-                        &iv, true))
-           continue;
-
-         gimple *inner_reduc_stmt
-           = vect_force_simple_reduction (simple_inner_loop_info, inner_phi,
-                                          true, &double_reduc, true);
-         gcc_assert (!double_reduc);
-         if (inner_reduc_stmt == NULL)
-           continue;
+         double_reduc_phis.safe_push (phi);
+         double_reduc_stmts.safe_push (reduc_stmt);
+         continue;
        }
 
       build_new_reduction (reduction_list, reduc_stmt, phi);
     }
   destroy_loop_vec_info (simple_loop_info, true);
-  destroy_loop_vec_info (simple_inner_loop_info, true);
+
+  if (!double_reduc_phis.is_empty ())
+    {
+      simple_loop_info = vect_analyze_loop_form (loop->inner);
+      if (simple_loop_info)
+       {
+         gphi *phi;
+         unsigned int i;
+
+         FOR_EACH_VEC_ELT (double_reduc_phis, i, phi)
+           {
+             affine_iv iv;
+             tree res = PHI_RESULT (phi);
+             bool double_reduc;
+
+             use_operand_p use_p;
+             gimple *inner_stmt;
+             bool single_use_p = single_imm_use (res, &use_p, &inner_stmt);
+             gcc_assert (single_use_p);
+             if (gimple_code (inner_stmt) != GIMPLE_PHI)
+               continue;
+             gphi *inner_phi = as_a <gphi *> (inner_stmt);
+             if (simple_iv (loop->inner, loop->inner, PHI_RESULT (inner_phi),
+                            &iv, true))
+               continue;
+
+             gimple *inner_reduc_stmt
+               = vect_force_simple_reduction (simple_loop_info, inner_phi,
+                                              true, &double_reduc, true);
+             gcc_assert (!double_reduc);
+             if (inner_reduc_stmt == NULL)
+               continue;
+
+             build_new_reduction (reduction_list, double_reduc_stmts[i], phi);
+           }
+         destroy_loop_vec_info (simple_loop_info, true);
+       }
+    }
 
  gather_done:
   /* Release the claim on gimple_uid.  */
2017-02-15  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2017-02-06  Jakub Jelinek  <ja...@redhat.com>

        PR c++/79377
        * tree.c (build_min_non_dep_op_overload): For POST{INC,DEC}REMENT_EXPR
        allow one fewer than expected arguments if flag_permissive.

        * g++.dg/lookup/pr79377.C: New test.

--- gcc/cp/tree.c       (revision 245218)
+++ gcc/cp/tree.c       (revision 245219)
@@ -2938,8 +2938,10 @@ build_min_non_dep_op_overload (enum tree
   nargs = call_expr_nargs (non_dep);
 
   expected_nargs = cp_tree_code_length (op);
-  if (op == POSTINCREMENT_EXPR
-      || op == POSTDECREMENT_EXPR)
+  if ((op == POSTINCREMENT_EXPR
+       || op == POSTDECREMENT_EXPR)
+      /* With -fpermissive non_dep could be operator++().  */
+      && (!flag_permissive || nargs != expected_nargs))
     expected_nargs += 1;
   gcc_assert (nargs == expected_nargs);
 
--- gcc/testsuite/g++.dg/lookup/pr79377.C       (nonexistent)
+++ gcc/testsuite/g++.dg/lookup/pr79377.C       (revision 245219)
@@ -0,0 +1,36 @@
+// PR c++/79377
+// { dg-do run }
+// { dg-options "-fpermissive" }
+
+struct A
+{
+  A () : a (0) {}
+  A& operator++ () { ++a; ++c; return *this; }
+  int a;
+  static int c;
+};
+
+int A::c = 0;
+
+template <typename>
+void
+foo (A& a)
+{
+  a++;         // { dg-warning "trying prefix operator instead" }
+  if (A::c != 3 || a.a != 3) __builtin_abort ();
+  ++a;
+  if (A::c != 4 || a.a != 4) __builtin_abort ();
+}
+
+int
+main ()
+{
+  A a;
+  if (A::c != 0 || a.a != 0) __builtin_abort ();
+  ++a;
+  if (A::c != 1 || a.a != 1) __builtin_abort ();
+  a++;         // { dg-warning "trying prefix operator instead" }
+  if (A::c != 2 || a.a != 2) __builtin_abort ();
+  foo<int> (a);
+  if (A::c != 4 || a.a != 4) __builtin_abort ();
+}
2017-02-15  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2017-02-07  Jakub Jelinek  <ja...@redhat.com>
                    Richard Biener  <rguent...@suse.de>

        PR middle-end/79399
        * ira-int.h (struct target_ira_int): Change x_max_struct_costs_size
        type from int to size_t.
        * ira-costs.c (struct_costs_size): Change type from int to size_t.

--- gcc/ira-int.h       (revision 245255)
+++ gcc/ira-int.h       (revision 245256)
@@ -782,7 +782,7 @@ struct target_ira_int {
 
   /* Initialized once.  It is a maximal possible size of the allocated
      struct costs.  */
-  int x_max_struct_costs_size;
+  size_t x_max_struct_costs_size;
 
   /* Allocated and initialized once, and used to initialize cost values
      for each insn.  */
--- gcc/ira-costs.c     (revision 245255)
+++ gcc/ira-costs.c     (revision 245256)
@@ -74,7 +74,7 @@ static struct costs *costs;
 static struct costs *total_allocno_costs;
 
 /* It is the current size of struct costs.  */
-static int struct_costs_size;
+static size_t struct_costs_size;
 
 /* Return pointer to structure containing costs of allocno or pseudo
    with given NUM in array ARR.  */
2017-02-15  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2017-02-09  Jakub Jelinek  <ja...@redhat.com>

        PR c/79431
        * gimplify.c (gimplify_adjust_omp_clauses): Ignore
        "omp declare target link" attribute unless is_global_var.
        * omp-low.c (find_link_var_op): Likewise.

        * c-parser.c (c_parser_omp_declare_target): Don't invoke
        symtab_node::get on automatic variables.

        * parser.c (cp_parser_oacc_declare): Formatting fix.
        (cp_parser_omp_declare_target): Don't invoke symtab_node::get on
        automatic variables.

        * c-c++-common/gomp/pr79431.c: New test.

--- gcc/gimplify.c      (revision 245301)
+++ gcc/gimplify.c      (revision 245302)
@@ -8938,8 +8938,9 @@ gimplify_adjust_omp_clauses (gimple_seq
          if ((ctx->region_type & ORT_TARGET) != 0
              && !(n->value & GOVD_SEEN)
              && GOMP_MAP_ALWAYS_P (OMP_CLAUSE_MAP_KIND (c)) == 0
-             && !lookup_attribute ("omp declare target link",
-                                   DECL_ATTRIBUTES (decl)))
+             && (!is_global_var (decl)
+                 || !lookup_attribute ("omp declare target link",
+                                       DECL_ATTRIBUTES (decl))))
            {
              remove = true;
              /* For struct element mapping, if struct is never referenced
--- gcc/omp-low.c       (revision 245301)
+++ gcc/omp-low.c       (revision 245302)
@@ -19890,7 +19890,9 @@ find_link_var_op (tree *tp, int *walk_su
 {
   tree t = *tp;
 
-  if (TREE_CODE (t) == VAR_DECL && DECL_HAS_VALUE_EXPR_P (t)
+  if (TREE_CODE (t) == VAR_DECL
+      && DECL_HAS_VALUE_EXPR_P (t)
+      && is_global_var (t)
       && lookup_attribute ("omp declare target link", DECL_ATTRIBUTES (t)))
     {
       *walk_subtrees = 0;
--- gcc/c/c-parser.c    (revision 245301)
+++ gcc/c/c-parser.c    (revision 245302)
@@ -16849,8 +16849,11 @@ c_parser_omp_declare_target (c_parser *p
        }
       if (!at1)
        {
-         symtab_node *node = symtab_node::get (t);
          DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+         if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
+           continue;
+
+         symtab_node *node = symtab_node::get (t);
          if (node != NULL)
            {
              node->offloadable = 1;
--- gcc/cp/parser.c     (revision 245301)
+++ gcc/cp/parser.c     (revision 245302)
@@ -36230,7 +36230,7 @@ cp_parser_oacc_declare (cp_parser *parse
            id = get_identifier ("omp declare target");
 
          DECL_ATTRIBUTES (decl)
-                          = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
+           = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (decl));
          if (global_bindings_p ())
            {
              symtab_node *node = symtab_node::get (decl);
@@ -36770,8 +36770,11 @@ cp_parser_omp_declare_target (cp_parser
        }
       if (!at1)
        {
-         symtab_node *node = symtab_node::get (t);
          DECL_ATTRIBUTES (t) = tree_cons (id, NULL_TREE, DECL_ATTRIBUTES (t));
+         if (TREE_CODE (t) != FUNCTION_DECL && !is_global_var (t))
+           continue;
+
+         symtab_node *node = symtab_node::get (t);
          if (node != NULL)
            {
              node->offloadable = 1;
--- gcc/testsuite/c-c++-common/gomp/pr79431.c   (nonexistent)
+++ gcc/testsuite/c-c++-common/gomp/pr79431.c   (revision 245302)
@@ -0,0 +1,8 @@
+/* PR c/79431 */
+
+void
+foo (void)
+{
+  int a;
+  #pragma omp declare target (a)
+}
2017-02-15  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2017-02-09  Jakub Jelinek  <ja...@redhat.com>

        PR c++/79429
        * parser.c (cp_parser_omp_ordered): Don't check for non-pragma_stmt
        non-pragma_compound context here.
        (cp_parser_omp_target): Likewise.
        (cp_parser_pragma): Don't call push_omp_privatization_clauses and
        parsing for ordered and target omp pragmas in non-pragma_stmt
        non-pragma_compound contexts.

        * c-c++-common/gomp/pr79429.c: New test.
        * g++.dg/gomp/pr79429.C: New test.

--- gcc/cp/parser.c     (revision 245302)
+++ gcc/cp/parser.c     (revision 245303)
@@ -34934,13 +34934,6 @@ cp_parser_omp_ordered (cp_parser *parser
 {
   location_t loc = pragma_tok->location;
 
-  if (context != pragma_stmt && context != pragma_compound)
-    {
-      cp_parser_error (parser, "expected declaration specifiers");
-      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
-      return false;
-    }
-
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     {
       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -35846,13 +35839,6 @@ cp_parser_omp_target (cp_parser *parser,
 {
   tree *pc = NULL, stmt;
 
-  if (context != pragma_stmt && context != pragma_compound)
-    {
-      cp_parser_error (parser, "expected declaration specifiers");
-      cp_parser_skip_to_pragma_eol (parser, pragma_tok);
-      return false;
-    }
-
   if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
     {
       tree id = cp_lexer_peek_token (parser->lexer)->u.value;
@@ -38283,12 +38269,16 @@ cp_parser_pragma (cp_parser *parser, enu
       return true;
 
     case PRAGMA_OMP_ORDERED:
+      if (context != pragma_stmt && context != pragma_compound)
+       goto bad_stmt;
       stmt = push_omp_privatization_clauses (false);
       ret = cp_parser_omp_ordered (parser, pragma_tok, context, if_p);
       pop_omp_privatization_clauses (stmt);
       return ret;
 
     case PRAGMA_OMP_TARGET:
+      if (context != pragma_stmt && context != pragma_compound)
+       goto bad_stmt;
       stmt = push_omp_privatization_clauses (false);
       ret = cp_parser_omp_target (parser, pragma_tok, context, if_p);
       pop_omp_privatization_clauses (stmt);
--- gcc/testsuite/g++.dg/gomp/pr79429.C (nonexistent)
+++ gcc/testsuite/g++.dg/gomp/pr79429.C (revision 245303)
@@ -0,0 +1,3 @@
+// PR c++/79429
+
+#pragma omp ordered // { dg-error "expected declaration specifiers" }
--- gcc/testsuite/c-c++-common/gomp/pr79429.c   (nonexistent)
+++ gcc/testsuite/c-c++-common/gomp/pr79429.c   (revision 245303)
@@ -0,0 +1,3 @@
+/* PR c++/79429 */
+
+#pragma omp target /* { dg-error "expected declaration specifiers" } */
2017-02-15  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2017-02-10  Jakub Jelinek  <ja...@redhat.com>

        PR tree-optimization/79411
        * tree-ssa-reassoc.c (is_reassociable_op): Return false if
        stmt operands are SSA_NAMEs used in abnormal phis.
        (can_reassociate_p): Return false if op is SSA_NAME used in abnormal
        phis.

        * gcc.c-torture/compile/pr79411.c: New test.

--- gcc/tree-ssa-reassoc.c      (revision 245323)
+++ gcc/tree-ssa-reassoc.c      (revision 245324)
@@ -605,7 +605,18 @@ is_reassociable_op (gimple *stmt, enum t
   if (is_gimple_assign (stmt)
       && gimple_assign_rhs_code (stmt) == code
       && has_single_use (gimple_assign_lhs (stmt)))
-    return true;
+    {
+      tree rhs1 = gimple_assign_rhs1 (stmt);
+      tree rhs2 = gimple_assign_rhs1 (stmt);
+      if (TREE_CODE (rhs1) == SSA_NAME
+         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs1))
+       return false;
+      if (rhs2
+         && TREE_CODE (rhs2) == SSA_NAME
+         && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (rhs2))
+       return false;
+      return true;
+    }
 
   return false;
 }
@@ -4989,6 +5000,8 @@ static bool
 can_reassociate_p (tree op)
 {
   tree type = TREE_TYPE (op);
+  if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
+    return false;
   if ((ANY_INTEGRAL_TYPE_P (type) && TYPE_OVERFLOW_WRAPS (type))
       || NON_SAT_FIXED_POINT_TYPE_P (type)
       || (flag_associative_math && FLOAT_TYPE_P (type)))
--- gcc/testsuite/gcc.c-torture/compile/pr79411.c       (nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr79411.c       (revision 245324)
@@ -0,0 +1,22 @@
+/* PR tree-optimization/79411 */
+
+typedef struct __jmp_buf_tag { char buf[1024]; } jmp_buf[1];
+extern int setjmp (jmp_buf);
+extern int bar (unsigned int *);
+extern jmp_buf *baz (void);
+struct C { int c1; unsigned int c2, c3, c4; };
+
+void
+foo (struct C *x, const int *y, unsigned int *z, unsigned int e, unsigned int 
g)
+{
+  unsigned int d = 0;
+  unsigned long f;
+  setjmp (*baz ());
+  f = 1 + d;
+  if ((x->c1 || x->c2) && g && (!e || d >= 8))
+    d = 16;
+  else
+    d = 8;
+  if ((!x->c3 && !x->c4 || *y == 0) && !e && bar (z))
+    *z = 1 + f;
+}

Reply via email to