diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d5e89b783a239f8335ffb234b859b4c39e6b98cd..f008e7805de0a6120aefd19747c8ec232cd207c3 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2019-05-29  Jakub Jelinek  <jakub@redhat.com>
+
+	* gimplify.c (struct gimplify_omp_ctx): Add clauses member.
+	(gimplify_scan_omp_clauses): Initialize ctx->clauses.
+	(gimplify_adjust_omp_clauses_1): Transform lastprivate conditional
+	explicit clause on combined parallel into implicit shared clause.
+	(gimplify_adjust_omp_clauses): Move lastprivate conditional clause
+	and firstprivate if the decl has one too from combined parallel to
+	the worksharing construct.
+
 2019-05-28  Bill Schmidt  <wschmidt@linux.ibm.com>
 	    Michael Meissner  <meissner@linux.ibm.com>
 
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index a0177b25f563160aa6f993ec218dc272523a9423..539cc402af17ea8e465612a2fcd90f2f0d02278a 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -205,6 +205,7 @@ struct gimplify_omp_ctx
   struct gimplify_omp_ctx *outer_context;
   splay_tree variables;
   hash_set<tree> *privatized_types;
+  tree clauses;
   /* Iteration variables in an OMP_FOR.  */
   vec<tree> loop_iter_var;
   location_t location;
@@ -8054,7 +8055,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
   struct gimplify_omp_ctx *ctx, *outer_ctx;
   tree c;
   hash_map<tree, tree> *struct_map_to_clause = NULL;
-  tree *prev_list_p = NULL;
+  tree *prev_list_p = NULL, *orig_list_p = list_p;
   int handled_depend_iterators = -1;
   int nowait = -1;
 
@@ -8143,7 +8144,9 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
 	    }
 	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
 	    {
-	      if (code == OMP_FOR || code == OMP_SECTIONS)
+	      if (code == OMP_FOR
+		  || code == OMP_SECTIONS
+		  || region_type == ORT_COMBINED_PARALLEL)
 		flags |= GOVD_LASTPRIVATE_CONDITIONAL;
 	      else
 		{
@@ -9312,6 +9315,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
 	list_p = &OMP_CLAUSE_CHAIN (c);
     }
 
+  ctx->clauses = *orig_list_p;
   gimplify_omp_ctxp = ctx;
   if (struct_map_to_clause)
     delete struct_map_to_clause;
@@ -9455,6 +9459,9 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
   tree clause;
   bool private_debug;
 
+  if (gimplify_omp_ctxp->region_type == ORT_COMBINED_PARALLEL
+      && (flags & GOVD_LASTPRIVATE_CONDITIONAL) != 0)
+    flags = GOVD_SHARED | GOVD_SEEN | GOVD_WRITTEN;
   if (flags & (GOVD_EXPLICIT | GOVD_LOCAL))
     return 0;
   if ((flags & GOVD_SEEN) == 0)
@@ -9697,6 +9704,34 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
 			   omp_find_stores_op, &wi);
 	}
     }
+
+  if (ctx->region_type == ORT_WORKSHARE
+      && ctx->outer_context
+      && ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
+    {
+      for (c = ctx->outer_context->clauses; c; c = OMP_CLAUSE_CHAIN (c))
+	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+	    && OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c))
+	  {
+	    decl = OMP_CLAUSE_DECL (c);
+	    splay_tree_node n
+	      = splay_tree_lookup (ctx->outer_context->variables,
+				   (splay_tree_key) decl);
+	    gcc_checking_assert (!splay_tree_lookup (ctx->variables,
+						     (splay_tree_key) decl));
+	    omp_add_variable (ctx, decl, n->value);
+	    tree c2 = copy_node (c);
+	    OMP_CLAUSE_CHAIN (c2) = *list_p;
+	    *list_p = c2;
+	    if ((n->value & GOVD_FIRSTPRIVATE) == 0)
+	      continue;
+	    c2 = build_omp_clause (OMP_CLAUSE_LOCATION (c),
+				   OMP_CLAUSE_FIRSTPRIVATE);
+	    OMP_CLAUSE_DECL (c2) = decl;
+	    OMP_CLAUSE_CHAIN (c2) = *list_p;
+	    *list_p = c2;
+	  }
+    }
   while ((c = *list_p) != NULL)
     {
       splay_tree_node n;
@@ -9723,6 +9758,10 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
 	  decl = OMP_CLAUSE_DECL (c);
 	  n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
 	  remove = !(n->value & GOVD_SEEN);
+	  if ((n->value & GOVD_LASTPRIVATE_CONDITIONAL) != 0
+	      && code == OMP_PARALLEL
+	      && OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE)
+	    remove = true;
 	  if (! remove)
 	    {
 	      bool shared = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED;
@@ -9771,6 +9810,8 @@ gimplify_adjust_omp_clauses (gimple_seq *pre_p, gimple_seq body, tree *list_p,
 	      && DECL_P (decl)
 	      && omp_shared_to_firstprivate_optimizable_decl_p (decl))
 	    omp_mark_stores (gimplify_omp_ctxp->outer_context, decl);
+	  if (OMP_CLAUSE_LASTPRIVATE_CONDITIONAL (c) && code == OMP_PARALLEL)
+	    remove = true;
 	  break;
 
 	case OMP_CLAUSE_ALIGNED:
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 9ca22fb61ea51aa421f2e75bb905d049ec0439fa..aec79b1e6b9191d1a32fee8de1304c4052878410 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,11 @@
 2019-05-29  Jakub Jelinek  <jakub@redhat.com>
 
+	* c-c++-common/gomp/lastprivate-conditional-2.c (foo): Don't expect
+	sorry on lastprivate conditional on parallel for.
+	* c-c++-common/gomp/lastprivate-conditional-3.c (foo): Add tests for
+	lastprivate conditional warnings on parallel for constructs.
+	* c-c++-common/gomp/lastprivate-conditional-4.c: New test.
+
 	PR c/90628
 	* c-c++-common/builtin-arith-overflow-3.c: New test.
 
diff --git a/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-2.c b/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-2.c
index 34c7e12287b4ec64df83d789b40e0317216a9831..549ab4846632019c7ac58696763ba658a2772d45 100644
--- a/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-2.c
@@ -17,7 +17,7 @@ foo (int *p)
   for (i = 0; i < 32; i++)
     if (p[i])
       c = i;
-  #pragma omp parallel for lastprivate (conditional: d) /* { dg-message "not supported yet" } */
+  #pragma omp parallel for lastprivate (conditional: d)
   for (i = 0; i < 32; i++)
     if (p[i])
       d = i;
diff --git a/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-3.c b/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-3.c
index bf413ec8d9b4f0cfa51be5b4e474dcabdb697750..dc9b003753c3c33743db63d13a3b4694c83837e8 100644
--- a/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-3.c
+++ b/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-3.c
@@ -23,4 +23,22 @@ foo (int *p)
 	for (k = 0; k < 2; ++k)
 	  ;
   }
+  #pragma omp parallel for lastprivate (conditional: i)	/* { dg-warning "conditional 'lastprivate' on loop iterator 'i' ignored" } */
+  for (i = 0; i < 32; i++)
+    ;
+  #pragma omp parallel for collapse (3) lastprivate (conditional: i)	/* { dg-warning "conditional 'lastprivate' on loop iterator 'i' ignored" } */
+  for (i = 0; i < 32; i++)
+    for (j = 0; j < 32; ++j)
+      for (k = 0; k < 2; ++k)
+	;
+  #pragma omp parallel for collapse (3) lastprivate (conditional: j)	/* { dg-warning "conditional 'lastprivate' on loop iterator 'j' ignored" } */
+  for (i = 0; i < 32; i++)
+    for (j = 0; j < 32; ++j)
+      for (k = 0; k < 2; ++k)
+	;
+  #pragma omp parallel for collapse (3) lastprivate (conditional: k)	/* { dg-warning "conditional 'lastprivate' on loop iterator 'k' ignored" } */
+  for (i = 0; i < 32; i++)
+    for (j = 0; j < 32; ++j)
+      for (k = 0; k < 2; ++k)
+	;
 }
diff --git a/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-4.c b/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-4.c
new file mode 100644
index 0000000000000000000000000000000000000000..d87c7982b2693c4c72c38e950eee1aae609c2aed
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/lastprivate-conditional-4.c
@@ -0,0 +1,23 @@
+int x = 6, w = 8;
+int bar (int);
+
+void
+foo ()
+{
+  int y = 5, i;
+  #pragma omp teams num_teams(1) firstprivate (x) shared (y) shared (w)
+  {
+    int z = 7;
+    #pragma omp parallel for firstprivate (x, y, z, w) lastprivate (conditional: x, y, z, w)
+    for (i = 0; i < 64; i++)
+      if (bar (i))
+	{
+	  x = i;
+	  y = i + 1;
+	  z = i + 2;
+	  w = i + 3;
+	}
+    bar (y);
+    bar (z);
+  }
+}
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index e6cda724fbd2fe2ea9d258f7142193dafbde14f9..b9bf097319c839b62ab7c998c917f5938c759a71 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,11 @@
+2019-05-29  Jakub Jelinek  <jakub@redhat.com>
+
+	* testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: Rename
+	to ...
+	* testsuite/libgomp.c-c++-common/lastprivate-conditional-4.c: ... this.
+	* testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c: New test.
+	* testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c: New test.
+
 2019-05-27  Jakub Jelinek  <jakub@redhat.com>
 
 	* testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c: New test.
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-4.c
similarity index 100%
rename from libgomp/testsuite/libgomp.c-c++-common/lastprivate_conditional_4.c
rename to libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-4.c
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c
new file mode 100644
index 0000000000000000000000000000000000000000..de6b9a87c1f343f238f56dce1e9d731f49e0faae
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-5.c
@@ -0,0 +1,143 @@
+/* { dg-do run } */
+/* { dg-require-effective-target tls_runtime } */
+/* { dg-additional-options "-std=gnu99" {target c } } */
+
+#include <omp.h>
+#include <stdlib.h>
+
+int r, s, u, v, r2, s2, u2, v2, r3, s3, u3, v3;
+long long w, w2, w3, p, p2, p3;
+int *x, *x2, *x3;
+short y, y2, y3;
+int z;
+int thr1, thr2;
+#pragma omp threadprivate (thr1, thr2)
+
+void
+foo (int *a, long long int b, long long int c)
+{
+  int i;
+  long long j;
+  #pragma omp parallel for lastprivate (conditional: u, x)
+  for (i = 15; i < 64; i++)
+    {
+      if ((a[i] % 5) == 3)
+	u = i;
+      if ((a[i] % 7) == 2)
+	x = &a[i];
+    }
+  #pragma omp parallel for lastprivate (conditional: v) reduction (+:r, s) schedule (nonmonotonic: static)
+  for (i = -3; i < 119; i += 2)
+    {
+      ++s;
+      if ((a[i + 4] % 11) == 9)
+	v = i;
+      else
+	++r;
+    }
+  #pragma omp parallel for schedule (monotonic: static) lastprivate (conditional: w)
+  for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+    if ((a[j] % 13) == 5)
+      w = j * 2;
+  #pragma omp parallel for schedule (auto) lastprivate (conditional: p) collapse(3)
+  for (i = -5; i < (int) (b + 5); i += 2)
+    for (j = b + 12 + c; j > b; --j)
+      for (int k = 0; k < 5; k += c)
+	if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+	  p = i * 10000 + j * 100 + k;
+
+  #pragma omp parallel for schedule (nonmonotonic: static, 2) lastprivate (conditional: u2, x2)
+  for (i = 15; i < 64; i++)
+    {
+      if ((a[i] % 5) == 3)
+	u2 = i;
+      if ((a[i] % 7) == 2)
+	x2 = &a[i];
+    }
+  #pragma omp parallel for schedule (static, 3) lastprivate (conditional: v2) reduction (+:r2, s2)
+  for (i = -3; i < 119; i += 2)
+    {
+      ++s2;
+      if ((a[i + 4] % 11) == 9)
+	v2 = i;
+      else
+	++r2;
+    }
+  #pragma omp parallel for lastprivate (conditional: w2) schedule (static, 1)
+  for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+    if ((a[j] % 13) == 5)
+      w2 = j * 2;
+  #pragma omp parallel for schedule (static, 3) collapse (3) lastprivate (conditional: p2)
+  for (i = -5; i < (int) (b + 5); i += 2)
+    for (j = b + 12 + c; j > b; --j)
+      for (int k = 0; k < 5; k += c)
+	if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+	  p2 = i * 10000 + j * 100 + k;
+
+  #pragma omp parallel for lastprivate (conditional: u3, x3) schedule (runtime)
+  for (i = 15; i < 64; i++)
+    {
+      if ((a[i] % 5) == 3)
+	u3 = i;
+      if ((a[i] % 7) == 2)
+	x3 = &a[i];
+    }
+  #pragma omp parallel for lastprivate (conditional: v3) reduction (+:r3, s3) schedule (nonmonotonic: dynamic)
+  for (i = -3; i < 119; i += 2)
+    {
+      ++s3;
+      if ((a[i + 4] % 11) == 9)
+	v3 = i;
+      else
+	++r3;
+    }
+  #pragma omp parallel for schedule (monotonic: guided, 3) lastprivate (conditional: w3)
+  for (j = b; j < b + 115 * c; j += (b & 3) + 7)
+    if ((a[j] % 13) == 5)
+      w3 = j * 2;
+  #pragma omp parallel for schedule (dynamic, 4) lastprivate (conditional: p3) collapse(3)
+  for (i = -5; i < (int) (b + 5); i += 2)
+    for (j = b + 12 + c; j > b; --j)
+      for (int k = 0; k < 5; k += c)
+	if (((((i + 5) * 13 + (13 - j)) * 5 + k) % 17) == 6)
+	  p3 = i * 10000 + j * 100 + k;
+
+  /* Nasty testcase, verify that even a no-op assignment is accounted
+     for in lastprivate(conditional:).  */
+  #pragma omp parallel for schedule (monotonic: static, 2) firstprivate (z) \
+			   lastprivate (conditional: z)
+  for (int k = -2000; k < 8000; ++k)
+    {
+      if (k < 3000 && (k & 3) == 1)
+	{
+	  z = k;
+	  thr1 = k;
+	}
+      else if (k == 7931)
+	{
+	  z = z;
+	  thr2 = 1;
+	}
+    }
+
+  if (thr2 && z != thr1)
+    abort ();
+}
+
+int
+main ()
+{
+  int a[128], i;
+  volatile int j = 0;
+  for (i = 0; i < 128; i++)
+    a[i] = i;
+  w = 1234;
+  foo (a, j, j + 1);
+  if (u != 63 || v != 115 || w != 140 || x != &a[58] || r != 55 || s != 61 || p != 30104)
+    abort ();
+  if (u2 != 63 || v2 != 115 || w2 != 140 || x2 != &a[58] || r2 != 55 || s2 != 61 || p2 != 30104)
+    abort ();
+  if (u3 != 63 || v3 != 115 || w3 != 140 || x3 != &a[58] || r3 != 55 || s3 != 61 || p3 != 30104)
+    abort ();
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c
new file mode 100644
index 0000000000000000000000000000000000000000..d21379358590af59d525d5429c29ec2e53d7ef71
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c-c++-common/lastprivate-conditional-6.c
@@ -0,0 +1,159 @@
+#include <stdlib.h>
+
+int x;
+long long y;
+int r, s, t;
+
+void
+foo (const char *a)
+{
+  #pragma omp parallel sections lastprivate (conditional: x, y)
+  {
+    if (a[0])
+      x = a[0];
+    #pragma omp section
+    {
+      if (a[1])
+	x = a[1];
+      if (a[2])
+	y = a[2];
+    }
+    #pragma omp section
+    if (a[3])
+      y = a[3];
+    #pragma omp section
+    if (a[4])
+      x = a[4];
+    #pragma omp section
+    {
+      if (a[5])
+	x = a[5];
+      if (a[6])
+	y = a[6];
+    }
+  }
+}
+
+void
+bar (const char *a)
+{
+  #pragma omp parallel sections lastprivate (conditional: x, y) reduction (task, +: t)
+  {
+    if (a[0])
+      x = a[0];
+    #pragma omp section
+    {
+      if (a[1])
+	x = a[1];
+      if (a[2])
+	y = a[2];
+      #pragma omp task in_reduction (+: t)
+      t++;
+    }
+    #pragma omp section
+    if (a[3])
+      y = a[3];
+    #pragma omp section
+    if (a[4])
+      x = a[4];
+    #pragma omp section
+    {
+      #pragma omp task in_reduction (+: t)
+      ++t;
+      if (a[5])
+	x = a[5];
+      if (a[6])
+	y = a[6];
+    }
+  }
+}
+
+void
+baz (const char *a)
+{
+  #pragma omp parallel sections lastprivate (conditional: x, y) reduction (+: r, s)
+  {
+    if (a[0])
+      x = a[0];
+    #pragma omp section
+    {
+      if (a[1])
+	x = a[1];
+      ++r;
+      ++s;
+      if (a[2])
+	y = a[2];
+    }
+    #pragma omp section
+    if (a[3])
+      y = a[3];
+    #pragma omp section
+    {
+      ++s;
+      if (a[4])
+	x = a[4];
+    }
+    #pragma omp section
+    {
+      if (a[5])
+	x = a[5];
+      if (a[6])
+	y = a[6];
+      ++s;
+    }
+  }
+}
+
+int
+main ()
+{
+  foo ("\0\1\2\3\0\5");
+  if (x != 5 || y != 3)
+    abort ();
+
+  foo ("\6\0\0\0\0\0\7");
+  if (x != 6 || y != 7)
+    abort ();
+
+  foo ("\7\6\5\4\3\2\1");
+  if (x != 2 || y != 1)
+    abort ();
+
+  foo ("\0\0\4\3\0\7");
+  if (x != 7 || y != 3)
+    abort ();
+
+  bar ("\0\1\2\4\0\5");
+  if (x != 5 || y != 4 || t != 2)
+    abort ();
+
+  bar ("\6\0\0\0\0\0\7");
+  if (x != 6 || y != 7 || t != 4)
+    abort ();
+
+  bar ("\7\6\5\4\3\2\1");
+  if (x != 2 || y != 1 || t != 6)
+    abort ();
+
+  bar ("\0\0\4\3\0\7");
+  if (x != 7 || y != 3 || t != 8)
+    abort ();
+
+  baz ("\0\1\2\4\0\5");
+  if (x != 5 || y != 4 || r != 1 || s != 3)
+    abort ();
+
+  baz ("\6\0\0\0\0\0\7");
+  if (x != 6 || y != 7 || r != 2 || s != 6)
+    abort ();
+
+  baz ("\7\6\5\4\3\2\1");
+  if (x != 2 || y != 1 || r != 3 || s != 9)
+    abort ();
+
+  baz ("\0\0\4\3\0\7");
+  if (x != 7 || y != 3 || r != 4 || s != 12)
+    abort ();
+
+  return 0;
+}