Hi!

I've backported 13 commits of mine and one from Richard.
Bootstrapped/regtested on x86_64-linux and i686-linux, committed
to gcc-6-branch.

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

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

        PR target/81225
        * config/i386/sse.md (vec_extract_lo_<mode><mask_name>): For
        V8FI, V16FI and VI8F_256 iterators, use <store_mask_predicate> instead
        of nonimmediate_operand and <store_mask_constraint> instead of m for
        the input operand.  For V8FI iterator, always split if input is a MEM.
        For V16FI and V8SF_256 iterators, don't test if both operands are MEM
        if <mask_applied>.  For VI4F_256 iterator, use <store_mask_predicate>
        instead of register_operand and <store_mask_constraint> instead of v for
        the input operand.  Make sure both operands aren't MEMs for if not
        <mask_applied>.

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

--- gcc/config/i386/sse.md      (revision 250284)
+++ gcc/config/i386/sse.md      (revision 250285)
@@ -7230,12 +7230,13 @@ (define_insn "vec_extract_lo_<mode>_mask
 (define_insn "vec_extract_lo_<mode><mask_name>"
   [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" 
"=<store_mask_constraint>,v")
        (vec_select:<ssehalfvecmode>
-         (match_operand:V8FI 1 "nonimmediate_operand" "v,m")
+         (match_operand:V8FI 1 "<store_mask_predicate>" 
"v,<store_mask_constraint>")
          (parallel [(const_int 0) (const_int 1)
             (const_int 2) (const_int 3)])))]
-  "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+  "TARGET_AVX512F
+   && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))"
 {
-  if (<mask_applied> || !TARGET_AVX512VL)
+  if (<mask_applied> || (!TARGET_AVX512VL && !MEM_P (operands[1])))
     return "vextract<shuffletype>64x4\t{$0x0, %1, 
%0<mask_operand2>|%0<mask_operand2>, %1, 0x0}";
   else
     return "#";
@@ -7374,14 +7375,15 @@ (define_expand "avx_vextractf128<mode>"
 (define_insn "vec_extract_lo_<mode><mask_name>"
   [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=v,m")
        (vec_select:<ssehalfvecmode>
-         (match_operand:V16FI 1 "nonimmediate_operand" "vm,v")
+         (match_operand:V16FI 1 "<store_mask_predicate>"
+                                "<store_mask_constraint>,v")
          (parallel [(const_int 0) (const_int 1)
                      (const_int 2) (const_int 3)
                      (const_int 4) (const_int 5)
                      (const_int 6) (const_int 7)])))]
   "TARGET_AVX512F
    && <mask_mode512bit_condition>
-   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+   && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))"
 {
   if (<mask_applied>)
     return "vextract<shuffletype>32x8\t{$0x0, %1, 
%0<mask_operand2>|%0<mask_operand2>, %1, 0x0}";
@@ -7413,11 +7415,12 @@ (define_split
 (define_insn "vec_extract_lo_<mode><mask_name>"
   [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=v,m")
        (vec_select:<ssehalfvecmode>
-         (match_operand:VI8F_256 1 "nonimmediate_operand" "vm,v")
+         (match_operand:VI8F_256 1 "<store_mask_predicate>"
+                                   "<store_mask_constraint>,v")
          (parallel [(const_int 0) (const_int 1)])))]
   "TARGET_AVX
    && <mask_avx512vl_condition> && <mask_avx512dq_condition>
-   && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+   && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))"
 {
   if (<mask_applied>)
     return "vextract<shuffletype>64x2\t{$0x0, %1, %0%{%3%}|%0%{%3%}, %1, 0x0}";
@@ -7493,12 +7496,16 @@ (define_split
 
 
 (define_insn "vec_extract_lo_<mode><mask_name>"
-  [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" 
"=<store_mask_constraint>")
+  [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>"
+                                         "=<store_mask_constraint>,v")
        (vec_select:<ssehalfvecmode>
-         (match_operand:VI4F_256 1 "register_operand" "v")
+         (match_operand:VI4F_256 1 "<store_mask_predicate>"
+                                   "v,<store_mask_constraint>")
          (parallel [(const_int 0) (const_int 1)
                     (const_int 2) (const_int 3)])))]
-  "TARGET_AVX && <mask_avx512vl_condition> && <mask_avx512dq_condition>"
+  "TARGET_AVX
+   && <mask_avx512vl_condition> && <mask_avx512dq_condition>
+   && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))"
 {
   if (<mask_applied>)
     return "vextract<shuffletype>32x4\t{$0x0, %1, 
%0<mask_operand2>|%0<mask_operand2>, %1, 0x0}";
--- gcc/testsuite/gcc.target/i386/pr81225.c     (nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr81225.c     (revision 250285)
@@ -0,0 +1,14 @@
+/* PR target/81225 */
+/* { dg-do compile } */
+/* { dg-options "-mavx512ifma -O3 -ffloat-store" } */
+
+long a[24];
+float b[4], c[24];
+int d;
+
+void
+foo ()
+{
+  for (d = 0; d < 24; d++)
+    c[d] = (float) d ? : b[a[d]];
+}
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

        PR libquadmath/65757
        * math/roundq.c: Cherry-pick upstream glibc 2015-04-28 change.

--- libquadmath/math/roundq.c   (revision 250378)
+++ libquadmath/math/roundq.c   (revision 250379)
@@ -1,5 +1,5 @@
 /* Round __float128 to integer away from zero.
-   Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drep...@cygnus.com>, 1997 and
                  Jakub Jelinek <j...@ultra.linux.cz>, 1999.
@@ -32,7 +32,7 @@ roundq (__float128 x)
 
   GET_FLT128_WORDS64 (i0, i1, x);
   j0 = ((i0 >> 48) & 0x7fff) - 0x3fff;
-  if (j0 < 31)
+  if (j0 < 48)
     {
       if (j0 < 0)
        {
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2017-08-08  Richard Biener  <rguent...@suse.de>

        PR middle-end/81766
        * function.c (thread_prologue_and_epilogue_insns): Restore
        behavior of always calling find_many_sub_basic_blocks on
        the inserted prologue.

        * gcc.target/i386/pr81766.c: New testcase.

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

        PR middle-end/79499
        * function.c (thread_prologue_and_epilogue_insns): Determine blocks
        for find_many_sub_basic_blocks bitmap by looking up BLOCK_FOR_INSN
        of first NONDEBUG_INSN_P in each of the split_prologue_seq and
        prologue_seq sequences - if any.

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

--- gcc/function.c      (revision 250814)
+++ gcc/function.c      (revision 250958)
@@ -6068,13 +6068,19 @@ thread_prologue_and_epilogue_insns (void
 
   try_shrink_wrapping (&entry_edge, &bb_flags, prologue_seq);
 
+  rtx_insn *split_prologue_insn = split_prologue_seq;
   if (split_prologue_seq != NULL_RTX)
     {
+      while (split_prologue_insn && !NONDEBUG_INSN_P (split_prologue_insn))
+       split_prologue_insn = NEXT_INSN (split_prologue_insn);
       insert_insn_on_edge (split_prologue_seq, orig_entry_edge);
       inserted = true;
     }
+  rtx_insn *prologue_insn = prologue_seq;
   if (prologue_seq != NULL_RTX)
     {
+      while (prologue_insn && !NONDEBUG_INSN_P (prologue_insn))
+       prologue_insn = NEXT_INSN (prologue_insn);
       insert_insn_on_edge (prologue_seq, entry_edge);
       inserted = true;
     }
@@ -6215,8 +6221,19 @@ epilogue_done:
       commit_edge_insertions ();
 
       /* Look for basic blocks within the prologue insns.  */
+      if (split_prologue_insn
+         && BLOCK_FOR_INSN (split_prologue_insn) == NULL)
+       split_prologue_insn = NULL;
+      if (prologue_insn
+         && BLOCK_FOR_INSN (prologue_insn) == NULL)
+       prologue_insn = NULL;
       blocks = sbitmap_alloc (last_basic_block_for_fn (cfun));
       bitmap_clear (blocks);
+      if (split_prologue_insn)
+       bitmap_set_bit (blocks,
+                       BLOCK_FOR_INSN (split_prologue_insn)->index);
+      if (prologue_insn)
+       bitmap_set_bit (blocks, BLOCK_FOR_INSN (prologue_insn)->index);
       bitmap_set_bit (blocks, entry_edge->dest->index);
       bitmap_set_bit (blocks, orig_entry_edge->dest->index);
       find_many_sub_basic_blocks (blocks);
--- gcc/testsuite/gcc.dg/pr79499.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr79499.c      (revision 250815)
@@ -0,0 +1,13 @@
+/* PR middle-end/79499 */
+/* { dg-do compile { target split_stack } } */
+/* { dg-options "-O2 -fsplit-stack -fno-omit-frame-pointer" } */
+
+struct S { struct S *a, *b; };
+
+void
+foo (struct S *x)
+{
+  do
+    x->b = x->a;
+  while (x = x->a);
+}
--- gcc/testsuite/gcc.target/i386/pr81766.c     (nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr81766.c     (revision 250958)
@@ -0,0 +1,5 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -fPIE -mcmodel=large" } */
+
+int main() { return 0; }
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

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

        PR c/45784
        * c-omp.c (c_finish_omp_for): If the condition is wrapped in
        rhs of COMPOUND_EXPR(s), skip them and readd their lhs into
        new COMPOUND_EXPRs around the rhs of the comparison.

        * testsuite/libgomp.c/pr45784.c: New test.
        * testsuite/libgomp.c++/pr45784.C: New test.

--- gcc/c-family/c-omp.c        (revision 251847)
+++ gcc/c-family/c-omp.c        (revision 251848)
@@ -531,6 +531,12 @@ c_finish_omp_for (location_t locus, enum
        {
          bool cond_ok = false;
 
+         /* E.g. C sizeof (vla) could add COMPOUND_EXPRs with
+            evaluation of the vla VAR_DECL.  We need to readd
+            them to the non-decl operand.  See PR45784.  */
+         while (TREE_CODE (cond) == COMPOUND_EXPR)
+           cond = TREE_OPERAND (cond, 1);
+
          if (EXPR_HAS_LOCATION (cond))
            elocus = EXPR_LOCATION (cond);
 
@@ -605,6 +611,21 @@ c_finish_omp_for (location_t locus, enum
                  else if (code != CILK_SIMD && code != CILK_FOR)
                    cond_ok = false;
                }
+
+             if (cond_ok && TREE_VEC_ELT (condv, i) != cond)
+               {
+                 tree ce = NULL_TREE, *pce = &ce;
+                 tree type = TREE_TYPE (TREE_OPERAND (cond, 1));
+                 for (tree c = TREE_VEC_ELT (condv, i); c != cond;
+                      c = TREE_OPERAND (c, 1))
+                   {
+                     *pce = build2 (COMPOUND_EXPR, type, TREE_OPERAND (c, 0),
+                                    TREE_OPERAND (cond, 1));
+                     pce = &TREE_OPERAND (*pce, 1);
+                   }
+                 TREE_OPERAND (cond, 1) = ce;
+                 TREE_VEC_ELT (condv, i) = cond;
+               }
            }
 
          if (!cond_ok)
--- libgomp/testsuite/libgomp.c/pr45784.c       (nonexistent)
+++ libgomp/testsuite/libgomp.c/pr45784.c       (revision 251848)
@@ -0,0 +1,41 @@
+/* PR c/45784 */
+/* { dg-do run } */
+
+void
+foo (int n)
+{
+  char *p, vla[2 * n];
+  int i;
+  #pragma omp parallel for
+  for (p = vla; p < vla + (sizeof (vla) / sizeof (vla[0])); p++)
+    *p = ' ';
+  #pragma omp parallel for
+  for (i = 0; i < 2 * n; i++)
+    if (vla[i] != ' ')
+      __builtin_abort ();
+}
+
+void
+bar (int n)
+{
+  char *p, vla1[n], vla2[n * 2], vla3[n * 3], vla4[n * 4];
+  int i;
+  __builtin_memset (vla4, ' ', n * 4);
+  #pragma omp parallel for
+  for (p = vla4 + sizeof (vla1); p < vla4 + sizeof (vla3) - sizeof (vla2) + 
sizeof (vla1); p += sizeof (vla4) / sizeof (vla4))
+    p[0] = '!';
+  #pragma omp parallel for
+  for (i = 0; i < n * 4; i++)
+    if (vla4[i] != ((i >= n && i < 2 * n) ? '!' : ' '))
+      __builtin_abort ();
+}
+
+int
+main ()
+{
+  volatile int n;
+  n = 128;
+  foo (n);
+  bar (n);
+  return 0;
+}
--- libgomp/testsuite/libgomp.c++/pr45784.C     (nonexistent)
+++ libgomp/testsuite/libgomp.c++/pr45784.C     (revision 251848)
@@ -0,0 +1,5 @@
+// PR c/45784
+// { dg-do run }
+
+#include "../libgomp.c/pr45784.c"
+
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

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

        PR middle-end/81052
        * omp-low.c (diagnose_sb_0): Handle flag_openmp_simd like flag_openmp.
        (pass_diagnose_omp_blocks::gate): Enable also for flag_openmp_simd.

        * c-c++-common/pr81052.c: New test.

--- gcc/omp-low.c       (revision 251848)
+++ gcc/omp-low.c       (revision 251849)
@@ -9089,7 +9089,7 @@ diagnose_sb_0 (gimple_stmt_iterator *gsi
     }
   if (kind == NULL)
     {
-      gcc_checking_assert (flag_openmp);
+      gcc_checking_assert (flag_openmp || flag_openmp_simd);
       kind = "OpenMP";
     }
 
@@ -9349,7 +9349,7 @@ public:
   /* opt_pass methods: */
   virtual bool gate (function *)
   {
-    return flag_cilkplus || flag_openacc || flag_openmp;
+    return flag_cilkplus || flag_openacc || flag_openmp || flag_openmp_simd;
   }
   virtual unsigned int execute (function *)
     {
--- gcc/testsuite/c-c++-common/pr81052.c        (nonexistent)
+++ gcc/testsuite/c-c++-common/pr81052.c        (revision 251849)
@@ -0,0 +1,28 @@
+/* PR middle-end/81052 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp-simd -O2" } */
+
+int
+foo (int x, int y)
+{
+  int i;
+#pragma omp simd
+  for (i = x; i < y; ++i)
+    return 0;                  /* { dg-error "invalid branch to/from OpenMP 
structured block" } */
+  return 1;
+}
+
+#ifdef __cplusplus
+template <typename T>
+T
+bar (T x, T y)
+{
+  T i;
+#pragma omp simd
+  for (i = x; i < y; ++i)
+    return 0;                  /* { dg-error "invalid branch to/from OpenMP 
structured block" "" { target c++ } } */
+  return 1;
+}
+
+int x = bar (1, 7);
+#endif
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

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

        PR target/81621
        * bb-reorder.c (pass_partition_blocks::execute): Return TODO_df_finish
        after setting changeable df flags.

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

--- gcc/bb-reorder.c    (revision 251850)
+++ gcc/bb-reorder.c    (revision 251851)
@@ -2881,7 +2881,8 @@ pass_partition_blocks::execute (function
 
   crossing_edges = find_rarely_executed_basic_blocks_and_crossing_edges ();
   if (!crossing_edges.exists ())
-    return 0;
+    /* Make sure to process deferred rescans and clear changeable df flags.  */
+    return TODO_df_finish;
 
   crtl->has_bb_partition = true;
 
@@ -2947,7 +2948,8 @@ pass_partition_blocks::execute (function
       df_analyze ();
     }
 
-  return 0;
+  /* Make sure to process deferred rescans and clear changeable df flags.  */
+  return TODO_df_finish;
 }
 
 } // anon namespace
--- gcc/testsuite/gcc.dg/pr81621.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr81621.c      (revision 251851)
@@ -0,0 +1,5 @@
+/* PR target/81621 */
+/* { dg-do compile { target freorder } } */
+/* { dg-options "-Og -fno-split-wide-types -freorder-blocks-and-partition" } */
+
+#include "graphite/scop-10.c"
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

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

        PR c/81687
        * omp-low.c (omp_copy_decl): Don't remap FORCED_LABEL or DECL_NONLOCAL
        LABEL_DECLs.
        * tree-cfg.c (move_stmt_op): Don't adjust DECL_CONTEXT of FORCED_LABEL
        or DECL_NONLOCAL labels.
        (move_stmt_r) <case GIMPLE_LABEL>: Adjust DECL_CONTEXT of FORCED_LABEL
        or DECL_NONLOCAL labels here.

        * testsuite/libgomp.c/pr81687-1.c: New test.
        * testsuite/libgomp.c/pr81687-2.c: New test.

--- gcc/omp-low.c       (revision 251852)
+++ gcc/omp-low.c       (revision 251853)
@@ -800,6 +800,8 @@ omp_copy_decl (tree var, copy_body_data
 
   if (TREE_CODE (var) == LABEL_DECL)
     {
+      if (FORCED_LABEL (var) || DECL_NONLOCAL (var))
+       return var;
       new_var = create_artificial_label (DECL_SOURCE_LOCATION (var));
       DECL_CONTEXT (new_var) = current_function_decl;
       insert_decl_map (&ctx->cb, var, new_var);
--- gcc/tree-cfg.c      (revision 251852)
+++ gcc/tree-cfg.c      (revision 251853)
@@ -6667,7 +6667,15 @@ move_stmt_op (tree *tp, int *walk_subtre
                *tp = t = out->to;
            }
 
-         DECL_CONTEXT (t) = p->to_context;
+         /* For FORCED_LABELs we can end up with references from other
+            functions if some SESE regions are outlined.  It is UB to
+            jump in between them, but they could be used just for printing
+            addresses etc.  In that case, DECL_CONTEXT on the label should
+            be the function containing the glabel stmt with that LABEL_DECL,
+            rather than whatever function a reference to the label was seen
+            last time.  */
+         if (!FORCED_LABEL (t) && !DECL_NONLOCAL (t))
+           DECL_CONTEXT (t) = p->to_context;
        }
       else if (p->remap_decls_p)
        {
@@ -6785,6 +6793,21 @@ move_stmt_r (gimple_stmt_iterator *gsi_p
     case GIMPLE_OMP_RETURN:
     case GIMPLE_OMP_CONTINUE:
       break;
+
+    case GIMPLE_LABEL:
+      {
+       /* For FORCED_LABEL, move_stmt_op doesn't adjust DECL_CONTEXT,
+          so that such labels can be referenced from other regions.
+          Make sure to update it when seeing a GIMPLE_LABEL though,
+          that is the owner of the label.  */
+       walk_gimple_op (stmt, move_stmt_op, wi);
+       *handled_ops_p = true;
+       tree label = gimple_label_label (as_a <glabel *> (stmt));
+       if (FORCED_LABEL (label) || DECL_NONLOCAL (label))
+         DECL_CONTEXT (label) = p->to_context;
+      }
+      break;
+
     default:
       if (is_gimple_omp (stmt))
        {
--- libgomp/testsuite/libgomp.c/pr81687-1.c     (nonexistent)
+++ libgomp/testsuite/libgomp.c/pr81687-1.c     (revision 251853)
@@ -0,0 +1,23 @@
+/* PR c/81687 */
+/* { dg-do link } */
+/* { dg-additional-options "-O2" } */
+
+extern int printf (const char *, ...);
+
+int
+main ()
+{
+  #pragma omp parallel
+  {
+   lab1:
+    printf ("lab1=%p\n", (void *)(&&lab1));
+  }
+ lab2:
+  #pragma omp parallel
+  {
+   lab3:
+    printf ("lab2=%p\n", (void *)(&&lab2));
+  }
+  printf ("lab3=%p\n", (void *)(&&lab3));
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/pr81687-2.c     (nonexistent)
+++ libgomp/testsuite/libgomp.c/pr81687-2.c     (revision 251853)
@@ -0,0 +1,27 @@
+/* PR c/81687 */
+/* { dg-do link } */
+/* { dg-additional-options "-O2" } */
+
+int
+main ()
+{
+  __label__ lab4, lab5, lab6;
+  volatile int l = 0;
+  int m = l;
+  void foo (int x) { if (x == 1) goto lab4; }
+  void bar (int x) { if (x == 2) goto lab5; }
+  void baz (int x) { if (x == 3) goto lab6; }
+  #pragma omp parallel
+  {
+    foo (m + 1);
+   lab4:;
+  }
+  #pragma omp task
+  {
+    bar (m + 2);
+   lab5:;
+  }
+  baz (m + 3);
+ lab6:;
+  return 0;
+}
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

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

        * lra-remat.c (reg_overlap_for_remat_p): Fix a pasto.

--- gcc/lra-remat.c     (revision 251854)
+++ gcc/lra-remat.c     (revision 251855)
@@ -684,7 +684,7 @@ reg_overlap_for_remat_p (lra_insn_reg *r
 
        if (regno2 >= FIRST_PSEUDO_REGISTER && reg_renumber[regno2] >= 0)
          regno2 = reg_renumber[regno2];
-       if (regno >= FIRST_PSEUDO_REGISTER)
+       if (regno2 >= FIRST_PSEUDO_REGISTER)
          nregs2 = 1;
        else
          nregs2 = hard_regno_nregs[regno2][reg->biggest_mode];
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

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

        PR middle-end/81768
        * omp-low.c (expand_omp_simd): Force second operands of COND_EXPR
        into gimple val before gimplification fo the COND_EXPR.

        * gcc.dg/gomp/pr81768-1.c: New test.

--- gcc/omp-low.c       (revision 251855)
+++ gcc/omp-low.c       (revision 251856)
@@ -4725,24 +4725,28 @@ expand_omp_simd (struct omp_region *regi
              tree itype2 = TREE_TYPE (fd->loops[i - 1].v);
              if (POINTER_TYPE_P (itype2))
                itype2 = signed_type_for (itype2);
+             t = fold_convert (itype2, fd->loops[i - 1].step);
+             t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true,
+                                           GSI_SAME_STMT);
              t = build3 (COND_EXPR, itype2,
                          build2 (fd->loops[i].cond_code, boolean_type_node,
                                  fd->loops[i].v,
                                  fold_convert (itype, fd->loops[i].n2)),
-                         build_int_cst (itype2, 0),
-                         fold_convert (itype2, fd->loops[i - 1].step));
+                         build_int_cst (itype2, 0), t);
              if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i - 1].v)))
                t = fold_build_pointer_plus (fd->loops[i - 1].v, t);
              else
                t = fold_build2 (PLUS_EXPR, itype2, fd->loops[i - 1].v, t);
              expand_omp_build_assign (&gsi, fd->loops[i - 1].v, t);
 
+             t = fold_convert (itype, fd->loops[i].n1);
+             t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE, true,
+                                           GSI_SAME_STMT);
              t = build3 (COND_EXPR, itype,
                          build2 (fd->loops[i].cond_code, boolean_type_node,
                                  fd->loops[i].v,
                                  fold_convert (itype, fd->loops[i].n2)),
-                         fd->loops[i].v,
-                         fold_convert (itype, fd->loops[i].n1));
+                         fd->loops[i].v, t);
              expand_omp_build_assign (&gsi, fd->loops[i].v, t);
            }
        }
--- gcc/testsuite/gcc.dg/gomp/pr81768-1.c       (nonexistent)
+++ gcc/testsuite/gcc.dg/gomp/pr81768-1.c       (revision 251856)
@@ -0,0 +1,15 @@
+/* PR middle-end/81768 */
+/* { dg-do compile } */
+
+float b[10][15][10];
+
+void
+foo (void)
+{
+  float *i;
+#pragma omp target parallel for simd schedule(static, 32) collapse(3)
+  for (i = &b[0][0][0]; i < &b[0][0][10]; i++)
+    for (float *j = &b[0][15][0]; j > &b[0][0][0]; j -= 10)
+      for (float *k = &b[0][0][10]; k > &b[0][0][0]; --k)
+       b[i - &b[0][0][0]][(j - &b[0][0][0]) / 10 - 1][(k - &b[0][0][0]) - 1] 
-= 3.5;
+}
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

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

        PR middle-end/81768
        * omp-low.c (lower_omp_for): Recompute tree invariant if
        gimple_omp_for_initial/final is ADDR_EXPR.

        * gcc.dg/gomp/pr81768-2.c: New test.

--- gcc/omp-low.c       (revision 251856)
+++ gcc/omp-low.c       (revision 251857)
@@ -6927,10 +6927,14 @@ lower_omp_for (gimple_stmt_iterator *gsi
       rhs_p = gimple_omp_for_initial_ptr (stmt, i);
       if (!is_gimple_min_invariant (*rhs_p))
        *rhs_p = get_formal_tmp_var (*rhs_p, &body);
+      else if (TREE_CODE (*rhs_p) == ADDR_EXPR)
+       recompute_tree_invariant_for_addr_expr (*rhs_p);
 
       rhs_p = gimple_omp_for_final_ptr (stmt, i);
       if (!is_gimple_min_invariant (*rhs_p))
        *rhs_p = get_formal_tmp_var (*rhs_p, &body);
+      else if (TREE_CODE (*rhs_p) == ADDR_EXPR)
+       recompute_tree_invariant_for_addr_expr (*rhs_p);
 
       rhs_p = &TREE_OPERAND (gimple_omp_for_incr (stmt, i), 1);
       if (!is_gimple_min_invariant (*rhs_p))
--- gcc/testsuite/gcc.dg/gomp/pr81768-2.c       (nonexistent)
+++ gcc/testsuite/gcc.dg/gomp/pr81768-2.c       (revision 251857)
@@ -0,0 +1,15 @@
+/* PR middle-end/81768 */
+/* { dg-do compile } */
+
+float b[10][15][10];
+
+void
+foo (void)
+{
+  float *i;
+#pragma omp target parallel for schedule(static, 32) collapse(3)
+  for (i = &b[0][0][0]; i < &b[0][0][10]; i++)
+    for (float *j = &b[0][15][0]; j > &b[0][0][0]; j -= 10)
+      for (float *k = &b[0][0][10]; k > &b[0][0][0]; --k)
+        b[i - &b[0][0][0]][(j - &b[0][0][0]) / 10 - 1][(k - &b[0][0][0]) - 1] 
-= 3.5;
+}
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

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

        PR target/82112
        * c-common.c (sync_resolve_size): Instead of c_dialect_cxx ()
        assertion check that in the condition.
        (get_atomic_generic_size): Likewise.  Before testing if parameter
        has pointer type, if it has array type, call for C++
        default_conversion to perform array-to-pointer conversion.

        * c-c++-common/pr82112.c: New test.
        * gcc.dg/pr82112.c: New test.

--- gcc/c-family/c-common.c     (revision 252802)
+++ gcc/c-family/c-common.c     (revision 252803)
@@ -6576,10 +6576,9 @@ sync_resolve_size (tree function, vec<tr
     }
 
   argtype = type = TREE_TYPE ((*params)[0]);
-  if (TREE_CODE (type) == ARRAY_TYPE)
+  if (TREE_CODE (type) == ARRAY_TYPE && c_dialect_cxx ())
     {
       /* Force array-to-pointer decay for C++.  */
-      gcc_assert (c_dialect_cxx());
       (*params)[0] = default_conversion ((*params)[0]);
       type = TREE_TYPE ((*params)[0]);
     }
@@ -6741,10 +6740,9 @@ get_atomic_generic_size (location_t loc,
 
   /* Get type of first parameter, and determine its size.  */
   type_0 = TREE_TYPE ((*params)[0]);
-  if (TREE_CODE (type_0) == ARRAY_TYPE)
+  if (TREE_CODE (type_0) == ARRAY_TYPE && c_dialect_cxx ())
     {
       /* Force array-to-pointer decay for C++.  */
-      gcc_assert (c_dialect_cxx());
       (*params)[0] = default_conversion ((*params)[0]);
       type_0 = TREE_TYPE ((*params)[0]);
     }
@@ -6783,6 +6781,12 @@ get_atomic_generic_size (location_t loc,
       /* __atomic_compare_exchange has a bool in the 4th position, skip it.  */
       if (n_param == 6 && x == 3)
         continue;
+      if (TREE_CODE (type) == ARRAY_TYPE && c_dialect_cxx ())
+       {
+         /* Force array-to-pointer decay for C++.  */
+         (*params)[x] = default_conversion ((*params)[x]);
+         type = TREE_TYPE ((*params)[x]);
+       }
       if (!POINTER_TYPE_P (type))
        {
          error_at (loc, "argument %d of %qE must be a pointer type", x + 1,
--- gcc/testsuite/gcc.dg/pr82112.c      (nonexistent)
+++ gcc/testsuite/gcc.dg/pr82112.c      (revision 252803)
@@ -0,0 +1,21 @@
+/* PR target/82112 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu90" } */
+
+struct S { int a[10]; } bar (void);
+int b, c;
+
+void
+foo (void)
+{
+  __atomic_load (bar ().a, &b, __ATOMIC_ACQUIRE);      /* { dg-error "argument 
1 of .__atomic_load. must be a non-void pointer type" } */
+  __atomic_load (&b, bar ().a, __ATOMIC_ACQUIRE);      /* { dg-error "argument 
2 of .__atomic_load. must be a pointer type" } */
+  __atomic_store (bar ().a, &b, __ATOMIC_SEQ_CST);     /* { dg-error "argument 
1 of .__atomic_store. must be a non-void pointer type" } */
+  __atomic_store (&b, bar ().a, __ATOMIC_SEQ_CST);     /* { dg-error "argument 
2 of .__atomic_store. must be a pointer type" } */
+  __atomic_exchange (bar ().a, &b, &c, __ATOMIC_RELAXED);      /* { dg-error 
"argument 1 of .__atomic_exchange. must be a non-void pointer type" } */
+  __atomic_exchange (&b, bar ().a, &c, __ATOMIC_RELAXED);      /* { dg-error 
"argument 2 of .__atomic_exchange. must be a pointer type" } */
+  __atomic_exchange (&b, &c, bar ().a, __ATOMIC_RELAXED);      /* { dg-error 
"argument 3 of .__atomic_exchange. must be a pointer type" } */
+  __atomic_compare_exchange (bar ().a, &b, &c, 1, __ATOMIC_RELAXED, 
__ATOMIC_RELAXED); /* { dg-error "argument 1 of .__atomic_compare_exchange. 
must be a non-void pointer type" } */
+  __atomic_compare_exchange (&b, bar ().a, &c, 1, __ATOMIC_RELAXED, 
__ATOMIC_RELAXED); /* { dg-error "argument 2 of .__atomic_compare_exchange. 
must be a pointer type" } */
+  __atomic_compare_exchange (&b, &c, bar ().a, 1, __ATOMIC_RELAXED, 
__ATOMIC_RELAXED); /* { dg-error "argument 3 of .__atomic_compare_exchange. 
must be a pointer type" } */
+}
--- gcc/testsuite/c-c++-common/pr82112.c        (nonexistent)
+++ gcc/testsuite/c-c++-common/pr82112.c        (revision 252803)
@@ -0,0 +1,13 @@
+/* PR target/82112 */
+/* { dg-do compile } */
+
+int c[10], d[10], e[10], f[10], g[10], h[10], i[10], j[10], k[10], l[10];
+
+void
+foo (void)
+{
+  __atomic_load (c, d, __ATOMIC_ACQUIRE);
+  __atomic_store (e, f, __ATOMIC_SEQ_CST);
+  __atomic_exchange (g, h, i, __ATOMIC_RELAXED);
+  __atomic_compare_exchange (j, k, l, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+}
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

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

        PR target/82112
        * gcc.target/powerpc/pr82112.c: New test.
        * g++.dg/ext/altivec-18.C: New test.

--- gcc/testsuite/gcc.target/powerpc/pr82112.c  (nonexistent)
+++ gcc/testsuite/gcc.target/powerpc/pr82112.c  (revision 252804)
@@ -0,0 +1,16 @@
+/* PR target/82112 */
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec -std=gnu90" } */
+
+#include <altivec.h>
+
+struct __attribute__((aligned (16))) S { unsigned char c[64]; } bar (void);
+vector unsigned char v;
+
+void
+foo (void)
+{
+  vec_ld (0, bar ().c);        /* { dg-error "invalid parameter combination 
for AltiVec intrinsic" } */
+  vec_st (v, 0, bar ().c);     /* { dg-error "invalid parameter combination 
for AltiVec intrinsic" } */
+}
--- gcc/testsuite/g++.dg/ext/altivec-18.C       (nonexistent)
+++ gcc/testsuite/g++.dg/ext/altivec-18.C       (revision 252804)
@@ -0,0 +1,14 @@
+// PR target/82112
+// { dg-do compile { target powerpc*-*-* } }
+// { dg-require-effective-target powerpc_altivec_ok }
+// { dg-options "-maltivec" }
+
+#include <altivec.h>
+
+__attribute__((aligned (16))) extern const unsigned char c[16];
+
+void
+foo (void)
+{
+  vec_ld (0, c);
+}
2017-09-15  Jakub Jelinek  <ja...@redhat.com>

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

        PR c++/81314
        * cp-gimplify.c (omp_var_to_track): Look through references.
        (omp_cxx_notice_variable): Likewise.

        * testsuite/libgomp.c++/pr81314.C: New test.

--- gcc/cp/cp-gimplify.c        (revision 252805)
+++ gcc/cp/cp-gimplify.c        (revision 252806)
@@ -924,6 +924,8 @@ omp_var_to_track (tree decl)
   tree type = TREE_TYPE (decl);
   if (is_invisiref_parm (decl))
     type = TREE_TYPE (type);
+  else if (TREE_CODE (type) == REFERENCE_TYPE)
+    type = TREE_TYPE (type);
   while (TREE_CODE (type) == ARRAY_TYPE)
     type = TREE_TYPE (type);
   if (type == error_mark_node || !CLASS_TYPE_P (type))
@@ -976,6 +978,8 @@ omp_cxx_notice_variable (struct cp_gener
              tree type = TREE_TYPE (decl);
              if (is_invisiref_parm (decl))
                type = TREE_TYPE (type);
+             else if (TREE_CODE (type) == REFERENCE_TYPE)
+               type = TREE_TYPE (type);
              while (TREE_CODE (type) == ARRAY_TYPE)
                type = TREE_TYPE (type);
              get_copy_ctor (type, tf_none);
--- libgomp/testsuite/libgomp.c++/pr81314.C     (nonexistent)
+++ libgomp/testsuite/libgomp.c++/pr81314.C     (revision 252806)
@@ -0,0 +1,38 @@
+// PR c++/81314
+// { dg-do link }
+
+template <int N>
+struct S {
+  S () { s = 0; }
+  S (const S &x) { s = x.s; }
+  ~S () {}
+  int s;
+};
+
+void
+foo (S<2> &x)
+{
+  #pragma omp taskloop
+  for (int i = 0; i < 100; ++i)
+    x.s++;
+}
+
+void
+bar (S<3> &x)
+{
+  #pragma omp task
+  x.s++;
+}
+
+int
+main ()
+{
+  S<2> s;
+  S<3> t;
+  #pragma omp parallel
+  #pragma omp master
+  {
+    foo (s);
+    bar (t);
+  }
+}

Reply via email to