diff --git a/gcc/testsuite/c-c++-common/goacc-gomp/nesting-1.c b/gcc/testsuite/c-c++-common/goacc-gomp/nesting-1.c
index 51c5e359f29801006dcd5d7235d2d9b2762d59c0..9ef154ed218b4d716c435a42fcfc6b6e42657b8b 100644
--- a/gcc/testsuite/c-c++-common/goacc-gomp/nesting-1.c
+++ b/gcc/testsuite/c-c++-common/goacc-gomp/nesting-1.c
@@ -62,3 +62,16 @@ f_acc_parallel (void)
     i = 0;
   }
 }
+
+void
+f_acc_serial (void)
+{
+#pragma acc serial
+  /* { dg-note {variable 'i' declared in block is candidate for adjusting OpenACC privatization level} "" { target *-*-* } .-1 }
+     { dg-note {variable 'i' ought to be adjusted for OpenACC privatization level: 'gang'} "" { target *-*-* } .-2 } */
+  {
+    int i;
+#pragma omp atomic write
+    i = 0;
+  }
+}
diff --git a/gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c b/gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c
index ddbd247342f026cf23831934ed51d28635397c34..740e164ea9cad4f6f4d853da0207ec59ba7e2a7f 100644
--- a/gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c
+++ b/gcc/testsuite/c-c++-common/goacc-gomp/nesting-fail-1.c
@@ -10,6 +10,8 @@ f_omp (void)
     ;
 #pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
+#pragma acc serial /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
+    ;
 #pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
 #pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
@@ -27,6 +29,8 @@ f_omp (void)
       ;
 #pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
       ;
+#pragma acc serial /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
+      ;
 #pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
       ;
 #pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
@@ -50,6 +54,11 @@ f_omp (void)
     }
 #pragma omp section
     {
+#pragma acc serial /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
+      ;
+    }
+#pragma omp section
+    {
 #pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
       ;
     }
@@ -79,6 +88,8 @@ f_omp (void)
     ;
 #pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
+#pragma acc serial /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
+    ;
 #pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
 #pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
@@ -95,6 +106,8 @@ f_omp (void)
     ;
 #pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
+#pragma acc serial /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
+    ;
 #pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
 #pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
@@ -111,6 +124,8 @@ f_omp (void)
     ;
 #pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
+#pragma acc serial /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
+    ;
 #pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
 #pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
@@ -127,6 +142,8 @@ f_omp (void)
     ;
 #pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
+#pragma acc serial /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
+    ;
 #pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
 #pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
@@ -143,6 +160,8 @@ f_omp (void)
     ;
 #pragma acc kernels /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
+#pragma acc serial /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
+    ;
 #pragma acc data /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
     ;
 #pragma acc update host(i) /* { dg-error "OpenACC construct inside of non-OpenACC region" } */
@@ -159,6 +178,8 @@ f_omp (void)
     ;
 #pragma acc kernels /* { dg-error "OpenACC .kernels. construct inside of OpenMP .target. region" } */
     ;
+#pragma acc serial /* { dg-error "OpenACC .serial. construct inside of OpenMP .target. region" } */
+    ;
 #pragma acc data /* { dg-error "OpenACC .data. construct inside of OpenMP .target. region" } */
     ;
 #pragma acc update host(i) /* { dg-error "OpenACC .update. construct inside of OpenMP .target. region" } */
@@ -298,6 +319,70 @@ f_acc_kernels (void)
   }
 }
 
+void
+f_acc_serial (void)
+{
+#pragma acc serial
+  {
+#pragma omp parallel /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+    ;
+  }
+
+#pragma acc serial
+  {
+#pragma omp for /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+    for (i = 0; i < 3; i++)
+      ;
+  }
+
+#pragma acc serial
+  {
+#pragma omp sections /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+    {
+      ;
+    }
+  }
+
+#pragma acc serial
+  {
+#pragma omp single /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+    ;
+  }
+
+#pragma acc serial
+  {
+#pragma omp task /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+    ;
+  }
+
+#pragma acc serial
+  {
+#pragma omp master /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+    ;
+  }
+
+#pragma acc serial
+  {
+#pragma omp critical /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+    ;
+  }
+
+#pragma acc serial
+  {
+#pragma omp ordered /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+    ;
+  }
+
+#pragma acc serial
+  {
+#pragma omp target /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+    ;
+#pragma omp target data map(i) /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+    ;
+#pragma omp target update to(i) /* { dg-error "non-OpenACC construct inside of OpenACC region" } */
+  }
+}
+
 void
 f_acc_data (void)
 {
diff --git a/gcc/testsuite/c-c++-common/goacc/Wparentheses-1.c b/gcc/testsuite/c-c++-common/goacc/Wparentheses-1.c
index 08265b65e0bd0426c9dab2ddbab3992c7dc1f387..c299bcea167ab5f4509121629f98d64353470d1d 100644
--- a/gcc/testsuite/c-c++-common/goacc/Wparentheses-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/Wparentheses-1.c
@@ -59,6 +59,21 @@ f1 (void)
       else
 	baz2 ();
 
+  if (a) /* { dg-warning "ambiguous" } */
+    #pragma acc serial
+      if (b)
+	bar2 ();
+      else
+	baz2 ();
+
+  if (a) /* { dg-warning "ambiguous" } */
+    #pragma acc serial loop
+    for (i = 0; i < 10; i++)
+      if (b)
+	bar2 ();
+      else
+	baz2 ();
+
   (void) d[0];
 
   if (a)
@@ -138,14 +153,23 @@ f1 (void)
       }
 
   if (a)
-    {
-      #pragma acc parallel loop
-      for (i = 0; i < 10; i++)
+    #pragma acc serial
+      {
 	if (b)
 	  bar2 ();
 	else
 	  baz2 ();
-    }
+      }
+
+  if (a)
+    #pragma acc serial loop
+    for (i = 0; i < 10; i++)
+      {
+	if (b)
+	  bar2 ();
+	else
+	  baz2 ();
+      }
 }
 
 #pragma acc routine vector
diff --git a/gcc/testsuite/c-c++-common/goacc/builtin-goacc-parlevel-id-size.c b/gcc/testsuite/c-c++-common/goacc/builtin-goacc-parlevel-id-size.c
index 19d6c21d0776f481a26677d3fd9a78dcd00a3f35..637a7c2e726ed4add8cb7303e42745768d3679a9 100644
--- a/gcc/testsuite/c-c++-common/goacc/builtin-goacc-parlevel-id-size.c
+++ b/gcc/testsuite/c-c++-common/goacc/builtin-goacc-parlevel-id-size.c
@@ -7,7 +7,7 @@
 
 #pragma acc routine
 int
-foo (void)
+foo_routine (void)
 {
   int res;
   /* { dg-note {'res' was declared here} {} { target *-*-* } .-1 } */
@@ -33,7 +33,7 @@ foo (void)
 }
 
 void
-foo2 (void)
+foo_parallel (void)
 {
   int res;
 
@@ -60,7 +60,7 @@ foo2 (void)
 }
 
 void
-foo3 (void)
+foo_kernels (void)
 {
   int res;
 
@@ -85,3 +85,30 @@ foo3 (void)
     res += __builtin_goacc_parlevel_size (GOMP_DIM_VECTOR);
   }
 }
+
+void
+foo_serial (void)
+{
+  int res;
+
+#pragma acc serial
+  /* implicit 'firstprivate (res)'
+     { dg-warning {'res' is used uninitialized} TODO { xfail *-*-* } .-2 } */
+  {
+    __builtin_goacc_parlevel_id (GOMP_DIM_GANG);
+    __builtin_goacc_parlevel_id (GOMP_DIM_WORKER);
+    __builtin_goacc_parlevel_id (GOMP_DIM_VECTOR);
+
+    __builtin_goacc_parlevel_size (GOMP_DIM_GANG);
+    __builtin_goacc_parlevel_size (GOMP_DIM_WORKER);
+    __builtin_goacc_parlevel_size (GOMP_DIM_VECTOR);
+
+    res += __builtin_goacc_parlevel_id (GOMP_DIM_GANG);
+    res += __builtin_goacc_parlevel_id (GOMP_DIM_WORKER);
+    res += __builtin_goacc_parlevel_id (GOMP_DIM_VECTOR);
+
+    res += __builtin_goacc_parlevel_size (GOMP_DIM_GANG);
+    res += __builtin_goacc_parlevel_size (GOMP_DIM_WORKER);
+    res += __builtin_goacc_parlevel_size (GOMP_DIM_VECTOR);
+  }
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/combined-directives-2.c b/gcc/testsuite/c-c++-common/goacc/combined-directives-2.c
index c51e2f9c75b8f6f12f636a32ac256800075f88eb..607d5a3861393a2d785e50eba7be9d315e912987 100644
--- a/gcc/testsuite/c-c++-common/goacc/combined-directives-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/combined-directives-2.c
@@ -10,5 +10,11 @@ main ()
   for (i = 0; i < 100; i++)
     a++;
 
+
+#pragma acc serial loop vector copy(a[0:100]) reduction(+:a) /* { dg-error "'a' does not have pointer or array type" } */
+  for (i = 0; i < 100; i++)
+    a++;
+
+
   return a;
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/combined-directives-3.c b/gcc/testsuite/c-c++-common/goacc/combined-directives-3.c
index c6e31c26a8f13733debc4aaa9d5cd3dc28d03d5a..162fd679c341ee53cb34799657892472cdb62da8 100644
--- a/gcc/testsuite/c-c++-common/goacc/combined-directives-3.c
+++ b/gcc/testsuite/c-c++-common/goacc/combined-directives-3.c
@@ -21,5 +21,21 @@ main ()
       for (z = 0; z < 10; z++)
 	;
 
+
+#pragma acc serial loop seq auto /* { dg-error "'seq' overrides other OpenACC loop specifiers" } */
+  for (x = 0; x < 10; x++)
+#pragma acc loop
+    for (y = 0; y < 10; y++)
+      ;
+
+#pragma acc serial loop gang auto /* { dg-error "'auto' conflicts with other OpenACC loop specifiers" } */
+  for (x = 0; x < 10; x++)
+#pragma acc loop worker auto /* { dg-error "'auto' conflicts with other OpenACC loop specifiers" } */
+    for (y = 0; y < 10; y++)
+#pragma acc loop vector
+      for (z = 0; z < 10; z++)
+	;
+
+
   return 0;
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/combined-directives.c b/gcc/testsuite/c-c++-common/goacc/combined-directives.c
index c2a3c57b48b83432c1bf000d279a2d09a8f2f57a..51232485fec8a8fef6f5477ba6130b302f84dbb8 100644
--- a/gcc/testsuite/c-c++-common/goacc/combined-directives.c
+++ b/gcc/testsuite/c-c++-common/goacc/combined-directives.c
@@ -8,6 +8,7 @@ test ()
 {
   int a[100], i, j, z;
 
+
   // acc parallel
 
   #pragma acc parallel loop collapse (2)
@@ -56,6 +57,7 @@ test ()
 //  for (i = 0; i < 100; i++)
 //    ;
 
+
   // acc kernels
 
   #pragma acc kernels loop collapse (2)
@@ -102,15 +104,65 @@ test ()
 
 //  #pragma acc kernels loop reduction (+:z) copy (z)
 //  for (i = 0; i < 100; i++)
+//    ;
+
+  
+  // acc serial
+
+  #pragma acc serial loop collapse (2)
+  for (i = 0; i < 100; i++)
+    for (j = 0; j < 10; j++)
+      ;
+
+  #pragma acc serial loop gang
+  for (i = 0; i < 100; i++)
+    ;
+
+  #pragma acc serial loop worker
+  for (i = 0; i < 100; i++)
+    for (j = 0; j < 10; j++)
+      ;
+
+  #pragma acc serial loop vector
+  for (i = 0; i < 100; i++)
+    for (j = 0; j < 10; j++)
+      ;
+
+  #pragma acc serial loop seq
+  for (i = 0; i < 100; i++)
+    for (j = 0; j < 10; j++)
+      ;
+
+  #pragma acc serial loop auto
+  for (i = 0; i < 100; i++)
+    for (j = 0; j < 10; j++)
+      ;
+
+  #pragma acc serial loop tile (2, 3)
+  for (i = 0; i < 100; i++)
+    for (j = 0; j < 10; j++)
+      ;
+
+  #pragma acc serial loop independent
+  for (i = 0; i < 100; i++)
+    ;
+
+  #pragma acc serial loop private (z)
+  for (i = 0; i < 100; i++)
+    z = 0;
+
+//  #pragma acc serial loop reduction (+:z) copy (z)
+//  for (i = 0; i < 100; i++)
 //    ;
 }
 
-// { dg-final { scan-tree-dump-times "acc loop collapse.2. private.j. private.i" 2 "gimple" } }
-// { dg-final { scan-tree-dump-times "acc loop gang" 2 "gimple" } }
-// { dg-final { scan-tree-dump-times "acc loop worker" 2 "gimple" } }
-// { dg-final { scan-tree-dump-times "acc loop vector" 2 "gimple" } }
-// { dg-final { scan-tree-dump-times "acc loop seq" 2 "gimple" } }
-// { dg-final { scan-tree-dump-times "acc loop auto" 2 "gimple" } }
-// { dg-final { scan-tree-dump-times "acc loop tile.2, 3" 2 "gimple" } }
-// { dg-final { scan-tree-dump-times "acc loop independent private.i" 2 "gimple" } }
-// { dg-final { scan-tree-dump-times "private.z" 2 "gimple" } }
+
+// { dg-final { scan-tree-dump-times "acc loop collapse.2. private.j. private.i" 3 "gimple" } }
+// { dg-final { scan-tree-dump-times "acc loop gang" 3 "gimple" } }
+// { dg-final { scan-tree-dump-times "acc loop worker" 3 "gimple" } }
+// { dg-final { scan-tree-dump-times "acc loop vector" 3 "gimple" } }
+// { dg-final { scan-tree-dump-times "acc loop seq" 3 "gimple" } }
+// { dg-final { scan-tree-dump-times "acc loop auto" 3 "gimple" } }
+// { dg-final { scan-tree-dump-times "acc loop tile.2, 3" 3 "gimple" } }
+// { dg-final { scan-tree-dump-times "acc loop independent private.i" 3 "gimple" } }
+// { dg-final { scan-tree-dump-times "private.z" 3 "gimple" } }
diff --git a/gcc/testsuite/c-c++-common/goacc/combined-reduction.c b/gcc/testsuite/c-c++-common/goacc/combined-reduction.c
index ecf23f59d66073b8fe44a06222a93bf92bc8df78..0a541402d9d4383400a3bd2fd3f273f5108642de 100644
--- a/gcc/testsuite/c-c++-common/goacc/combined-reduction.c
+++ b/gcc/testsuite/c-c++-common/goacc/combined-reduction.c
@@ -1,6 +1,8 @@
 /* { dg-do compile } */
 /* { dg-options "-fopenacc -fdump-tree-gimple" } */
 
+/* See also '../../gfortran.dg/goacc/reduction-2.f95'.  */
+
 #include <assert.h>
 
 int
@@ -20,6 +22,12 @@ main ()
 
   assert (v1 == n);
 
+#pragma acc serial loop reduction(+:v1)
+  for (i = 0; i < n; i++)
+    v1++;
+
+  assert (v1 == n);
+
   return 0;
 }
 
@@ -27,3 +35,5 @@ main ()
 /* { dg-final { scan-tree-dump-times "acc loop reduction.+:v1. private.i." 1 "gimple" } } */
 /* { dg-final { scan-tree-dump-times "omp target oacc_kernels map.force_tofrom:n .len: 4.. map.force_tofrom:v1 .len: 4.." 1 "gimple" } } */
 /* { dg-final { scan-tree-dump-times "acc loop reduction.+:v1. private.i." 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "omp target oacc_serial reduction.+:v1. map.tofrom:v1" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "acc loop reduction.+:v1. private.i." 1 "gimple" } } */
diff --git a/gcc/testsuite/c-c++-common/goacc/data-clause-duplicate-1.c b/gcc/testsuite/c-c++-common/goacc/data-clause-duplicate-1.c
index 6245beb20794e2c60f437b05388b7c9f0fc44504..c87ef8bee84c9546386b355cfd1f4c6d67f46103 100644
--- a/gcc/testsuite/c-c++-common/goacc/data-clause-duplicate-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/data-clause-duplicate-1.c
@@ -6,6 +6,8 @@ fun (void)
   ;
 #pragma acc kernels present_or_copyin(fp[3]) present_or_copyout(fp[7:4]) /* { dg-error "'fp' appears more than once in data clauses" } */
   ;
+#pragma acc serial present(fp[0:2]) copyin(fp[0:2]) /* { dg-error "'fp' appears more than once in data clauses" } */
+  ;
 #pragma acc data create(fp[:10]) deviceptr(fp) /* { dg-error "'fp' appears more than once in data clauses" } */
   ;
 #pragma acc data create(fp) present(fp) /* { dg-error "'fp' appears more than once in data clauses" } */
diff --git a/gcc/testsuite/c-c++-common/goacc/default-1.c b/gcc/testsuite/c-c++-common/goacc/default-1.c
index 23c25ab45a9e017684f8772e23248c245f495d05..161252e37dcaad802d8a0bbf5cc70e7448b83f42 100644
--- a/gcc/testsuite/c-c++-common/goacc/default-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/default-1.c
@@ -6,9 +6,13 @@ void f1 ()
   ;
 #pragma acc parallel default (none)
   ;
+#pragma acc serial default (none)
+  ;
 
 #pragma acc kernels default (present)
   ;
 #pragma acc parallel default (present)
   ;
+#pragma acc serial default (present)
+  ;
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/default-2.c b/gcc/testsuite/c-c++-common/goacc/default-2.c
index c0cdd1263bd112c5f6e5a6cfafb11fa8bc4da724..1f3e09ec04638d2b7b551b7c3466af2c5b225772 100644
--- a/gcc/testsuite/c-c++-common/goacc/default-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/default-2.c
@@ -6,54 +6,76 @@ void f1 ()
   ;
 #pragma acc parallel default /* { dg-error "expected .\\(. before end of line" } */
   ;
+#pragma acc serial default /* { dg-error "expected .\\(. before end of line" } */
+  ;
 
 #pragma acc kernels default ( /* { dg-error "expected .none. or .present. before end of line" } */
   ;
 #pragma acc parallel default ( /* { dg-error "expected .none. or .present. before end of line" } */
   ;
+#pragma acc serial default ( /* { dg-error "expected .none. or .present. before end of line" } */
+  ;
 
 #pragma acc kernels default (, /* { dg-error "expected .none. or .present. before .,. token" } */
   ;
 #pragma acc parallel default (, /* { dg-error "expected .none. or .present. before .,. token" } */
   ;
+#pragma acc serial default (, /* { dg-error "expected .none. or .present. before .,. token" } */
+  ;
 
 #pragma acc kernels default () /* { dg-error "expected .none. or .present. before .\\). token" } */
   ;
 #pragma acc parallel default () /* { dg-error "expected .none. or .present. before .\\). token" } */
   ;
+#pragma acc serial default () /* { dg-error "expected .none. or .present. before .\\). token" } */
+  ;
 
 #pragma acc kernels default (,) /* { dg-error "expected .none. or .present. before .,. token" } */
   ;
 #pragma acc parallel default (,) /* { dg-error "expected .none. or .present. before .,. token" } */
   ;
+#pragma acc serial default (,) /* { dg-error "expected .none. or .present. before .,. token" } */
+  ;
 
 #pragma acc kernels default (firstprivate) /* { dg-error "expected .none. or .present. before .firstprivate." } */
   ;
 #pragma acc parallel default (firstprivate) /* { dg-error "expected .none. or .present. before .firstprivate." } */
   ;
+#pragma acc serial default (firstprivate) /* { dg-error "expected .none. or .present. before .firstprivate." } */
+  ;
 
 #pragma acc kernels default (private) /* { dg-error "expected .none. or .present. before .private." } */
   ;
 #pragma acc parallel default (private) /* { dg-error "expected .none. or .present. before .private." } */
   ;
+#pragma acc serial default (private) /* { dg-error "expected .none. or .present. before .private." } */
+  ;
 
 #pragma acc kernels default (shared) /* { dg-error "expected .none. or .present. before .shared." } */
   ;
 #pragma acc parallel default (shared) /* { dg-error "expected .none. or .present. before .shared." } */
   ;
+#pragma acc serial default (shared) /* { dg-error "expected .none. or .present. before .shared." } */
+  ;
 
 #pragma acc kernels default (none /* { dg-error "expected .\\). before end of line" } */
   ;
 #pragma acc parallel default (none /* { dg-error "expected .\\). before end of line" } */
   ;
+#pragma acc serial default (none /* { dg-error "expected .\\). before end of line" } */
+  ;
 
 #pragma acc kernels default (none none) /* { dg-error "expected .\\). before .none." } */
   ;
 #pragma acc parallel default (none none) /* { dg-error "expected .\\). before .none." } */
   ;
+#pragma acc serial default (none none) /* { dg-error "expected .\\). before .none." } */
+  ;
 
 #pragma acc kernels default (none, none) /* { dg-error "expected .\\). before .,. token" } */
   ;
 #pragma acc parallel default (none, none) /* { dg-error "expected .\\). before .,. token" } */
   ;
+#pragma acc serial default (none, none) /* { dg-error "expected .\\). before .,. token" } */
+  ;
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/default-3.c b/gcc/testsuite/c-c++-common/goacc/default-3.c
index 73dbc90847587cd81f62d5acd250d7790aa2e622..feee3fbb0737ca1feaf25e2a52163587814da4da 100644
--- a/gcc/testsuite/c-c++-common/goacc/default-3.c
+++ b/gcc/testsuite/c-c++-common/goacc/default-3.c
@@ -15,6 +15,11 @@ void f1 ()
     f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .parallel. construct" } */
       = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .parallel. construct" } */
   }
+#pragma acc serial default (none) /* { dg-note "enclosing OpenACC 'serial' construct with 'default\\\(none\\\)' clause" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" } */
+  }
 
 #pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
 #pragma acc kernels /* { dg-note "enclosing OpenACC 'kernels' construct and" } */
@@ -28,22 +33,65 @@ void f1 ()
     f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .parallel. construct" } */
       = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .parallel. construct" } */
   }
+#pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
+#pragma acc serial /* { dg-note "enclosing OpenACC 'serial' construct and" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" } */
+  }
 
 #pragma acc data default (none)
+#pragma acc kernels default (none) /* { dg-note "enclosing OpenACC 'kernels' construct with 'default\\\(none\\\)' clause" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .kernels. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .kernels. construct" } */
+  }
+#pragma acc data default (none)
 #pragma acc parallel default (none) /* { dg-note "enclosing OpenACC 'parallel' construct with 'default\\\(none\\\)' clause" } */
   {
     f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .parallel. construct" } */
       = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .parallel. construct" } */
   }
+#pragma acc data default (none)
+#pragma acc serial default (none) /* { dg-note "enclosing OpenACC 'serial' construct with 'default\\\(none\\\)' clause" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" } */
+  }
 
 #pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
 #pragma acc data
 #pragma acc data
+#pragma acc kernels /* { dg-note "enclosing OpenACC 'kernels' construct and" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .kernels. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .kernels. construct" } */
+  }
+#pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
+#pragma acc data
+#pragma acc data
 #pragma acc parallel /* { dg-note "enclosing OpenACC 'parallel' construct and" } */
   {
     f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .parallel. construct" } */
       = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .parallel. construct" } */
   }
+#pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
+#pragma acc data
+#pragma acc data
+#pragma acc serial /* { dg-note "enclosing OpenACC 'serial' construct and" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" } */
+  }
+
+#pragma acc data
+#pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
+#pragma acc data
+#pragma acc kernels /* { dg-note "enclosing OpenACC 'kernels' construct and" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .kernels. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .kernels. construct" } */
+  }
 #pragma acc data
 #pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
 #pragma acc data
@@ -53,6 +101,23 @@ void f1 ()
       = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .parallel. construct" } */
   }
 #pragma acc data
+#pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
+#pragma acc data
+#pragma acc serial /* { dg-note "enclosing OpenACC 'serial' construct and" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" } */
+  }
+
+#pragma acc data
+#pragma acc data
+#pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
+#pragma acc kernels /* { dg-note "enclosing OpenACC 'kernels' construct and" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .kernels. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .kernels. construct" } */
+  }
+#pragma acc data
 #pragma acc data
 #pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
 #pragma acc parallel /* { dg-note "enclosing OpenACC 'parallel' construct and" } */
@@ -61,6 +126,23 @@ void f1 ()
       = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .parallel. construct" } */
   }
 #pragma acc data
+#pragma acc data
+#pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
+#pragma acc serial /* { dg-note "enclosing OpenACC 'serial' construct and" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" } */
+  }
+
+#pragma acc data
+#pragma acc data default (none)
+#pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
+#pragma acc kernels /* { dg-note "enclosing OpenACC 'kernels' construct and" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .kernels. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .kernels. construct" } */
+  }
+#pragma acc data
 #pragma acc data default (none)
 #pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
 #pragma acc parallel /* { dg-note "enclosing OpenACC 'parallel' construct and" } */
@@ -68,4 +150,12 @@ void f1 ()
     f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .parallel. construct" } */
       = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .parallel. construct" } */
   }
+#pragma acc data
+#pragma acc data default (none)
+#pragma acc data default (none) /* { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" } */
+#pragma acc serial /* { dg-note "enclosing OpenACC 'serial' construct and" } */
+  {
+    f1_b[0] /* { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" } */
+      = f1_a; /* { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" } */
+  }
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/default-4.c b/gcc/testsuite/c-c++-common/goacc/default-4.c
index e12cb86d097bb40f896eb1ecaa793cd786d9d511..e763a30afc101fb084d9c1332576d57deeab1449 100644
--- a/gcc/testsuite/c-c++-common/goacc/default-4.c
+++ b/gcc/testsuite/c-c++-common/goacc/default-4.c
@@ -20,6 +20,11 @@ void f1 ()
     {
       f1_b[0] = f1_a;
     }
+#pragma acc serial
+    /* { dg-final { scan-tree-dump-times "omp target oacc_serial map\\(tofrom:f1_b \[^\\)\]+\\) map\\(tofrom:f1_a" 1 "gimple" } } */
+    {
+      f1_b[0] = f1_a;
+    }
   }
 }
 
@@ -41,6 +46,11 @@ void f2 ()
     {
       f2_b[0] = f2_a;
     }
+#pragma acc serial default (none)
+    /* { dg-final { scan-tree-dump-times "omp target oacc_serial default\\(none\\) map\\(tofrom:f2_b \[^\\)\]+\\) map\\(tofrom:f2_a" 1 "gimple" } } */
+    {
+      f2_b[0] = f2_a;
+    }
   }
 }
 
@@ -62,6 +72,11 @@ void f2_ ()
     {
       f2__b[0] = f2__a;
     }
+#pragma acc serial
+    /* { dg-final { scan-tree-dump-times "omp target oacc_serial map\\(tofrom:f2__b \[^\\)\]+\\) map\\(tofrom:f2__a" 1 "gimple" } } */
+    {
+      f2__b[0] = f2__a;
+    }
   }
 }
 
@@ -83,6 +98,11 @@ void f3 ()
     {
       f3_b[0] = f3_a;
     }
+#pragma acc serial default (present)
+    /* { dg-final { scan-tree-dump-times "omp target oacc_serial default\\(present\\) map\\(tofrom:f3_b \[^\\)\]+\\) map\\(tofrom:f3_a" 1 "gimple" } } */
+    {
+      f3_b[0] = f3_a;
+    }
   }
 }
 
@@ -104,5 +124,10 @@ void f3_ ()
     {
       f3__b[0] = f3__a;
     }
+#pragma acc serial
+    /* { dg-final { scan-tree-dump-times "omp target oacc_serial map\\(tofrom:f3__b \[^\\)\]+\\) map\\(tofrom:f3__a" 1 "gimple" } } */
+    {
+      f3__b[0] = f3__a;
+    }
   }
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/default-5.c b/gcc/testsuite/c-c++-common/goacc/default-5.c
index 59ac1d79668a5282c47b2db75fc23c7c032db33a..16a10dd8f0633fe75d2dc6a691ba65c57f05569e 100644
--- a/gcc/testsuite/c-c++-common/goacc/default-5.c
+++ b/gcc/testsuite/c-c++-common/goacc/default-5.c
@@ -17,8 +17,13 @@ void f1 ()
   {
     f1_b[0] = f1_a;
   }
+#pragma acc serial default (present)
+  /* { dg-final { scan-tree-dump-times "omp target oacc_serial default\\(present\\) map\\(force_present:f1_b \[^\\)\]+\\) firstprivate\\(f1_a\\)" 1 "gimple" } } */
+  {
+    f1_b[0] = f1_a;
+  }
 
-  /* { dg-final { scan-tree-dump-times "omp target oacc_data default\\(present\\)" 2 "gimple" } } */
+  /* { dg-final { scan-tree-dump-times "omp target oacc_data default\\(present\\)" 3 "gimple" } } */
 #pragma acc data default (present)
 #pragma acc kernels
   /* { dg-final { scan-tree-dump-times "omp target oacc_kernels map\\(force_present:f1_d \[^\\)\]+\\) map\\(force_tofrom:f1_c" 1 "gimple" } } */
@@ -32,4 +37,12 @@ void f1 ()
   {
     f1_d[0] = f1_c;
   }
+#pragma acc data default (none)
+#pragma acc data default (none)
+#pragma acc data default (present)
+#pragma acc serial
+  /* { dg-final { scan-tree-dump-times "omp target oacc_serial map\\(force_present:f1_d \[^\\)\]+\\) firstprivate\\(f1_c\\)" 1 "gimple" } } */
+  {
+    f1_d[0] = f1_c;
+  }
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/if-clause-2.c b/gcc/testsuite/c-c++-common/goacc/if-clause-2.c
index 7147552175816a4e359550a3b30a656b79332f7a..901b268a2955b6bcd385224093425b7de628be5a 100644
--- a/gcc/testsuite/c-c++-common/goacc/if-clause-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/if-clause-2.c
@@ -16,6 +16,9 @@ f (short c)
      { dg-final { scan-tree-dump-times {(?n)#pragma omp target oacc_parallel_kernels_gang_single async\(-1\) num_gangs\(1\) map\(force_present:c \[len: [0-9]+\]\) if\(_[0-9]+\)$} 1 "omp_oacc_kernels_decompose" } } */
   ++c;
 
+#pragma acc serial if(c) copy(c)
+  ++c;
+
 #pragma acc data if(c) copy(c)
   ++c;
 
diff --git a/gcc/testsuite/c-c++-common/goacc/kernels-1.c b/gcc/testsuite/c-c++-common/goacc/kernels-1.c
index 016abbdfe8d8d7a1535804756738c4761a4cd00e..7326bf4198a0dc7169829f55aeb97f23739ad2d2 100644
--- a/gcc/testsuite/c-c++-common/goacc/kernels-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/kernels-1.c
@@ -1,3 +1,5 @@
+// See also 'parallel-1.c', 'serial-1.c'.
+
 /* { dg-additional-options "-fopt-info-optimized-omp" } */
 
 int
diff --git a/gcc/testsuite/c-c++-common/goacc/loop-1.c b/gcc/testsuite/c-c++-common/goacc/loop-1.c
index 4cf5429c9bbf41454c33aaf1ed5896377e0af264..fea47dd593b4e3b1f53d4a1571e2bcc2612acae2 100644
--- a/gcc/testsuite/c-c++-common/goacc/loop-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/loop-1.c
@@ -62,6 +62,10 @@ int test1()
     {
     }
   #pragma acc kernels loop
+  for(i = 1; i < 10; i++)
+    {
+    }
+  #pragma acc serial loop
   for(i = 1; i < 10; i++)
     {
     }
diff --git a/gcc/testsuite/c-c++-common/goacc/loop-2-serial.c b/gcc/testsuite/c-c++-common/goacc/loop-2-serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..bcabdd3bfc1f0784538cec6e7f4a1e9cc62100d6
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/loop-2-serial.c
@@ -0,0 +1,164 @@
+/* See also "../../gfortran.dg/goacc/loop-2-serial.f95".  */
+
+void S(void)
+{
+  int i, j;
+
+#pragma acc serial
+  {
+#pragma acc loop auto
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang(static:5)
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang(static:*)
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang // { dg-message "containing loop" }
+    for (i = 0; i < 10; i++)
+      {
+#pragma acc loop vector
+	for (j = 1; j < 10; j++)
+	  { }
+#pragma acc loop worker 
+	for (j = 1; j < 10; j++)
+	  { }
+#pragma acc loop gang // { dg-error "inner loop uses same" }
+	for (j = 1; j < 10; j++)
+	  { }
+      }
+#pragma acc loop seq gang // { dg-error "'seq' overrides" }
+    for (i = 0; i < 10; i++)
+      { }
+
+#pragma acc loop worker
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop worker // { dg-message "containing loop" 2 }
+    for (i = 0; i < 10; i++)
+      {
+#pragma acc loop vector 
+	for (j = 1; j < 10; j++)
+	  { }
+#pragma acc loop worker // { dg-error "inner loop uses same" }
+	for (j = 1; j < 10; j++)
+	  { }
+#pragma acc loop gang // { dg-error "incorrectly nested" }
+	for (j = 1; j < 10; j++)
+	  { }
+      }
+#pragma acc loop seq worker // { dg-error "'seq' overrides" }
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang worker
+    for (i = 0; i < 10; i++)
+      { }
+
+#pragma acc loop vector
+    for (i = 0; i < 10; i++)
+      { }
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop vector // { dg-message "containing loop" 3 }
+    for (i = 0; i < 10; i++)
+      {
+#pragma acc loop vector // { dg-error "inner loop uses same" }
+	for (j = 1; j < 10; j++)
+	  { }
+#pragma acc loop worker // { dg-error "incorrectly nested" }
+	for (j = 1; j < 10; j++)
+	  { }
+#pragma acc loop gang // { dg-error "incorrectly nested" }
+	for (j = 1; j < 10; j++)
+	  { }
+      }
+#pragma acc loop seq vector // { dg-error "'seq' overrides" }
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang vector
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop worker vector
+    for (i = 0; i < 10; i++)
+      { }
+
+#pragma acc loop auto
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop seq auto // { dg-error "'seq' overrides" }
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang auto // { dg-error "'auto' conflicts" }
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop worker auto // { dg-error "'auto' conflicts" }
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop vector auto // { dg-error "'auto' conflicts" }
+    for (i = 0; i < 10; i++)
+      { }
+
+  }
+
+#pragma acc serial loop auto
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop gang
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop gang(static:5)
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop gang(static:*)
+  for (i = 0; i < 10; i++)
+    { }
+
+#pragma acc serial loop seq gang // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
+    { }
+
+#pragma acc serial loop worker
+  for (i = 0; i < 10; i++)
+    { }
+
+#pragma acc serial loop seq worker // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop gang worker
+  for (i = 0; i < 10; i++)
+    { }
+
+#pragma acc serial loop vector
+  for (i = 0; i < 10; i++)
+    { }
+
+#pragma acc serial loop seq vector // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop gang vector
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop worker vector
+  for (i = 0; i < 10; i++)
+    { }
+
+#pragma acc serial loop auto
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop seq auto // { dg-error "'seq' overrides" }
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop gang auto // { dg-error "'auto' conflicts" }
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop worker auto // { dg-error "'auto' conflicts" }
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop vector auto // { dg-error "'auto' conflicts" }
+  for (i = 0; i < 10; i++)
+    { }
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/loop-3.c b/gcc/testsuite/c-c++-common/goacc/loop-3-parallel.c
similarity index 97%
rename from gcc/testsuite/c-c++-common/goacc/loop-3.c
rename to gcc/testsuite/c-c++-common/goacc/loop-3-parallel.c
index ad5a4bd5aa9acec1185fdd58fdf621b769c31a60..cf618b34342a9f5e5906acde88571919dbee14ec 100644
--- a/gcc/testsuite/c-c++-common/goacc/loop-3.c
+++ b/gcc/testsuite/c-c++-common/goacc/loop-3-parallel.c
@@ -1,6 +1,6 @@
 /* See also "../../gfortran.dg/goacc/loop-2-parallel-3.f95".  */
 
-void par1 (void)
+void f1 (void)
 {
   int i, j;
 
@@ -33,7 +33,7 @@ void par1 (void)
    }
 }
 
-void p2 (void)
+void f2 (void)
 {
   int i, j;
 
diff --git a/gcc/testsuite/c-c++-common/goacc/loop-3-serial.c b/gcc/testsuite/c-c++-common/goacc/loop-3-serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..aea6fe72208dbb32fae44463008581a0780e1e54
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/loop-3-serial.c
@@ -0,0 +1,60 @@
+/* See also "../../gfortran.dg/goacc/loop-2-serial-3.f95".  */
+
+void f1 (void)
+{
+  int i, j;
+
+#pragma acc serial
+  {
+#pragma acc loop gang(5) // { dg-error "argument not permitted" }
+    for (i = 0; i < 10; i++)
+      { }
+
+#pragma acc loop gang(num:5) // { dg-error "argument not permitted" }
+    for (i = 0; i < 10; i++)
+      { }
+
+#pragma acc loop worker(5) // { dg-error "argument not permitted" }
+    for (i = 0; i < 10; i++)
+      { }
+
+#pragma acc loop worker(num:5) // { dg-error "argument not permitted" }
+    for (i = 0; i < 10; i++)
+      { }
+
+#pragma acc loop vector(5) // { dg-error "argument not permitted" }
+    for (i = 0; i < 10; i++)
+      { }
+
+#pragma acc loop vector(length:5) // { dg-error "argument not permitted" }
+    for (i = 0; i < 10; i++)
+      { }
+
+   }
+}
+
+void f2 (void)
+{
+  int i, j;
+
+#pragma acc serial loop gang(5) // { dg-error "argument not permitted" }
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop gang(num:5) // { dg-error "argument not permitted" }
+  for (i = 0; i < 10; i++)
+    { }
+
+#pragma acc serial loop worker(5) // { dg-error "argument not permitted" }
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop worker(num:5) // { dg-error "argument not permitted" }
+  for (i = 0; i < 10; i++)
+    { }
+
+#pragma acc serial loop vector(5) // { dg-error "argument not permitted" }
+  for (i = 0; i < 10; i++)
+    { }
+#pragma acc serial loop vector(length:5) // { dg-error "argument not permitted" }
+  for (i = 0; i < 10; i++)
+    { }
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/loop-clauses.c b/gcc/testsuite/c-c++-common/goacc/loop-clauses.c
index f3c720730ead7725f8ca9183468d36715ad75b6d..bd960bc0388ebee23cc3d960d6d444303c66b0c6 100644
--- a/gcc/testsuite/c-c++-common/goacc/loop-clauses.c
+++ b/gcc/testsuite/c-c++-common/goacc/loop-clauses.c
@@ -44,6 +44,7 @@ main ()
       { }
   }
 
+
 #pragma acc kernels default (none)
   {
 #pragma acc loop auto
@@ -78,5 +79,48 @@ main ()
       { }
   }
 
+
+#pragma acc serial firstprivate (j) private (i)
+  {
+#pragma acc loop seq
+    for (i = 0; i < 10; i++)
+      { }
+  }
+
+#pragma acc serial default (none)
+  {
+#pragma acc loop auto private (j)
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang(static:5)
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang(static:*)
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop vector
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop worker
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop auto
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop independent
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop seq
+    for (i = 0; i < 10; i++)
+      { }
+#pragma acc loop gang worker vector
+    for (i = 0; i < 10; i++)
+      { }
+  }
+
+
   return 0;
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/nested-reductions-1-serial.c b/gcc/testsuite/c-c++-common/goacc/nested-reductions-1-serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..39251d0f4cc2450261e6c4aee1dbb52062204ab4
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/nested-reductions-1-serial.c
@@ -0,0 +1,332 @@
+/* Test cases of nested 'reduction' clauses expected to compile cleanly.  */
+
+/* See also 'gfortran.dg/goacc/nested-reductions-1-serial.f90'. */
+
+/* { dg-additional-options -Wuninitialized } */
+
+void acc_serial (void)
+{
+  int i, j, k, sum, diff;
+
+  #pragma acc serial
+  /* implicit 'copy (sum, diff)'
+     { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+     { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 } */
+  {
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop collapse(2) reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(+:sum)
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop collapse(2) reduction(+:sum)
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(+:sum)
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum) reduction(-:diff)
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(+:sum)
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop reduction(-:diff)
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+  }
+}
+
+/* The same tests as above, but using a combined serial loop construct.  */
+
+void acc_serial_loop (void)
+{
+  int i, j, k, l, sum, diff;
+
+  #pragma acc serial loop
+  /* implicit 'copy (sum, diff)'
+     { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+     { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 } */
+  for (int h = 0; h < 10; ++h)
+  {
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop collapse(2) reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(+:sum)
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop collapse(2) reduction(+:sum)
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(+:sum) // { dg-warning "insufficient partitioning available to parallelize loop" }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum) reduction(-:diff)
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(+:sum) // { dg-warning "insufficient partitioning available to parallelize loop" }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop reduction(-:diff) // { dg-warning "insufficient partitioning available to parallelize loop" }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+  }
+}
+
+/* The same tests as above, but now the outermost reduction clause is on
+   the serial region, not the outermost loop.  */
+
+void acc_serial_reduction (void)
+{
+  int i, j, k, sum, diff;
+
+  #pragma acc serial reduction(+:sum)
+  /* implicit 'copy (sum, diff)'
+     { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+     { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 } */
+  {
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    for (i = 0; i < 10; i++)
+      #pragma acc loop
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        #pragma acc loop
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(+:sum)
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum) reduction(-:diff)
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(+:sum)
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop reduction(-:diff)
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(+:sum)
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop reduction(-:diff)
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(+:sum)
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+  }
+}
+
+/* The same tests as above, but using a combined serial loop construct, and
+   the outermost reduction clause is on that one, not the outermost loop.  */
+void acc_serial_loop_reduction (void)
+{
+  int i, j, k, sum, diff;
+
+  #pragma acc serial loop reduction(+:sum)
+  /* implicit 'copy (sum, diff)'
+     { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+     { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 } */
+  for (int h = 0; h < 10; ++h)
+  {
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    for (i = 0; i < 10; i++)
+      #pragma acc loop
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    for (i = 0; i < 10; i++)
+      for (j = 0; j < 10; j++)
+        #pragma acc loop
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(+:sum) // { dg-warning "insufficient partitioning available to parallelize loop" }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum) reduction(-:diff)
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(+:sum) // { dg-warning "insufficient partitioning available to parallelize loop" }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop reduction(-:diff) // { dg-warning "insufficient partitioning available to parallelize loop" }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(+:sum) // { dg-warning "insufficient partitioning available to parallelize loop" }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop reduction(-:diff) // { dg-warning "insufficient partitioning available to parallelize loop" }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(+:sum) // { dg-warning "insufficient partitioning available to parallelize loop" }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop // { dg-warning "insufficient partitioning available to parallelize loop" }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+  }
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/nested-reductions-2-serial.c b/gcc/testsuite/c-c++-common/goacc/nested-reductions-2-serial.c
new file mode 100644
index 0000000000000000000000000000000000000000..dded69959e8d7628eec006cf05b681d2b0e9de02
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/nested-reductions-2-serial.c
@@ -0,0 +1,403 @@
+/* Test erroneous cases of nested 'reduction' clauses.  */
+
+/* See also 'gfortran.dg/goacc/nested-reductions-2-serial.f90'. */
+
+/* { dg-additional-options -Wuninitialized } */
+
+void acc_serial (void)
+{
+  int i, j, k, l, sum, diff;
+
+  #pragma acc serial
+  /* implicit 'copy (sum, diff)'
+     { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+     { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 } */
+  {
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop collapse(2) // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          #pragma acc loop reduction(+:sum)
+          for (l = 0; l < 10; l++)
+            sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+          #pragma acc loop reduction(+:sum)
+          for (l = 0; l < 10; l++)
+            sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum) // { dg-warning "conflicting reduction operations for .sum." } 
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(-:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+	  #pragma acc loop reduction(*:sum) // { dg-warning "conflicting reduction operations for .sum." }
+	  for (l = 0; l < 10; l++)
+	    sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum) // { dg-warning "conflicting reduction operations for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+	  #pragma acc loop reduction(*:sum) // { dg-warning "conflicting reduction operations for .sum." }
+	  for (l = 0; l < 10; l++)
+	    sum = 1;
+
+    #pragma acc loop reduction(+:sum) reduction(-:diff)
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(-:diff) // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop reduction(+:sum) // { dg-warning "nested loop in reduction needs reduction clause for .diff." }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+  }
+}
+
+/* The same tests as above, but using a combined serial loop construct.  */
+
+void acc_serial_loop (void)
+{
+  int i, j, k, l, sum, diff;
+
+  #pragma acc serial loop
+  /* implicit 'copy (sum, diff)'
+     { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+     { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 } */
+  for (int h = 0; h < 10; ++h)
+  {
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop collapse(2) // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          #pragma acc loop reduction(+:sum)
+          for (l = 0; l < 10; l++)
+            sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+          #pragma acc loop reduction(+:sum)
+          for (l = 0; l < 10; l++)
+            sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum) // { dg-warning "conflicting reduction operations for .sum." }
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(-:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+	  #pragma acc loop reduction(*:sum) // { dg-warning "conflicting reduction operations for .sum." }
+	  for (l = 0; l < 10; l++)
+	    sum = 1;
+
+    #pragma acc loop reduction(+:sum)
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum) // { dg-warning "conflicting reduction operations for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+	  #pragma acc loop reduction(*:sum) // { dg-warning "conflicting reduction operations for .sum." }
+	  for (l = 0; l < 10; l++)
+	    sum = 1;
+
+    #pragma acc loop reduction(+:sum) reduction(-:diff)
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(-:diff) // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop reduction(+:sum) // { dg-warning "nested loop in reduction needs reduction clause for .diff." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+  }
+}
+
+/* The same tests as above, but now the outermost reduction clause is on
+   the serial region, not the outermost loop.  */
+void acc_serial_reduction (void)
+{
+  int i, j, k, l, sum, diff;
+
+  #pragma acc serial reduction(+:sum)
+  /* implicit 'copy (sum, diff)'
+     { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+     { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 } */
+  {
+    #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop collapse(2) // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          #pragma acc loop reduction(+:sum)
+          for (l = 0; l < 10; l++)
+            sum = 1;
+
+    #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+          #pragma acc loop reduction(+:sum)
+          for (l = 0; l < 10; l++)
+            sum = 1;
+
+    #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum) // { dg-warning "conflicting reduction operations for .sum." }
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(-:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(max:sum) // { dg-warning "conflicting reduction operations for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      for (j = 0; j < 10; j++)
+        #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+	  #pragma acc loop reduction(*:sum) // { dg-warning "conflicting reduction operations for .sum." }
+	  for (l = 0; l < 10; l++)
+	    sum = 1;
+
+    #pragma acc loop reduction(max:sum) // { dg-warning "conflicting reduction operations for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      for (j = 0; j < 10; j++)
+      #pragma acc loop reduction(+:sum) // { dg-warning "conflicting reduction operations for .sum." })
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+	for (k = 0; k < 10; k++)
+	  #pragma acc loop reduction(*:sum) // { dg-warning "conflicting reduction operations for .sum." }
+	  for (l = 0; l < 10; l++)
+	    sum = 1;
+
+    #pragma acc loop reduction(-:diff) // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(-:diff) // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop reduction(+:sum) // { dg-warning "nested loop in reduction needs reduction clause for .diff." }
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+  }
+}
+
+/* The same tests as above, but using a combined serial loop construct, and
+   the outermost reduction clause is on that one, not the outermost loop.  */
+void acc_serial_loop_reduction (void)
+{
+  int i, j, k, l, sum, diff;
+
+  #pragma acc serial loop reduction(+:sum)
+  /* implicit 'copy (sum, diff)'
+     { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+     { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 } */
+  for (int h = 0; h < 10; ++h)
+  {
+    #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop collapse(2) // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        for (k = 0; k < 10; k++)
+          #pragma acc loop reduction(+:sum)
+          for (l = 0; l < 10; l++)
+            sum = 1;
+
+    #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+          #pragma acc loop reduction(+:sum)
+          for (l = 0; l < 10; l++)
+            sum = 1;
+
+    #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(+:sum) // { dg-warning "conflicting reduction operations for .sum." }
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop reduction(-:sum)
+        for (k = 0; k < 10; k++)
+          sum = 1;
+
+    #pragma acc loop reduction(max:sum) // { dg-warning "conflicting reduction operations for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+        #pragma acc loop // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+	  #pragma acc loop reduction(*:sum) // { dg-warning "conflicting reduction operations for .sum." }
+	  for (l = 0; l < 10; l++)
+	    sum = 1;
+
+    #pragma acc loop reduction(max:sum) // { dg-warning "conflicting reduction operations for .sum." }
+    for (i = 0; i < 10; i++)
+      #pragma acc loop reduction(-:sum) // { dg-warning "conflicting reduction operations for .sum." }
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+      for (j = 0; j < 10; j++)
+      #pragma acc loop reduction(+:sum) // { dg-warning "conflicting reduction operations for .sum." })
+      // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (k = 0; k < 10; k++)
+	  #pragma acc loop reduction(*:sum) // { dg-warning "conflicting reduction operations for .sum." }
+	  for (l = 0; l < 10; l++)
+	    sum = 1;
+
+    #pragma acc loop reduction(-:diff) // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    for (i = 0; i < 10; i++)
+      {
+        #pragma acc loop reduction(-:diff) // { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(+:sum)
+          for (k = 0; k < 10; k++)
+            sum = 1;
+
+        #pragma acc loop reduction(+:sum) // { dg-warning "nested loop in reduction needs reduction clause for .diff." }
+        // { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 } 
+        for (j = 0; j < 10; j++)
+          #pragma acc loop reduction(-:diff)
+          for (k = 0; k < 10; k++)
+            diff = 1;
+      }
+  }
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/nesting-1.c b/gcc/testsuite/c-c++-common/goacc/nesting-1.c
index 8c3d1adc785d1e1ff3ae53263ec7977bd3ef5572..e0db7aff736737e2e21a0ee442c318ec669dd3d5 100644
--- a/gcc/testsuite/c-c++-common/goacc/nesting-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/nesting-1.c
@@ -47,6 +47,22 @@ f_acc_kernels (void)
 }
 
 
+void
+f_acc_serial (void)
+{
+#pragma acc serial
+  {
+#pragma acc loop /* { dg-line l_loop_i[incr c_loop_i] } */
+    /* { dg-note {variable 'i\.[0-9]+' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop_i$c_loop_i } */
+    /* { dg-note {variable 'i' in 'private' clause is candidate for adjusting OpenACC privatization level} {} { target *-*-* } l_loop_i$c_loop_i }
+       { dg-note {variable 'i' ought to be adjusted for OpenACC privatization level: 'vector'} {} { target *-*-* } l_loop_i$c_loop_i } */
+    /* { dg-optimized {assigned OpenACC gang vector loop parallelism} {} { target *-*-* } l_loop_i$c_loop_i } */
+    for (i = 0; i < 2; ++i)
+      ;
+  }
+}
+
+
 void
 f_acc_data (void)
 {
@@ -82,6 +98,20 @@ f_acc_data (void)
 	;
     }
 
+#pragma acc serial
+    ;
+
+#pragma acc serial
+    {
+#pragma acc loop /* { dg-line l_loop_i[incr c_loop_i] } */
+      /* { dg-note {variable 'i\.[0-9]+' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop_i$c_loop_i } */
+      /* { dg-note {variable 'i' in 'private' clause is candidate for adjusting OpenACC privatization level} {} { target *-*-* } l_loop_i$c_loop_i }
+	 { dg-note {variable 'i' ought to be adjusted for OpenACC privatization level: 'vector'} {} { target *-*-* } l_loop_i$c_loop_i } */
+      /* { dg-optimized {assigned OpenACC gang vector loop parallelism} {} { target *-*-* } l_loop_i$c_loop_i } */
+      for (i = 0; i < 2; ++i)
+	;
+    }
+
 #pragma acc data
     ;
 
@@ -123,6 +153,20 @@ f_acc_data (void)
 	  ;
       }
 
+#pragma acc serial
+      ;
+
+#pragma acc serial
+      {
+#pragma acc loop /* { dg-line l_loop_i[incr c_loop_i] } */
+	/* { dg-note {variable 'i\.[0-9]+' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop_i$c_loop_i } */
+	/* { dg-note {variable 'i' in 'private' clause is candidate for adjusting OpenACC privatization level} {} { target *-*-* } l_loop_i$c_loop_i }
+	   { dg-note {variable 'i' ought to be adjusted for OpenACC privatization level: 'vector'} {} { target *-*-* } l_loop_i$c_loop_i } */
+	/* { dg-optimized {assigned OpenACC gang vector loop parallelism} {} { target *-*-* } l_loop_i$c_loop_i } */
+	for (i = 0; i < 2; ++i)
+	  ;
+      }
+
 #pragma acc data
       ;
 
diff --git a/gcc/testsuite/c-c++-common/goacc/nesting-data-1.c b/gcc/testsuite/c-c++-common/goacc/nesting-data-1.c
index fefe6cd16f75d3826e6b943bfa028b04a22182ba..d5de43803e5749b077de58a33ed19a77db6a4a5d 100644
--- a/gcc/testsuite/c-c++-common/goacc/nesting-data-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/nesting-data-1.c
@@ -30,6 +30,13 @@ f (void)
       caa[3][12] = ca[3] + caa[3][12];
     }
 
+#pragma acc serial copyout(ca[3:4])
+    {
+      c = 9;
+      ca[11] = c;
+      caa[3][12] = ca[3] + caa[3][12];
+    }
+
 #pragma acc data pcopy(ca[5:7])
     {
       c = 15;
@@ -56,6 +63,13 @@ f (void)
 	ca[10] = c;
 	caa[3][12] = ca[3] + caa[3][12];
       }
+
+#pragma acc serial pcopyout(caa[3:7][0:30])
+      {
+	c = 19;
+	ca[12] = c;
+	caa[3][12] = ca[3] + caa[3][12];
+      }
     }
   }
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c b/gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c
index 5cfb327f4b60951e785dd35f39409137cbcd0b09..52fdb71c8a2a35d53d3ea96499046b705e768d7c 100644
--- a/gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/nesting-fail-1.c
@@ -1,7 +1,8 @@
 extern int i;
 
-/* While the OpenACC specification does allow for certain kinds of
-   nesting, we don't support many of these yet.  */
+/* The OpenACC specification allows nested compute constructs, but we don't
+   support that yet.  */
+
 void
 f_acc_parallel (void)
 {
@@ -11,6 +12,8 @@ f_acc_parallel (void)
     ;
 #pragma acc kernels /* { dg-bogus ".kernels. construct inside of .parallel. region" "not implemented" { xfail *-*-* } } */
     ;
+#pragma acc serial /* { dg-bogus ".serial. construct inside of .parallel. region" "not implemented" { xfail *-*-* } } */
+    ;
 #pragma acc data /* { dg-error ".data. construct inside of .parallel. region" } */
     ;
 #pragma acc update host(i) /* { dg-error ".update. construct inside of .parallel. region" } */
@@ -19,8 +22,6 @@ f_acc_parallel (void)
   }
 }
 
-/* While the OpenACC specification does allow for certain kinds of
-   nesting, we don't support many of these yet.  */
 void
 f_acc_kernels (void)
 {
@@ -30,6 +31,8 @@ f_acc_kernels (void)
     ;
 #pragma acc kernels /* { dg-bogus ".kernels. construct inside of .kernels. region" "not implemented" { xfail *-*-* } } */
     ;
+#pragma acc serial /* { dg-bogus ".serial. construct inside of .kernels. region" "not implemented" { xfail *-*-* } } */
+    ;
 #pragma acc data /* { dg-error ".data. construct inside of .kernels. region" } */
     ;
 #pragma acc update host(i) /* { dg-error ".update. construct inside of .kernels. region" } */
@@ -38,6 +41,25 @@ f_acc_kernels (void)
   }
 }
 
+void
+f_acc_serial (void)
+{
+#pragma acc serial
+  {
+#pragma acc parallel /* { dg-bogus ".parallel. construct inside of .serial. region" "not implemented" { xfail *-*-* } } */
+    ;
+#pragma acc kernels /* { dg-bogus ".kernels. construct inside of .serial. region" "not implemented" { xfail *-*-* } } */
+    ;
+#pragma acc serial /* { dg-bogus ".serial. construct inside of .serial. region" "not implemented" { xfail *-*-* } } */
+    ;
+#pragma acc data /* { dg-error ".data. construct inside of .serial. region" } */
+    ;
+#pragma acc update host(i) /* { dg-error ".update. construct inside of .serial. region" } */
+#pragma acc enter data copyin(i) /* { dg-error ".enter data. construct inside of .serial. region" } */
+#pragma acc exit data delete(i) /* { dg-error ".exit data. construct inside of .serial. region" } */
+  }
+}
+
 void
 f_acc_data (void)
 {
diff --git a/gcc/testsuite/c-c++-common/goacc/parallel-1.c b/gcc/testsuite/c-c++-common/goacc/parallel-1.c
index 0afc53adaa8e06d01fbb7d0af86d4fde8bd993bd..230557a408c23b12f9079a3abeb41477ebf17736 100644
--- a/gcc/testsuite/c-c++-common/goacc/parallel-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/parallel-1.c
@@ -1,3 +1,5 @@
+// See also 'kernels-1.c', 'serial-1.c'.
+
 int
 parallel_empty (void)
 {
diff --git a/gcc/testsuite/c-c++-common/goacc/private-reduction-1.c b/gcc/testsuite/c-c++-common/goacc/private-reduction-1.c
index 38f6b7acf2bc8837a4c8f0d0079eb240e9771543..401bbaab86dda77f5421c0aeeccbd991ac9d522b 100644
--- a/gcc/testsuite/c-c++-common/goacc/private-reduction-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/private-reduction-1.c
@@ -14,5 +14,12 @@ reduction ()
   for (i = 0; i < 100; i++)
     r += 10;
 
+  #pragma acc serial
+  #pragma acc loop private (r) reduction (+:r)
+  /* { dg-note {variable 'r' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} r { target *-*-* } .-1 } */
+  /* { dg-note {variable 'i' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} i { target *-*-* } .-2 } */
+  for (i = 0; i < 100; i++)
+    r += 10;
+
   return r;
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/reduction-promotions.c b/gcc/testsuite/c-c++-common/goacc/reduction-promotions.c
index 4cc09da99802660b0cd2a2ade89fcbec37b17d7e..e469e9bf225d65db0d2b2dafccc97f2dee25a6ab 100644
--- a/gcc/testsuite/c-c++-common/goacc/reduction-promotions.c
+++ b/gcc/testsuite/c-c++-common/goacc/reduction-promotions.c
@@ -28,5 +28,28 @@ main(void)
 #pragma acc parallel reduction(+:v1,v2) pcreate(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */
   ;
 
+
+#pragma acc serial reduction(+:v1,v2)
+  ;
+#pragma acc serial reduction(+:v1,v2) copy(v1,v2)
+  ;
+#pragma acc serial reduction(+:v1,v2) pcopy(v1,v2)
+  ;
+#pragma acc serial reduction(+:v1,v2) present(v1,v2)
+  ;
+#pragma acc serial reduction(+:v1,v2) copyin(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */
+  ;
+#pragma acc serial reduction(+:v1,v2) pcopyin(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */
+  ;
+#pragma acc serial reduction(+:v1,v2) copyout(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */
+  ;
+#pragma acc serial reduction(+:v1,v2) pcopyout(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */
+  ;
+#pragma acc serial reduction(+:v1,v2) create(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */
+  ;
+#pragma acc serial reduction(+:v1,v2) pcreate(v1,v2) /* { dg-warning "incompatible data clause with reduction" } */
+  ;
+
+
   return 0;
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/routine-1.c b/gcc/testsuite/c-c++-common/goacc/routine-1.c
index 051f7937deee9a307ba7970fda3283fb5a74a481..d8b1943b1ffbfa7c1e0d7c352fbbb273f7ea971f 100644
--- a/gcc/testsuite/c-c++-common/goacc/routine-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/routine-1.c
@@ -1,3 +1,5 @@
+/* Ensure that routines with a certain level of parallelism can be called.  */
+
 /* { dg-additional-options "-Wopenacc-parallelism" } for testing/documenting
    aspects of that functionality.  */
 
@@ -45,5 +47,16 @@ int main ()
     seq ();
   }
 
+#pragma acc serial
+  /* { dg-warning "region contains gang partitioned code but is not gang partitioned" "" { target *-*-* } .-1 }
+     { dg-warning "region contains worker partitioned code but is not worker partitioned" "" { target *-*-* } .-2 }
+     { dg-warning "region contains vector partitioned code but is not vector partitioned" "" { target *-*-* } .-3 } */
+  {
+    gang ();
+    worker ();
+    vector ();
+    seq ();
+  }
+
   return 0;
 }
diff --git a/gcc/testsuite/c-c++-common/goacc/sb-1.c b/gcc/testsuite/c-c++-common/goacc/sb-1.c
index 1ce41df0c0969a33a4d4a69b5483ef58d132f6c2..cacccac5ec97a2aa01e172fe9e3e64ff3bcb2d14 100644
--- a/gcc/testsuite/c-c++-common/goacc/sb-1.c
+++ b/gcc/testsuite/c-c++-common/goacc/sb-1.c
@@ -9,6 +9,8 @@ void foo()
     goto bad1; // { dg-error "invalid branch to/from OpenACC structured block" }
   #pragma acc kernels
     goto bad1; // { dg-error "invalid branch to/from OpenACC structured block" }
+  #pragma acc serial
+    goto bad1; // { dg-error "invalid branch to/from OpenACC structured block" }
   #pragma acc data
     goto bad1; // { dg-error "invalid branch to/from OpenACC structured block" }
   #pragma acc loop /* { dg-error "loop directive must be associated with an OpenACC compute region" } */
@@ -27,6 +29,12 @@ void foo()
       bad2_kernels: ;
     }
 
+  goto bad2_serial; // { dg-error "invalid entry to OpenACC structured block" }
+  #pragma acc serial
+    {
+      bad2_serial: ;
+    }
+
   goto bad2_data; // { dg-error "invalid entry to OpenACC structured block" }
   #pragma acc data
     {
@@ -56,6 +64,14 @@ void foo()
 	{ ok1_kernels: break; }
     }
 
+  #pragma acc serial
+    {
+      int i;
+      goto ok1_serial;
+      for (i = 0; i < 10; ++i)
+	{ ok1_serial: break; }
+    }
+
   #pragma acc data
     {
       int i;
diff --git a/gcc/testsuite/c-c++-common/goacc/sb-2.c b/gcc/testsuite/c-c++-common/goacc/sb-2.c
index e986af3bb276961f71e203d6c19c1434812874e0..f9c7b352c1a9aaee63b77d08aaf56cb4e22b4a92 100644
--- a/gcc/testsuite/c-c++-common/goacc/sb-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/sb-2.c
@@ -14,6 +14,12 @@ void foo(int i)
     { case 0:; }
   }
 
+  switch (i) // { dg-error "invalid entry to OpenACC structured block" }
+  {
+  #pragma acc serial // { dg-warning "statement will never be executed" }
+    { case 0:; }
+  }
+
   switch (i) // { dg-error "invalid entry to OpenACC structured block" }
   {
   #pragma acc data // { dg-warning "statement will never be executed" }
diff --git a/gcc/testsuite/c-c++-common/goacc/serial-1.c b/gcc/testsuite/c-c++-common/goacc/serial-1.c
new file mode 100644
index 0000000000000000000000000000000000000000..9a0e57b71a87707acf3f1742f803a5c6a6a7ca3a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/goacc/serial-1.c
@@ -0,0 +1,42 @@
+// See also 'kernels-1.c', 'parallel-1.c'.
+
+int
+serial_empty (void)
+{
+#pragma acc serial
+  ;
+
+  return 0;
+}
+
+int
+serial_eternal (void)
+{
+#pragma acc serial
+  {
+    while (1)
+      ;
+  }
+
+  return 0;
+}
+
+int
+serial_noreturn (void)
+{
+#pragma acc serial
+  __builtin_abort ();
+
+  return 0;
+}
+
+int
+serial_clauses (void)
+{
+  int a, b[100];
+
+#pragma acc serial firstprivate (a, b)
+  ;
+
+  return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/uninit-firstprivate-clause.c b/gcc/testsuite/c-c++-common/goacc/uninit-firstprivate-clause.c
index bfe1a11aa2b43f26dc5682caec8ebee9e645c595..252bbdc0af3f87595b509332a7881015899b71bc 100644
--- a/gcc/testsuite/c-c++-common/goacc/uninit-firstprivate-clause.c
+++ b/gcc/testsuite/c-c++-common/goacc/uninit-firstprivate-clause.c
@@ -2,7 +2,7 @@
 /* { dg-additional-options "-Wuninitialized" } */
 
 void
-foo (void)
+foo_parallel (void)
 {
   int i;
 
@@ -12,9 +12,20 @@ foo (void)
   }
 }
 
+void
+foo_serial (void)
+{
+  int i;
+
+#pragma acc serial
+  {
+    i = 1;
+  }
+}
+
 
 void
-foo2 (void)
+foo2_parallel (void)
 {
   int i;
   /* { dg-note {'i' was declared here} {} { target *-*-* } .-1 } */
@@ -24,3 +35,15 @@ foo2 (void)
     i = 1;
   }
 }
+
+void
+foo2_serial (void)
+{
+  int i;
+  /* { dg-note {'i' was declared here} {} { target *-*-* } .-1 } */
+
+#pragma acc serial firstprivate (i) /* { dg-warning "is used uninitialized" } */
+  {
+    i = 1;
+  }
+}
diff --git a/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c b/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c
index de410e5e6ecb521f1f9f319f2c19247c9f868727..d4738b964425471157ac255b7b34b011f8d5bc93 100644
--- a/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c
+++ b/gcc/testsuite/c-c++-common/goacc/uninit-if-clause.c
@@ -6,16 +6,18 @@
 int
 main (void)
 {
-  int l, l2, l3, l4;
+  int l, l2, ls, l3, l4;
   /* { dg-note {'l' was declared here} {} { target *-*-* } .-1 } */
   /* { dg-note {'l2' was declared here} {} { target *-*-* } .-2 } */
-  /* { dg-note {'l3' was declared here} {} { target *-*-* } .-3 } */
-  /* { dg-note {'l4' was declared here} {} { target *-*-* } .-4 } */
-  bool b, b2, b3, b4;
+  /* { dg-note {'ls' was declared here} {} { target *-*-* } .-3 } */
+  /* { dg-note {'l3' was declared here} {} { target *-*-* } .-4 } */
+  /* { dg-note {'l4' was declared here} {} { target *-*-* } .-5 } */
+  bool b, b2, bs, b3, b4;
   /* { dg-note {'b' was declared here} {} { target *-*-* } .-1 } */
   /* { dg-note {'b2' was declared here} {} { target *-*-* } .-2 } */
-  /* { dg-note {'b3' was declared here} {} { target *-*-* } .-3 } */
-  /* { dg-note {'b4' was declared here} {} { target *-*-* } .-4 } */
+  /* { dg-note {'bs' was declared here} {} { target *-*-* } .-3 } */
+  /* { dg-note {'b3' was declared here} {} { target *-*-* } .-4 } */
+  /* { dg-note {'b4' was declared here} {} { target *-*-* } .-5 } */
   int i, i2;
 
   #pragma acc parallel if(l) /* { dg-warning "is used uninitialized" } */
@@ -30,6 +32,12 @@ main (void)
   #pragma acc kernels if(b2) /* { dg-warning "is used uninitialized" } */
   ;
 
+  #pragma acc serial if(ls) /* { dg-warning "is used uninitialized" } */
+  ;
+
+  #pragma acc serial if(bs) /* { dg-warning "is used uninitialized" } */
+  ;
+
   #pragma acc data if(l3) /* { dg-warning "is used uninitialized" } */
   ;
 
diff --git a/gcc/testsuite/c-c++-common/goacc/update-if_present-2.c b/gcc/testsuite/c-c++-common/goacc/update-if_present-2.c
index 974f1b8c42753518dcf9b33570e2b6a6a87eb7fb..0fd1505ace8f05e5488d755a085eb2a34f2f9f90 100644
--- a/gcc/testsuite/c-c++-common/goacc/update-if_present-2.c
+++ b/gcc/testsuite/c-c++-common/goacc/update-if_present-2.c
@@ -38,5 +38,9 @@ t2 ()
 #pragma acc parallel loop if_present /* { dg-error "'if_present' is not valid" } */
     for (b = 1; b < 10; b++)
     ;
+
+#pragma acc serial loop if_present /* { dg-error "'if_present' is not valid" } */
+    for (b = 1; b < 10; b++)
+    ;
 }
 
diff --git a/gcc/testsuite/g++.dg/goacc/template.C b/gcc/testsuite/g++.dg/goacc/template.C
index 10d3f446da7f604aafadfb39db4b908ab98c1745..995b9baa77b8ac0748ad312f10b027649db97f01 100644
--- a/gcc/testsuite/g++.dg/goacc/template.C
+++ b/gcc/testsuite/g++.dg/goacc/template.C
@@ -147,13 +147,101 @@ oacc_kernels_copy (T a)
   return b;
 }
 
+template<typename T, int I> T
+oacc_serial_copy (T a)
+{
+  T b = 0;
+  char w = 1;
+  int x = 2;
+  float y = 3;
+  double z = 4;
+
+#pragma acc serial default (none) copyout (b) copyin (a)
+#pragma acc loop gang worker vector
+  for (int i = 0; i < 1; i++)
+    b = a;
+
+#pragma acc serial copy (w, x, y, z)
+#pragma acc loop
+  for (int i = 0; i < 1; i++)
+    {
+      w = accDouble<char>(w);
+      x = accDouble<int>(x);
+      y = accDouble<float>(y);
+      z = accDouble<double>(z);
+    }
+
+#pragma acc serial if (1)
+  {
+#pragma acc loop independent collapse (2)
+    for (int i = 0; i < a; i++)
+      for (int j = 0; j < 5; j++)
+	b = a;
+
+#pragma acc loop auto tile (I, 3)
+    for (int i = 0; i < a; i++)
+      for (int j = 0; j < 5; j++)
+	b = a;
+
+#pragma acc loop seq
+    for (int i = 0; i < a; i++)
+      b = a;
+  }
+
+  T c;
+
+#pragma acc serial
+#pragma acc loop worker
+  for (int i = 0; i < 1; i++)
+    {
+#pragma acc atomic capture
+      c = b++;
+
+#pragma atomic update
+      c++;
+
+#pragma acc atomic read
+      b = a;
+
+#pragma acc atomic write
+      b = a;
+    }
+
+#pragma acc serial reduction (+:c)
+  c = 1;
+
+#pragma acc data if (1) copy (b)
+  {
+#pragma acc serial
+    {
+      b = a;
+    }
+  }
+
+#pragma acc enter data copyin (b)
+#pragma acc serial present (b)
+  {
+    b = a;
+  }
+
+#pragma acc update host (b)
+#pragma acc update self (b)
+#pragma acc update device (b)
+#pragma acc exit data delete (b)
+#pragma acc exit data finalize copyout (b)
+#pragma acc exit data delete (b) finalize
+
+  return b;
+}
+
 int
 main ()
 {
   int b = oacc_parallel_copy<int, 4> (5);
   int c = oacc_kernels_copy<int> (5);
+  int d = oacc_serial_copy<int, 6> (5);
 
-  return b + c;
+  return b + c + d;
 }
 
 /* { dg-final { scan-tree-dump-times {(?n)^OpenACC routine '[^']+' has 'nohost' clause\.$} 4 oaccloops } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/array-reduction.f90 b/gcc/testsuite/gfortran.dg/goacc/array-reduction.f90
index d71c400a5bf1d92de992f04b3844aa0f8daf4d97..5c489ffb2a04eb76b3b04b792e8a15f3c4ea44c8 100644
--- a/gcc/testsuite/gfortran.dg/goacc/array-reduction.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/array-reduction.f90
@@ -26,6 +26,20 @@ program test
   end do
   !$acc end kernels
 
+  !$acc serial reduction (+:a) ! { dg-error "Array 'a' is not permitted in reduction" }
+  do i = 1, 10
+     a = a + 1
+  end do
+  !$acc end serial
+
+  !$acc serial
+  !$acc loop reduction (+:a) ! { dg-error "Array 'a' is not permitted in reduction" }
+  do i = 1, 10
+     a = a + 1
+  end do
+  !$acc end serial
+
+
   ! Subarray reductions.
   
   !$acc parallel reduction (+:a(1:5)) ! { dg-error "Array 'a' is not permitted in reduction" }
@@ -48,6 +62,20 @@ program test
   end do
   !$acc end kernels
 
+  !$acc serial reduction (+:a(1:5)) ! { dg-error "Array 'a' is not permitted in reduction" }
+  do i = 1, 10
+     a = a + 1
+  end do
+  !$acc end serial
+
+  !$acc serial
+  !$acc loop reduction (+:a(1:5)) ! { dg-error "Array 'a' is not permitted in reduction" }
+  do i = 1, 10
+     a = a + 1
+  end do
+  !$acc end serial
+
+
   ! Reductions on array elements.
   
   !$acc parallel reduction (+:a(1)) ! { dg-error "Array 'a' is not permitted in reduction" }
@@ -70,5 +98,19 @@ program test
   end do
   !$acc end kernels
   
+  !$acc serial reduction (+:a(1)) ! { dg-error "Array 'a' is not permitted in reduction" }
+  do i = 1, 10
+     a(1) = a(1) + 1
+  end do
+  !$acc end serial
+
+  !$acc serial
+  !$acc loop reduction (+:a(1)) ! { dg-error "Array 'a' is not permitted in reduction" }
+  do i = 1, 10
+     a(1) = a(1) + 1
+  end do
+  !$acc end serial
+
+
   print *, a
 end program test
diff --git a/gcc/testsuite/gfortran.dg/goacc/assumed.f95 b/gcc/testsuite/gfortran.dg/goacc/assumed.f95
index 4e35c1d596008168ac5c74af1acdd243997881db..68de202d50705a2b4daaf313802b150951ad2fdf 100644
--- a/gcc/testsuite/gfortran.dg/goacc/assumed.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/assumed.f95
@@ -13,6 +13,8 @@ contains
     !$acc end data
     !$acc parallel private (a) ! { dg-error "Assumed size" }
     !$acc end parallel
+    !$acc serial private (a) ! { dg-error "Assumed size" }
+    !$acc end serial
     !$acc host_data use_device (a) ! { dg-error "Assumed size" }
     !$acc end host_data
     !$acc parallel loop reduction(+:a) ! { dg-error "Assumed size" }
@@ -20,6 +22,11 @@ contains
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:a) ! { dg-error "Assumed size" }
+    ! { dg-error "Array 'a' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc update device (a) ! { dg-error "Assumed size" }
     !$acc update host (a) ! { dg-error "Assumed size" }
     !$acc update self (a) ! { dg-error "Assumed size" }
@@ -35,6 +42,8 @@ contains
     !$acc end data
     !$acc parallel private (a) ! { dg-error "Assumed rank" }
     !$acc end parallel
+    !$acc serial private (a) ! { dg-error "Assumed rank" }
+    !$acc end serial
     !$acc host_data use_device (a) ! { dg-error "Assumed rank" }
     !$acc end host_data
     !$acc parallel loop reduction(+:a) ! { dg-error "Assumed rank" }
@@ -42,6 +51,11 @@ contains
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:a) ! { dg-error "Assumed rank" }
+    ! { dg-error "Array 'a' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc update device (a) ! { dg-error "Assumed rank" }
     !$acc update host (a) ! { dg-error "Assumed rank" }
     !$acc update self (a) ! { dg-error "Assumed rank" }
diff --git a/gcc/testsuite/gfortran.dg/goacc/branch.f95 b/gcc/testsuite/gfortran.dg/goacc/branch.f95
index 7eed3e209db11a6dbcd67fc899f9c8bad0533774..b32235e1483ebb9ad8f3afac189cc64005ce6a24 100644
--- a/gcc/testsuite/gfortran.dg/goacc/branch.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/branch.f95
@@ -17,6 +17,12 @@ program test
   !$acc end kernels 
   end if
 
+  if (.true.) then
+    !$acc serial 
+  end if ! { dg-error "Unexpected" }
+  !$acc end serial 
+  end if
+
   !$acc parallel
   if (.true.) then
     !$acc end parallel ! { dg-error "Unexpected" }
@@ -29,6 +35,12 @@ program test
   end if 
   !$acc end kernels
 
+  !$acc serial
+  if (.true.) then
+    !$acc end serial ! { dg-error "Unexpected" }
+  end if 
+  !$acc end serial
+
   !$acc parallel
   if (.true.) then
   end if
@@ -39,6 +51,11 @@ program test
   end if
   !$acc end kernels
 
+  !$acc serial
+  if (.true.) then
+  end if
+  !$acc end serial
+
   if (.true.) then
     !$acc parallel
     !$acc end parallel
@@ -49,5 +66,9 @@ program test
     !$acc end kernels
   end if
 
+  if (.true.) then
+    !$acc serial
+    !$acc end serial
+  end if
 
 end program test 
\ No newline at end of file
diff --git a/gcc/testsuite/gfortran.dg/goacc/coarray.f95 b/gcc/testsuite/gfortran.dg/goacc/coarray.f95
index f30917b8a9c42e6b63411d95210713e2347931cb..91a84394dc013b565c171830654e9c48a2fe8160 100644
--- a/gcc/testsuite/gfortran.dg/goacc/coarray.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/coarray.f95
@@ -16,17 +16,28 @@ contains
     !$acc end data
     !$acc parallel private (a)
     !$acc end parallel
+    !$acc serial private (a)
+    !$acc end serial
     !$acc host_data use_device (a)
     !$acc end host_data
     !$acc parallel loop reduction(+:a) ! { dg-error "Array 'a' is not permitted in reduction" }
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:a) ! { dg-error "Array 'a' is not permitted in reduction" }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc parallel loop
     do i = 1,5
       !$acc cache (a) ! { dg-error "" "TODO" { xfail *-*-* } }
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+      !$acc cache (a) ! { dg-error "" "TODO" { xfail *-*-* } }
+    enddo
+    !$acc end serial loop
     !$acc update device (a)
     !$acc update host (a)
     !$acc update self (a)
diff --git a/gcc/testsuite/gfortran.dg/goacc/coarray_2.f90 b/gcc/testsuite/gfortran.dg/goacc/coarray_2.f90
index 05167a18af1eb26cf0f8ae082daa2da1215e3442..8794aa4b65a39861411de2bd08aff2bfbfc09417 100644
--- a/gcc/testsuite/gfortran.dg/goacc/coarray_2.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/coarray_2.f90
@@ -16,16 +16,26 @@ contains
     !$acc end data
     !$acc parallel private (a)
     !$acc end parallel
+    !$acc serial private (a)
+    !$acc end serial
     !$acc host_data use_device (a)
     !$acc end host_data
     !$acc parallel loop reduction(+:a) ! { dg-error "Array 'a' is not permitted in reduction" }
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:a) ! { dg-error "Array 'a' is not permitted in reduction" }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc parallel loop
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc update device (a)
     !$acc update host (a)
     !$acc update self (a)
@@ -40,6 +50,8 @@ contains
     !$acc end data
     !$acc parallel private (a)
     !$acc end parallel
+    !$acc serial private (a)
+    !$acc end serial
 ! FIXME:
 !       !$acc parallel loop reduction(+:a)
 !       This involves an assignment, which shall not reallocate
@@ -48,10 +60,22 @@ contains
     do i = 1,5
     enddo
     !$acc end parallel loop
+! FIXME:
+!       !$acc serial loop reduction(+:a)
+!       This involves an assignment, which shall not reallocate
+!       the LHS variable. Version without reduction:
+    !$acc serial loop
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc parallel loop
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc update device (a)
     !$acc update host (a)
     !$acc update self (a)
@@ -68,16 +92,26 @@ contains
     !$acc end data
     !$acc parallel private (a)
     !$acc end parallel
+    !$acc serial private (a)
+    !$acc end serial
     !$acc host_data use_device (a)
     !$acc end host_data
     !$acc parallel loop reduction(+:a) ! { dg-error "Array 'a' is not permitted in reduction" }
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:a) ! { dg-error "Array 'a' is not permitted in reduction" }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc parallel loop
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc update device (a)
     !$acc update host (a)
     !$acc update self (a)
@@ -92,14 +126,24 @@ contains
     !$acc end data
     !$acc parallel private (a)
     !$acc end parallel
+    !$acc serial private (a)
+    !$acc end serial
     !$acc parallel loop reduction(+:a) ! { dg-error "Array 'a' is not permitted in reduction" }
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:a) ! { dg-error "Array 'a' is not permitted in reduction" }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc parallel loop
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc update device (a)
     !$acc update host (a)
     !$acc update self (a)
diff --git a/gcc/testsuite/gfortran.dg/goacc/combined-directives-3.f90 b/gcc/testsuite/gfortran.dg/goacc/combined-directives-3.f90
index b138822827f6c9b55108b543656732fd14154eb7..1af87c48b5fcae6777986dba48f5166a06110fd0 100644
--- a/gcc/testsuite/gfortran.dg/goacc/combined-directives-3.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/combined-directives-3.f90
@@ -23,4 +23,25 @@ subroutine test
      end do
   end do
   !$acc end parallel loop
+
+
+  !$acc serial loop seq auto ! { dg-error "'seq' overrides other OpenACC loop specifiers" }
+  do x = 0, 10
+     !$acc loop
+     do y = 0, 10
+     end do
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop gang auto ! { dg-error "'auto' conflicts with other OpenACC loop specifiers" }
+  do x = 0, 10
+     !$acc loop worker auto ! { dg-error "'auto' conflicts with other OpenACC loop specifiers" }
+     do y = 0, 10
+        !$acc loop vector
+        do z = 0, 10
+        end do
+     end do
+  end do
+  !$acc end serial loop
+
 end subroutine test
diff --git a/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90 b/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90
index 956349204f4d2353648adbe71a407400b92e6e5f..027547a13e60a8da39562c05da03148ffb435fd8 100644
--- a/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/combined-directives.f90
@@ -6,6 +6,7 @@ subroutine test
   implicit none
   integer a(100), i, j, y, z
 
+
   ! PARALLEL
   
   !$acc parallel loop collapse (2)
@@ -71,6 +72,7 @@ subroutine test
   end do
   !$acc end parallel loop
 
+
   ! KERNELS
 
   !$acc kernels loop collapse (2)
@@ -135,16 +137,84 @@ subroutine test
   do i = 1, 100
   end do
   !$acc end kernels loop
+
+
+  ! SERIAL
+  
+  !$acc serial loop collapse (2)
+  do i = 1, 100
+     do j = 1, 10
+     end do
+  end do
+  !$acc end serial loop
+  
+  !$acc serial loop gang
+  do i = 1, 100
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop worker
+  do i = 1, 100
+     do j = 1, 10
+     end do
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop vector
+  do i = 1, 100
+     do j = 1, 10
+     end do
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop seq
+  do i = 1, 100
+     do j = 1, 10
+     end do
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop auto
+  do i = 1, 100
+     do j = 1, 10
+     end do
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop tile (2, 3)
+  do i = 1, 100
+     do j = 1, 10
+     end do
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop independent
+  do i = 1, 100
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop private (z)
+  do i = 1, 100
+     z = 0
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop reduction (+:y) copy (y)
+  do i = 1, 100
+  end do
+  !$acc end serial loop
+
 end subroutine test
 
-! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. collapse.2." 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.i. gang" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. worker" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. vector" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. seq" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. auto" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. tile.2, 3" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.i. independent" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "private.z" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "omp target oacc_\[^ \]+ map.tofrom:y" 2 "gimple" } }
-! { dg-final { scan-tree-dump-times "acc loop private.i. reduction..:y." 2 "gimple" } }
+
+! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. collapse.2." 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop private.i. gang" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. worker" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. vector" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. seq" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. auto" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop private.i. private.j. tile.2, 3" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop private.i. independent" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "private.z" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "omp target oacc_\[^ \]+ map.tofrom:y" 3 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop private.i. reduction..:y." 3 "gimple" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/common-block-1.f90 b/gcc/testsuite/gfortran.dg/goacc/common-block-1.f90
index 6df5aa65e707effd93f661ea73eccedaddf55035..7c0815c2dd6c2bc139624d6dc6bd4d34f5e23032 100644
--- a/gcc/testsuite/gfortran.dg/goacc/common-block-1.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/common-block-1.f90
@@ -60,6 +60,12 @@ program test
   !$acc parallel firstprivate(/blockA/, /blockB/, e, v)
   !$acc end parallel
 
+  !$acc serial private(/blockA/, /blockB/, e, v)
+  !$acc end serial
+
+  !$acc serial firstprivate(/blockA/, /blockB/, e, v)
+  !$acc end serial
+
   !$acc update device(/blockA/)
   !$acc update self(/blockB/, v)
   !$acc update host(/blockA/, e, /blockB/)
diff --git a/gcc/testsuite/gfortran.dg/goacc/common-block-2.f90 b/gcc/testsuite/gfortran.dg/goacc/common-block-2.f90
index 30c87a91f36b782823257d7355bb1f99375abefa..a0533638c36b57a299dd6159862ca78e648fa73f 100644
--- a/gcc/testsuite/gfortran.dg/goacc/common-block-2.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/common-block-2.f90
@@ -48,6 +48,12 @@ program test
   !$acc parallel firstprivate(/blockA/, /blockB/, e, v, a) ! { dg-error "Symbol .a. present on multiple clauses" }
   !$acc end parallel
 
+  !$acc serial private(/blockA/, /blockB/, e, v, a) ! { dg-error "Symbol .a. present on multiple clauses" }
+  !$acc end serial
+
+  !$acc serial firstprivate(/blockA/, /blockB/, e, v, a) ! { dg-error "Symbol .a. present on multiple clauses" }
+  !$acc end serial
+
   !$acc update device(b, /blockA/, x) ! { dg-error "Symbol .x. present on multiple clauses" }
   !$acc update self(z, /blockB/, v) ! { dg-error "Symbol .z. present on multiple clauses" }
   !$acc update host(/blockA/, c) ! { dg-error "Symbol .c. present on multiple clauses" }
diff --git a/gcc/testsuite/gfortran.dg/goacc/common-block-3.f90 b/gcc/testsuite/gfortran.dg/goacc/common-block-3.f90
index 6f08d7eb8d5b60ae29bba0b4a39d9164596b132d..4861a643ecac937a7de02b64162919cf46a78f07 100644
--- a/gcc/testsuite/gfortran.dg/goacc/common-block-3.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/common-block-3.f90
@@ -39,6 +39,12 @@ program main
      x(i) = y(i) + c
   end do
   !$acc end kernels
+  !$acc serial loop copy(/BLOCK/) ! { dg-line l3 }
+  ! { dg-note {variable 'i' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l3 }
+  ! { dg-optimized {assigned OpenACC gang vector loop parallelism} {} { target *-*-* } l3 }
+  do i = 1, n
+     a(i) = b(i) + c
+  end do
 end program main
 
 ! { dg-final { scan-tree-dump-times "omp target oacc_parallel .*map\\(tofrom:a \\\[len: 400\\\]\\)" 1 "omplower" } }
@@ -54,6 +60,10 @@ end program main
 ! { dg-final { scan-tree-dump-times "omp target oacc_data_kernels .*map\\(force_tofrom:c \\\[len: 4\\\]\\)" 1 "omplower" } }
 !   { dg-final { scan-tree-dump-times "omp target oacc_kernels .*map\\(force_present:c \\\[len: 4\\\]\\)" 1 "omplower" } }
 
+! { dg-final { scan-tree-dump-times "omp target oacc_serial .*map\\(tofrom:a \\\[len: 400\\\]\\)" 1 "omplower" } }
+! { dg-final { scan-tree-dump-times "omp target oacc_serial .*map\\(tofrom:b \\\[len: 400\\\]\\\)" 1 "omplower" } }
+! { dg-final { scan-tree-dump-times "omp target oacc_serial .*map\\(tofrom:c \\\[len: 4\\\]\\)" 1 "omplower" } }
+
 ! Expecting no mapping of un-referenced common-blocks variables
 
 ! { dg-final { scan-tree-dump-not "map\\(.*:block" "omplower" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/parallel-kernels-clauses.f95 b/gcc/testsuite/gfortran.dg/goacc/compute_construct-clauses.f95
similarity index 69%
rename from gcc/testsuite/gfortran.dg/goacc/parallel-kernels-clauses.f95
rename to gcc/testsuite/gfortran.dg/goacc/compute_construct-clauses.f95
index 70b84f115496dbb7198d9584482905db79dae93c..bce902bbcc6f3847969d653410b94f5af7ff7543 100644
--- a/gcc/testsuite/gfortran.dg/goacc/parallel-kernels-clauses.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/compute_construct-clauses.f95
@@ -1,8 +1,6 @@
 ! { dg-do compile } 
 ! { dg-additional-options "-fmax-errors=100" } 
 
-! test clauses added in OpenACC ver 2.0
-
 program test
   implicit none
   integer :: i, a(10), b(5:7)
@@ -15,61 +13,83 @@ program test
   !$acc end kernels
   !$acc parallel async(i)
   !$acc end parallel
+  !$acc serial async(i)
+  !$acc end serial
 
   !$acc kernels async(0, 1) { dg-error "Failed to match clause" }
   !$acc parallel async(0, 1) { dg-error "Failed to match clause" }
+  !$acc serial async(0, 1) { dg-error "Failed to match clause" }
 
   !$acc kernels async
   !$acc end kernels
   !$acc parallel async
   !$acc end parallel
+  !$acc serial async
+  !$acc end serial
 
   !$acc kernels async(acc_async_noval)
   !$acc end kernels
   !$acc parallel async(acc_async_noval)
   !$acc end parallel
+  !$acc serial async(acc_async_noval)
+  !$acc end serial
 
   !$acc kernels async(acc_async_sync)
   !$acc end kernels
   !$acc parallel async(acc_async_sync)
   !$acc end parallel
+  !$acc serial async(acc_async_sync)
+  !$acc end serial
 
   !$acc kernels async() { dg-error "Invalid character" }
   !$acc parallel async() { dg-error "Invalid character" }
+  !$acc serial async() { dg-error "Invalid character" }
 
   !$acc kernels async("a") { dg-error "Failed to match clause" }
   !$acc parallel async("a") { dg-error "Failed to match clause" }
+  !$acc serial async("a") { dg-error "Failed to match clause" }
 
   !$acc kernels async(.true.) { dg-error "Failed to match clause" }
   !$acc parallel async(.true.) { dg-error "Failed to match clause" }
+  !$acc serial async(.true.) { dg-error "Failed to match clause" }
 
   ! default(none)
   !$acc kernels default(none)
   !$acc end kernels
   !$acc parallel default(none)
   !$acc end parallel
+  !$acc serial default(none)
+  !$acc end serial
 
   !$acc kernels default (none)
   !$acc end kernels
   !$acc parallel default (none)
   !$acc end parallel
+  !$acc serial default (none)
+  !$acc end serial
 
   !$acc kernels default ( none )
   !$acc end kernels
   !$acc parallel default ( none )
   !$acc end parallel
+  !$acc serial default ( none )
+  !$acc end serial
 
   !$acc kernels default { dg-error "Expected '\\(' after 'default'" }
   !$acc parallel default { dg-error "Expected '\\(' after 'default'" }
+  !$acc serial default { dg-error "Expected '\\(' after 'default'" }
 
   !$acc kernels default() { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
   !$acc parallel default() { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
+  !$acc serial default() { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 
   !$acc kernels default(i) { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
   !$acc parallel default(i) { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
+  !$acc serial default(i) { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 
   !$acc kernels default(1) { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
   !$acc parallel default(1) { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
+  !$acc serial default(1) { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 
   ! Wait
   !$acc kernels wait (l) ! { dg-error "INTEGER" }
@@ -93,4 +113,16 @@ program test
   !$acc end parallel
   !$acc parallel wait (b(5:6)) ! { dg-error "INTEGER" }
   !$acc end parallel
+
+  !$acc serial wait (l) ! { dg-error "INTEGER" }
+  !$acc end serial
+  !$acc serial wait (.true.) ! { dg-error "INTEGER" }
+  !$acc end serial
+  !$acc serial wait (i, 1) 
+  !$acc end serial
+  !$acc serial wait (a) ! { dg-error "INTEGER" }
+  !$acc end serial
+  !$acc serial wait (b(5:6)) ! { dg-error "INTEGER" }
+  !$acc end serial
+
 end
diff --git a/gcc/testsuite/gfortran.dg/goacc/cray-2.f95 b/gcc/testsuite/gfortran.dg/goacc/cray-2.f95
index 51b79b53636f2aa3f66471d71b7468f19b28e1b7..1d28ae3ab436d3a52d7f79dde649b30ae25b788c 100644
--- a/gcc/testsuite/gfortran.dg/goacc/cray-2.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/cray-2.f95
@@ -17,17 +17,28 @@ contains
     !$acc end data
     !$acc parallel private (pointee) ! { dg-error "Cray pointee" }
     !$acc end parallel
+    !$acc serial private (pointee) ! { dg-error "Cray pointee" }
+    !$acc end serial
     !$acc host_data use_device (pointee) ! { dg-error "Cray pointee" }
     !$acc end host_data
     !$acc parallel loop reduction(+:pointee) ! { dg-error "Cray pointee" }
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:pointee) ! { dg-error "Cray pointee" }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc parallel loop
     do i = 1,5
       !$acc cache (pointee) ! { dg-error "Cray pointee" }
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+      !$acc cache (pointee) ! { dg-error "Cray pointee" }
+    enddo
+    !$acc end serial loop
     !$acc update device (pointee) ! { dg-error "Cray pointee" }
     !$acc update host (pointee) ! { dg-error "Cray pointee" }
     !$acc update self (pointee) ! { dg-error "Cray pointee" }
@@ -37,18 +48,30 @@ contains
     !$acc end data
     !$acc parallel private (ptr)
     !$acc end parallel
+    !$acc serial private (ptr)
+    !$acc end serial
     !$acc host_data use_device (ptr) ! { dg-error "Cray pointer" }
     !$acc end host_data
     !$acc parallel loop reduction(+:ptr) ! { dg-error "Cray pointer" }
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:ptr) ! { dg-error "Cray pointer" }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc parallel loop
     do i = 1,5
       !TODO: This must fail, as in openacc-1_0-branch.
       !$acc cache (ptr) ! { dg-error "" "TODO" { xfail *-*-* } }
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+      !TODO: This must fail, as in openacc-1_0-branch.
+      !$acc cache (ptr) ! { dg-error "" "TODO" { xfail *-*-* } }
+    enddo
+    !$acc end serial loop
     !$acc update device (ptr)
     !$acc update host (ptr)
     !$acc update self (ptr)
diff --git a/gcc/testsuite/gfortran.dg/goacc/cray.f95 b/gcc/testsuite/gfortran.dg/goacc/cray.f95
index d6d531705a696b2bf30951f63b21f5ca2d36e0c9..b488f86c38c6b1116ef9ba5a3c99c22e5d829158 100644
--- a/gcc/testsuite/gfortran.dg/goacc/cray.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/cray.f95
@@ -16,17 +16,28 @@ contains
     !$acc end data
     !$acc parallel private (pointee) ! { dg-error "Cray pointee" }
     !$acc end parallel
+    !$acc serial private (pointee) ! { dg-error "Cray pointee" }
+    !$acc end serial
     !$acc host_data use_device (pointee) ! { dg-error "Cray pointee" }
     !$acc end host_data
     !$acc parallel loop reduction(+:pointee) ! { dg-error "Cray pointee" }
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:pointee) ! { dg-error "Cray pointee" }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc parallel loop
     do i = 1,5
       !$acc cache (pointee) ! { dg-error "Cray pointee" }
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+      !$acc cache (pointee) ! { dg-error "Cray pointee" }
+    enddo
+    !$acc end serial loop
     !$acc update device (pointee) ! { dg-error "Cray pointee" }
     !$acc update host (pointee) ! { dg-error "Cray pointee" }
     !$acc update self (pointee) ! { dg-error "Cray pointee" }
@@ -36,18 +47,30 @@ contains
     !$acc end data
     !$acc parallel private (ptr)
     !$acc end parallel
+    !$acc serial private (ptr)
+    !$acc end serial
     !$acc host_data use_device (ptr) ! { dg-error "Cray pointer" }
     !$acc end host_data
     !$acc parallel loop reduction(+:ptr) ! { dg-error "Cray pointer" }
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:ptr) ! { dg-error "Cray pointer" }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc parallel loop
     do i = 1,5
       !TODO: This must fail, as in openacc-1_0-branch.
       !$acc cache (ptr) ! { dg-error "" "TODO" { xfail *-*-* } }
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+      !TODO: This must fail, as in openacc-1_0-branch.
+      !$acc cache (ptr) ! { dg-error "" "TODO" { xfail *-*-* } }
+    enddo
+    !$acc end serial loop
     !$acc update device (ptr)
     !$acc update host (ptr)
     !$acc update self (ptr)
diff --git a/gcc/testsuite/gfortran.dg/goacc/critical.f95 b/gcc/testsuite/gfortran.dg/goacc/critical.f95
index 510ea1850527a83d21493b6ae4f40a939295da31..75a5df831766304d143128041525c7093a815981 100644
--- a/gcc/testsuite/gfortran.dg/goacc/critical.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/critical.f95
@@ -12,6 +12,11 @@ contains
     j = j + 1
   end critical
   !$acc end parallel
+  !$acc serial 
+  critical ! { dg-error "CRITICAL block inside of" }
+    j = j + 1
+  end critical
+  !$acc end serial
   end subroutine oacc1
 
   subroutine oacc2
@@ -22,6 +27,9 @@ contains
     !$acc parallel ! { dg-error "OpenACC directive inside of" }
       j = j + 1
     !$acc end parallel
+    !$acc serial ! { dg-error "OpenACC directive inside of" }
+      j = j + 1
+    !$acc end serial
   end critical
   end subroutine oacc2
 end module test
\ No newline at end of file
diff --git a/gcc/testsuite/gfortran.dg/goacc/data-clauses.f95 b/gcc/testsuite/gfortran.dg/goacc/data-clauses.f95
index fe32f1eaf087e8dbbe68d0f7dbce3c0ca748d102..61c4da14b623a1342a0554fd590f82acfee89018 100644
--- a/gcc/testsuite/gfortran.dg/goacc/data-clauses.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/data-clauses.f95
@@ -35,6 +35,8 @@ contains
   !$acc end parallel
   !$acc kernels deviceptr (i, c, r, ia, ca, ra, asa, ti)
   !$acc end kernels
+  !$acc serial deviceptr (i, c, r, ia, ca, ra, asa, ti)
+  !$acc end serial
   !$acc data deviceptr (i, c, r, ia, ca, ra, asa, ti)
   !$acc end data
 
@@ -50,6 +52,8 @@ contains
   !$acc end parallel
   !$acc kernels copy (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end kernels
+  !$acc serial copy (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
+  !$acc end serial
   !$acc data copy (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end data
 
@@ -67,6 +71,8 @@ contains
   !$acc end parallel
   !$acc kernels copyin (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end kernels
+  !$acc serial copyin (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
+  !$acc end serial
   !$acc data copyin (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end data
 
@@ -86,6 +92,8 @@ contains
   !$acc end parallel
   !$acc kernels copyout (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end kernels
+  !$acc serial copyout (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
+  !$acc end serial
   !$acc data copyout (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end data
 
@@ -107,6 +115,8 @@ contains
   !$acc end parallel
   !$acc kernels create (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end kernels
+  !$acc serial create (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
+  !$acc end serial
   !$acc data create (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end data
 
@@ -128,6 +138,8 @@ contains
   !$acc end parallel
   !$acc kernels no_create (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end kernels
+  !$acc serial no_create (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
+  !$acc end serial
   !$acc data no_create (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end data
 
@@ -151,6 +163,8 @@ contains
   !$acc end parallel
   !$acc kernels present (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end kernels
+  !$acc serial present (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
+  !$acc end serial
   !$acc data present (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end data
 
@@ -186,6 +200,8 @@ contains
   !$acc end parallel
   !$acc kernels present_or_copy (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end kernels
+  !$acc serial present_or_copy (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
+  !$acc end serial
   !$acc data present_or_copy (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end data
 
@@ -213,6 +229,8 @@ contains
   !$acc end parallel
   !$acc kernels present_or_copyin (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end kernels
+  !$acc serial present_or_copyin (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
+  !$acc end serial
   !$acc data present_or_copyin (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end data
 
@@ -242,6 +260,8 @@ contains
   !$acc end parallel
   !$acc kernels present_or_copyout (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end kernels
+  !$acc serial present_or_copyout (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
+  !$acc end serial
   !$acc data present_or_copyout (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end data
 
@@ -273,6 +293,8 @@ contains
   !$acc end parallel
   !$acc kernels present_or_create (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end kernels
+  !$acc serial present_or_create (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
+  !$acc end serial
   !$acc data present_or_create (i, c, r, ia, ca, ra, asa, rp, ti, vi, aa)
   !$acc end data
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/default-1.f95 b/gcc/testsuite/gfortran.dg/goacc/default-1.f95
index 41fa9446b91081f63b5823215980c26b1ef49d07..cb1de7c8c29c7743205eac3d04978506504ab739 100644
--- a/gcc/testsuite/gfortran.dg/goacc/default-1.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/default-1.f95
@@ -7,9 +7,14 @@ subroutine f1
   !$acc end kernels
   !$acc parallel default (none)
   !$acc end parallel
+  !$acc serial default (none)
+  !$acc end serial
 
   !$acc kernels default (present)
   !$acc end kernels
   !$acc parallel default (present)
   !$acc end parallel
+  !$acc serial default (present)
+  !$acc end serial
+
 end subroutine f1
diff --git a/gcc/testsuite/gfortran.dg/goacc/default-2.f b/gcc/testsuite/gfortran.dg/goacc/default-2.f
index 963d9780c65bef52b90d332a73d8cdf62150ff74..995e2882dd7984a98a231fb275cc9c56229917c5 100644
--- a/gcc/testsuite/gfortran.dg/goacc/default-2.f
+++ b/gcc/testsuite/gfortran.dg/goacc/default-2.f
@@ -7,54 +7,77 @@
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT ! { dg-error "Expected '\\(' after 'default" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT ! { dg-error "Expected '\\(' after 'default" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
 
 !$ACC KERNELS DEFAULT ( ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT ( ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT ( ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
 
 !$ACC KERNELS DEFAULT (, ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT (, ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT (, ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
 
 !$ACC KERNELS DEFAULT () ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT () ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT () ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
 
 !$ACC KERNELS DEFAULT (,) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT (,) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT (,) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
 
 !$ACC KERNELS DEFAULT (FIRSTPRIVATE) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT (FIRSTPRIVATE) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT (FIRSTPRIVATE) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
 
 !$ACC KERNELS DEFAULT (PRIVATE) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT (PRIVATE) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT (PRIVATE) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
 
 !$ACC KERNELS DEFAULT (SHARED) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT (SHARED) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT (SHARED) ! { dg-error "Expected NONE or PRESENT in DEFAULT clause" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
 
 !$ACC KERNELS DEFAULT (NONE ! { dg-error "Failed to match clause" }
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT (NONE ! { dg-error "Failed to match clause" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT (NONE ! { dg-error "Failed to match clause" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
 
 !$ACC KERNELS DEFAULT (NONE NONE) ! { dg-error "Failed to match clause" }
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT (NONE NONE) ! { dg-error "Failed to match clause" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT (NONE NONE) ! { dg-error "Failed to match clause" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
 
 !$ACC KERNELS DEFAULT (NONE, NONE) ! { dg-error "Failed to match clause" }
 !$ACC END KERNELS ! { dg-error "Unexpected" }
 !$ACC PARALLEL DEFAULT (NONE, NONE) ! { dg-error "Failed to match clause" }
 !$ACC END PARALLEL ! { dg-error "Unexpected" }
+!$ACC SERIAL DEFAULT (NONE, NONE) ! { dg-error "Failed to match clause" }
+!$ACC END SERIAL ! { dg-error "Unexpected" }
+
       END SUBROUTINE F1
diff --git a/gcc/testsuite/gfortran.dg/goacc/default-3.f95 b/gcc/testsuite/gfortran.dg/goacc/default-3.f95
index c1edf4c81371ed8f90b5fc7cbcbab4ed43271586..5c9ec5b561a61b90d488b85ff01278492a0aab10 100644
--- a/gcc/testsuite/gfortran.dg/goacc/default-3.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/default-3.f95
@@ -15,6 +15,11 @@ subroutine f1
        = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .parallel. construct" }
   ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .parallel. construct" "" { xfail *-*-* } .-1 }
   !$acc end parallel
+  !$acc serial default (none) ! { dg-note "enclosing OpenACC .serial. construct with 'default\\\(none\\\)' clause" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } .-1 }
+  !$acc end serial
 
   !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
   !$acc kernels ! { dg-note "enclosing OpenACC 'kernels' construct and" }
@@ -23,7 +28,6 @@ subroutine f1
   ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } .-1 }
   !$acc end kernels
   !$acc end data
-
   !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
   !$acc parallel ! { dg-note "enclosing OpenACC 'parallel' construct and" }
   f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .parallel. construct" "" { xfail *-*-* } }
@@ -31,7 +35,21 @@ subroutine f1
   ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .parallel. construct" "" { xfail *-*-* } .-1 }
   !$acc end parallel
   !$acc end data
+  !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
+  !$acc serial ! { dg-note "enclosing OpenACC 'serial' construct and" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } .-1 }
+  !$acc end serial
+  !$acc end data
 
+  !$acc data default (none)
+  !$acc kernels default (none) ! { dg-note "enclosing OpenACC .kernels. construct with 'default\\\(none\\\)' clause" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .kernels. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } .-1 }
+  !$acc end kernels
+  !$acc end data
   !$acc data default (none)
   !$acc parallel default (none) ! { dg-note "enclosing OpenACC .parallel. construct with 'default\\\(none\\\)' clause" }
   f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .parallel. construct" "" { xfail *-*-* } }
@@ -39,7 +57,25 @@ subroutine f1
   ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .parallel. construct" "" { xfail *-*-* } .-1 }
   !$acc end parallel
   !$acc end data
+  !$acc data default (none)
+  !$acc serial default (none) ! { dg-note "enclosing OpenACC .serial. construct with 'default\\\(none\\\)' clause" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } .-1 }
+  !$acc end serial
+  !$acc end data
 
+  !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
+  !$acc data
+  !$acc data
+  !$acc kernels ! { dg-note "enclosing OpenACC 'kernels' construct and" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .kernels. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } .-1 }
+  !$acc end kernels
+  !$acc end data
+  !$acc end data
+  !$acc end data
   !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
   !$acc data
   !$acc data
@@ -51,7 +87,29 @@ subroutine f1
   !$acc end data
   !$acc end data
   !$acc end data
+  !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
+  !$acc data
+  !$acc data
+  !$acc serial ! { dg-note "enclosing OpenACC 'serial' construct and" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } .-1 }
+  !$acc end serial
+  !$acc end data
+  !$acc end data
+  !$acc end data
 
+  !$acc data
+  !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
+  !$acc data
+  !$acc kernels ! { dg-note "enclosing OpenACC 'kernels' construct and" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .kernels. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } .-1 }
+  !$acc end kernels
+  !$acc end data
+  !$acc end data
+  !$acc end data
   !$acc data
   !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
   !$acc data
@@ -63,7 +121,29 @@ subroutine f1
   !$acc end data
   !$acc end data
   !$acc end data
+  !$acc data
+  !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
+  !$acc data
+  !$acc serial ! { dg-note "enclosing OpenACC 'serial' construct and" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } .-1 }
+  !$acc end serial
+  !$acc end data
+  !$acc end data
+  !$acc end data
 
+  !$acc data
+  !$acc data
+  !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
+  !$acc kernels ! { dg-note "enclosing OpenACC 'kernels' construct and" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .kernels. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } .-1 }
+  !$acc end kernels
+  !$acc end data
+  !$acc end data
+  !$acc end data
   !$acc data
   !$acc data
   !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
@@ -75,7 +155,29 @@ subroutine f1
   !$acc end data
   !$acc end data
   !$acc end data
+  !$acc data
+  !$acc data
+  !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
+  !$acc serial ! { dg-note "enclosing OpenACC 'serial' construct and" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } .-1 }
+  !$acc end serial
+  !$acc end data
+  !$acc end data
+  !$acc end data
 
+  !$acc data
+  !$acc data default (none)
+  !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
+  !$acc kernels ! { dg-note "enclosing OpenACC 'kernels' construct and" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .kernels. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .kernels. construct" "" { xfail *-*-* } .-1 }
+  !$acc end kernels
+  !$acc end data
+  !$acc end data
+  !$acc end data
   !$acc data
   !$acc data default (none)
   !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
@@ -87,5 +189,16 @@ subroutine f1
   !$acc end data
   !$acc end data
   !$acc end data
+  !$acc data
+  !$acc data default (none)
+  !$acc data default (none) ! { dg-note "enclosing OpenACC 'data' construct with 'default\\\(none\\\)' clause" }
+  !$acc serial ! { dg-note "enclosing OpenACC 'serial' construct and" }
+  f1_b(1) & ! { dg-error ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } }
+       = f1_a; ! { dg-error ".f1_a. not specified in enclosing OpenACC .serial. construct" }
+  ! { dg-bogus ".f1_b. not specified in enclosing OpenACC .serial. construct" "" { xfail *-*-* } .-1 }
+  !$acc end serial
+  !$acc end data
+  !$acc end data
+  !$acc end data
 
 end subroutine f1
diff --git a/gcc/testsuite/gfortran.dg/goacc/default-4.f b/gcc/testsuite/gfortran.dg/goacc/default-4.f
index 4e89b6859bad581868083f9aaaff0dd351155092..35b267dfa100775f694b48d95d22bbcccef44e7e 100644
--- a/gcc/testsuite/gfortran.dg/goacc/default-4.f
+++ b/gcc/testsuite/gfortran.dg/goacc/default-4.f
@@ -17,6 +17,10 @@
 ! { dg-final { scan-tree-dump-times "omp target oacc_parallel map\\(tofrom:f1_b \[^\\)\]+\\) map\\(tofrom:f1_a" 1 "gimple" } }
       F1_B(1) = F1_A;
 !$ACC END PARALLEL
+!$ACC SERIAL
+! { dg-final { scan-tree-dump-times "omp target oacc_serial map\\(tofrom:f1_b \[^\\)\]+\\) map\\(tofrom:f1_a" 1 "gimple" } }
+      F1_B(1) = F1_A;
+!$ACC END SERIAL
 !$ACC END DATA
       END SUBROUTINE F1
 
@@ -35,6 +39,10 @@
 ! { dg-final { scan-tree-dump-times "omp target oacc_parallel default\\(none\\) map\\(tofrom:f2_b \[^\\)\]+\\) map\\(tofrom:f2_a" 1 "gimple" } }
       F2_B(1) = F2_A;
 !$ACC END PARALLEL
+!$ACC SERIAL DEFAULT (NONE)
+! { dg-final { scan-tree-dump-times "omp target oacc_serial default\\(none\\) map\\(tofrom:f2_b \[^\\)\]+\\) map\\(tofrom:f2_a" 1 "gimple" } }
+      F2_B(1) = F2_A;
+!$ACC END SERIAL
 !$ACC END DATA
       END SUBROUTINE F2
 
@@ -53,6 +61,10 @@
 ! { dg-final { scan-tree-dump-times "omp target oacc_parallel map\\(tofrom:f2__b \[^\\)\]+\\) map\\(tofrom:f2__a" 1 "gimple" } }
       F2__B(1) = F2__A;
 !$ACC END PARALLEL
+!$ACC SERIAL
+! { dg-final { scan-tree-dump-times "omp target oacc_serial map\\(tofrom:f2__b \[^\\)\]+\\) map\\(tofrom:f2__a" 1 "gimple" } }
+      F2__B(1) = F2__A;
+!$ACC END SERIAL
 !$ACC END DATA
       END SUBROUTINE F2_
 
@@ -71,6 +83,10 @@
 ! { dg-final { scan-tree-dump-times "omp target oacc_parallel default\\(present\\) map\\(tofrom:f3_b \[^\\)\]+\\) map\\(tofrom:f3_a" 1 "gimple" } }
       F3_B(1) = F3_A;
 !$ACC END PARALLEL
+!$ACC SERIAL DEFAULT (PRESENT)
+! { dg-final { scan-tree-dump-times "omp target oacc_serial default\\(present\\) map\\(tofrom:f3_b \[^\\)\]+\\) map\\(tofrom:f3_a" 1 "gimple" } }
+      F3_B(1) = F3_A;
+!$ACC END SERIAL
 !$ACC END DATA
       END SUBROUTINE F3
 
@@ -89,5 +105,9 @@
 ! { dg-final { scan-tree-dump-times "omp target oacc_parallel map\\(tofrom:f3__b \[^\\)\]+\\) map\\(tofrom:f3__a" 1 "gimple" } }
       F3__B(1) = F3__A;
 !$ACC END PARALLEL
+!$ACC SERIAL
+! { dg-final { scan-tree-dump-times "omp target oacc_serial map\\(tofrom:f3__b \[^\\)\]+\\) map\\(tofrom:f3__a" 1 "gimple" } }
+      F3__B(1) = F3__A;
+!$ACC END SERIAL
 !$ACC END DATA
       END SUBROUTINE F3_
diff --git a/gcc/testsuite/gfortran.dg/goacc/default-5.f b/gcc/testsuite/gfortran.dg/goacc/default-5.f
index 2cb07a8cbca231438d9cb59172debba9a04fbfac..99f0dc95b449f1637ec1bc057c49f633e0d28e52 100644
--- a/gcc/testsuite/gfortran.dg/goacc/default-5.f
+++ b/gcc/testsuite/gfortran.dg/goacc/default-5.f
@@ -15,6 +15,10 @@
 ! { dg-final { scan-tree-dump-times "omp target oacc_parallel default\\(present\\) map\\(force_present:f1_b \[^\\)\]+\\) firstprivate\\(f1_a\\)" 1 "gimple" } }
       F1_B(1) = F1_A;
 !$ACC END PARALLEL
+!$ACC SERIAL DEFAULT (PRESENT)
+! { dg-final { scan-tree-dump-times "omp target oacc_serial default\\(present\\) map\\(force_present:f1_b \[^\\)\]+\\) firstprivate\\(f1_a\\)" 1 "gimple" } }
+      F1_B(1) = F1_A;
+!$ACC END SERIAL
 
 !$ACC DATA DEFAULT (PRESENT)
 !$ACC KERNELS
@@ -29,5 +33,15 @@
       F1_D(1) = F1_C;
 !$ACC END PARALLEL
 !$ACC END DATA
+!$ACC END DATA
+!$ACC DATA DEFAULT (NONE)
+!$ACC DATA DEFAULT (NONE)
+!$ACC DATA DEFAULT (PRESENT)
+!$ACC SERIAL DEFAULT (PRESENT)
+! { dg-final { scan-tree-dump-times "omp target oacc_serial default\\(present\\) map\\(force_present:f1_d \[^\\)\]+\\) firstprivate\\(f1_c\\)" 1 "gimple" } }
+      F1_D(1) = F1_C;
+!$ACC END SERIAL
+!$ACC END DATA
+!$ACC END DATA
 !$ACC END DATA
       END SUBROUTINE F1
diff --git a/gcc/testsuite/gfortran.dg/goacc/default_none.f95 b/gcc/testsuite/gfortran.dg/goacc/default_none.f95
index 5ce66aeacf226653b64f6907dc81610b591043a9..3adb845f0cd675f4a68ebda4a5b65848c66b9710 100644
--- a/gcc/testsuite/gfortran.dg/goacc/default_none.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/default_none.f95
@@ -15,10 +15,16 @@ program main
 
   !$acc parallel loop default(none) copy (a1(1:n))
   do i = 1,n
-     a1(i) = i
+     a1(i) = a1(i) + 1 * i
   end do
   !$acc end parallel loop
 
+  !$acc serial loop default(none) copy (a1(1:n))
+  do i = 1,n
+     a1(i) = a1(i) + 3 * i
+  end do
+  !$acc end serial loop
+
   call foo (a1)
   call bar (a1, n)
   call foobar (a2,n)
@@ -30,9 +36,16 @@ contains
 
     !$acc parallel loop default(none) copy (da1(1:n))
     do i = 1,n
-       da1(i) = i*2
+       da1(i) = da1(i) + 1 * i * 2
     end do
     !$acc end parallel loop
+
+    !$acc serial loop default(none) copy (da1(1:n))
+    do i = 1,n
+       da1(i) = da1(i) + 3 * i * 2
+    end do
+    !$acc end serial loop
+
   end subroutine foo
 end program main
 
@@ -42,9 +55,16 @@ subroutine bar (da2,n)
 
   !$acc parallel loop default(none) copy (da2(1:n)) firstprivate(n)
   do i = 1,n
-     da2(i) = i*3
+     da2(i) = da2(i) + 1 * i * 3
   end do
   !$acc end parallel loop
+
+  !$acc serial loop default(none) copy (da2(1:n)) firstprivate(n)
+  do i = 1,n
+     da2(i) = da2(i) + 1 * i * 3
+  end do
+  !$acc end serial loop
+
 end subroutine bar
 
 subroutine foobar (da3,n)
@@ -53,7 +73,14 @@ subroutine foobar (da3,n)
 
   !$acc parallel loop default(none) copy (da3(-n:n,-n:n)) firstprivate(n)
   do i = 1,n
-     da3(i,0) = i*3
+     da3(i, 0) = da3(i, 0) + 1 * i * 3
   end do
   !$acc end parallel loop
+
+  !$acc serial loop default(none) copy (da3(-n:n,-n:n)) firstprivate(n)
+  do i = 1,n
+     da3(i, 0) = da3(i, 0) + 1 * i * 3
+  end do
+  !$acc end serial loop
+
 end subroutine foobar
diff --git a/gcc/testsuite/gfortran.dg/goacc/derived-types.f90 b/gcc/testsuite/gfortran.dg/goacc/derived-types.f90
index 5fb29816c42f6dc93c306e236c71bad528abea01..c9d6285397e875c3ebc0d920f4eac3559ca9ac91 100644
--- a/gcc/testsuite/gfortran.dg/goacc/derived-types.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/derived-types.f90
@@ -74,4 +74,22 @@ program derived_acc
   do i = 1, 10
   end do
   !$acc end kernels loop
+
+  !$acc serial loop pcopyout(var)
+  do i = 1, 10
+  end do  
+  !$acc end serial loop
+
+  !$acc serial loop copyout(var%a)
+  do i = 1, 10
+  end do
+  !$acc end serial loop
+
+  !$acc serial pcopy(var)
+  !$acc end serial
+
+  !$acc serial pcopy(var%a)
+  do i = 1, 10
+  end do
+  !$acc end serial
 end program derived_acc
diff --git a/gcc/testsuite/gfortran.dg/goacc/firstprivate-1.f95 b/gcc/testsuite/gfortran.dg/goacc/firstprivate-1.f95
index fb92deedadf6be6cbf87f999dbe0d17278c3ee17..a1ae97d0129540558fc9389d2a23199a6e7cb5e8 100644
--- a/gcc/testsuite/gfortran.dg/goacc/firstprivate-1.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/firstprivate-1.f95
@@ -8,4 +8,12 @@ program test
 
   !$acc parallel firstprivate (b(10:20)) ! { dg-error "Syntax error in OpenMP variable list" }
   !$acc end parallel ! { dg-error "Unexpected !\\\$ACC END PARALLEL statement" }
+
+
+  !$acc serial firstprivate (a, b)
+  !$acc end serial
+
+  !$acc serial firstprivate (b(10:20)) ! { dg-error "Syntax error in OpenMP variable list" }
+  !$acc end serial ! { dg-error "Unexpected !\\\$ACC END SERIAL statement" }
+
 end program test
diff --git a/gcc/testsuite/gfortran.dg/goacc/gang-static.f95 b/gcc/testsuite/gfortran.dg/goacc/gang-static.f95
index cc83c7dd65b9b877034024c47837cc946d441d14..e6e0c2f1c52ea63041a1909f0f6da6712ab7361f 100644
--- a/gcc/testsuite/gfortran.dg/goacc/gang-static.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/gang-static.f95
@@ -9,6 +9,7 @@ program main
      b(i) = i
   end do
 
+
   !$acc parallel loop gang (static:*) num_gangs (10)
   do i = 1, n
      a(i) = b(i) + 0
@@ -47,6 +48,9 @@ program main
   end do
   !$acc end parallel loop
 
+  call test (a, b, 20, n)
+
+
   !$acc kernels loop gang (num:5, static:*)
   do i = 1, n
      a(i) = b(i) + 20
@@ -59,6 +63,45 @@ program main
   end do
   !$acc end kernels loop
 
+
+  !$acc serial loop gang (static:*)
+  do i = 1, n
+     a(i) = b(i) + 0
+  end do
+  !$acc end serial loop
+
+  call test (a, b, 0, n)
+
+  !$acc serial loop gang (static:1)
+  do i = 1, n
+     a(i) = b(i) + 1
+  end do
+  !$acc end serial loop
+
+  call test (a, b, 1, n)
+
+  !$acc serial loop gang (static:2)
+  do i = 1, n
+     a(i) = b(i) + 2
+  end do
+  !$acc end serial loop
+
+  call test (a, b, 2, n)
+
+  !$acc serial loop gang (static:5)
+  do i = 1, n
+     a(i) = b(i) + 5
+  end do
+  !$acc end serial loop
+
+  call test (a, b, 5, n)
+
+  !$acc serial loop gang (static:20)
+  do i = 1, n
+     a(i) = b(i) + 20
+  end do
+  !$acc end serial loop
+
   call test (a, b, 20, n)
 
 end program main
@@ -73,10 +116,10 @@ subroutine test (a, b, sarg, n)
   end do
 end subroutine test
 
-! { dg-final { scan-tree-dump-times "gang\\(static:\\\*\\)" 1 "omplower" } }
-! { dg-final { scan-tree-dump-times "gang\\(static:1\\)" 1 "omplower" } }
-! { dg-final { scan-tree-dump-times "gang\\(static:2\\)" 1 "omplower" } }
-! { dg-final { scan-tree-dump-times "gang\\(static:5\\)" 1 "omplower" } }
-! { dg-final { scan-tree-dump-times "gang\\(static:20\\)" 1 "omplower" } }
+! { dg-final { scan-tree-dump-times "gang\\(static:\\\*\\)" 2 "omplower" } }
+! { dg-final { scan-tree-dump-times "gang\\(static:1\\)" 2 "omplower" } }
+! { dg-final { scan-tree-dump-times "gang\\(static:2\\)" 2 "omplower" } }
+! { dg-final { scan-tree-dump-times "gang\\(static:5\\)" 2 "omplower" } }
+! { dg-final { scan-tree-dump-times "gang\\(static:20\\)" 2 "omplower" } }
 ! { dg-final { scan-tree-dump-times "gang\\(num: 5 static:\\\*\\)" 1 "omplower" } }
 ! { dg-final { scan-tree-dump-times "gang\\(num: 30 static:20\\)" 1 "omplower" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/if.f95 b/gcc/testsuite/gfortran.dg/goacc/if.f95
index 753ef8251c2143ca90c5233ce343bd0d4a8079da..8411328ad449412f5dd9b9adc6ecb774928ab09b 100644
--- a/gcc/testsuite/gfortran.dg/goacc/if.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/if.f95
@@ -22,6 +22,13 @@ program test
   !$acc kernels if (1) ! { dg-error "scalar LOGICAL expression" }
   !$acc end kernels
 
+  !$acc serial if ! { dg-error "Expected '\\(' after 'if'" }
+  !$acc serial if () ! { dg-error "Invalid character" }
+  !$acc serial if (i) ! { dg-error "scalar LOGICAL expression" }
+  !$acc end serial 
+  !$acc serial if (1) ! { dg-error "scalar LOGICAL expression" }
+  !$acc end serial 
+
   !$acc data if ! { dg-error "Expected '\\(' after 'if'" }
   !$acc data if () ! { dg-error "Invalid character" }
   !$acc data if (i) ! { dg-error "scalar LOGICAL expression" }
@@ -32,6 +39,7 @@ program test
   ! at most one if clause may appear
   !$acc parallel if (.false.) if (.false.) { dg-error "Duplicated 'if' clause" }
   !$acc kernels if (.false.) if (.false.) { dg-error "Duplicated 'if' clause" }
+  !$acc serial if (.false.) if (.false.) { dg-error "Duplicated 'if' clause" }
   !$acc data if (.false.) if (.false.) { dg-error "Duplicated 'if' clause" }
 
   !$acc parallel if (x)
@@ -48,6 +56,13 @@ program test
   !$acc kernels if (i.gt.1)
   !$acc end kernels
 
+  !$acc serial if (x)
+  !$acc end serial
+  !$acc serial if (.true.)
+  !$acc end serial
+  !$acc serial if (i.gt.1)
+  !$acc end serial
+
   !$acc data if (x)
   !$acc end data
   !$acc data if (.true.)
diff --git a/gcc/testsuite/gfortran.dg/goacc/list.f95 b/gcc/testsuite/gfortran.dg/goacc/list.f95
index 3d4ebf88720e860c570b1c661952b3bfe96a804e..0df6d2552a8a0ddd22b6cd1fe0ac930baeb4999e 100644
--- a/gcc/testsuite/gfortran.dg/goacc/list.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/list.f95
@@ -9,6 +9,7 @@ program test
   real, pointer :: p1 => NULL()
   complex :: c, d(10)
 
+
   !$acc parallel private(i)
   !$acc end parallel
 
@@ -76,6 +77,75 @@ program test
   !$acc parallel private (i) firstprivate (i) ! { dg-error "present on multiple clauses" }
   !$acc end parallel
 
+
+  !$acc serial private(i)
+  !$acc end serial
+
+  !$acc serial private(a)
+  !$acc end serial
+
+  !$acc serial private(c, d)
+  !$acc end serial
+
+  !$acc serial private(i, j, k, l, a)
+  !$acc end serial  
+
+  !$acc serial private (i) private (j)
+  !$acc end serial
+
+  !$acc serial private ! { dg-error "Failed to match clause" }
+
+  !$acc serial private() ! { dg-error "Syntax error" }
+
+  !$acc serial private(a(1:3)) ! { dg-error "Syntax error" }
+
+  !$acc serial private(10) ! { dg-error "Syntax error" }
+
+  !$acc serial private(/b/, /b/) ! { dg-error "present on multiple clauses" }
+  !$acc end serial
+
+  !$acc serial private(i, j, i) ! { dg-error "present on multiple clauses" }
+  !$acc end serial
+
+  !$acc serial private(p1) 
+  !$acc end serial
+
+  !$acc serial firstprivate(i)
+  !$acc end serial
+
+  !$acc serial firstprivate(c, d)
+  !$acc end serial
+
+  !$acc serial firstprivate(a)
+  !$acc end serial
+
+  !$acc serial firstprivate(i, j, k, l, a)
+  !$acc end serial  
+
+  !$acc serial firstprivate (i) firstprivate (j)
+  !$acc end serial
+
+  !$acc serial firstprivate ! { dg-error "Failed to match clause" }
+
+  !$acc serial firstprivate() ! { dg-error "Syntax error" }
+
+  !$acc serial firstprivate(a(1:3)) ! { dg-error "Syntax error" }
+
+  !$acc serial firstprivate(10) ! { dg-error "Syntax error" }
+
+  !$acc serial firstprivate (/b/, /b/) ! { dg-error "present on multiple clauses" }
+  !$acc end serial
+
+  !$acc serial firstprivate (i, j, i) ! { dg-error "present on multiple clauses" }
+  !$acc end serial
+
+  !$acc serial firstprivate(p1) 
+  !$acc end serial
+
+  !$acc serial private (i) firstprivate (i) ! { dg-error "present on multiple clauses" }
+  !$acc end serial
+
+
   !$acc host_data use_device(i) ! { dg-error "neither a POINTER nor an array" }
   !$acc end host_data
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/literal.f95 b/gcc/testsuite/gfortran.dg/goacc/literal.f95
index 896749a46cb88c1b6b84b56270cffb846a9e62df..66687482831046eaa1d9b60957129fa71c2474c9 100644
--- a/gcc/testsuite/gfortran.dg/goacc/literal.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/literal.f95
@@ -18,11 +18,20 @@ contains
     do i = 1,5
     enddo
     !$acc end parallel loop ! { dg-error "Unexpected" }
+    !$acc serial loop reduction(+:10) ! { dg-error "Syntax error" }
+    do i = 1,5
+    enddo
+    !$acc end serial loop ! { dg-error "Unexpected" }
     !$acc parallel loop
     do i = 1,5
       !$acc cache (10) ! { dg-error "Syntax error" }
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+      !$acc cache (10) ! { dg-error "Syntax error" }
+    enddo
+    !$acc end serial loop
     !$acc update device (10) ! { dg-error "Syntax error" }
     !$acc update host (10) ! { dg-error "Syntax error" }
     !$acc update self (10) ! { dg-error "Syntax error" }
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-1-2.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-1-2.f95
index 8846e7d2a1f8fbd913442e3c462fd566d8f89f67..4ccb8c8bdcf11be1fa3dc5a8c8b7ed33a0a159b3 100644
--- a/gcc/testsuite/gfortran.dg/goacc/loop-1-2.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-1-2.f95
@@ -82,6 +82,13 @@ subroutine test1
   do i = 1,10
   enddo
   !$acc end kernels loop
+  !$acc serial loop
+  do i = 1,10
+  enddo
+  !$acc serial loop
+  do i = 1,10
+  enddo
+  !$acc end serial loop
 
   !$acc kernels loop reduction(max:i)
   do i = 1,10
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-1.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-1.f95
index 67dc97a3ecdd2bc842c9f6bb5d132c13a10c5496..2ad705335fe162b635c854df2a13e8fecde3227f 100644
--- a/gcc/testsuite/gfortran.dg/goacc/loop-1.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-1.f95
@@ -82,6 +82,13 @@ subroutine test1
   do i = 1,10
   enddo
   !$acc end kernels loop
+  !$acc serial loop
+  do i = 1,10
+  enddo
+  !$acc serial loop
+  do i = 1,10
+  enddo
+  !$acc end serial loop
 
   !$acc kernels loop reduction(max:i)
   do i = 1,10
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-2-parallel-3.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-2-parallel-3.f95
index 5379fba16ed8167574a87a984fb11014619168b9..8541c863495f1ca1c61a060cd94efc555451e28d 100644
--- a/gcc/testsuite/gfortran.dg/goacc/loop-2-parallel-3.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-2-parallel-3.f95
@@ -1,4 +1,4 @@
-! See also "../../c-c++-common/goacc/loop-3.c".
+! See also "../../c-c++-common/goacc/loop-3-parallel.c".
 
 program test
   implicit none
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-3.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-3.f95
new file mode 100644
index 0000000000000000000000000000000000000000..edfe5b67df0a843a714502330f10ca7cd2650c61
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-3.f95
@@ -0,0 +1,56 @@
+! See also "../../c-c++-common/goacc/loop-3-serial.c".
+
+program test
+  implicit none
+  integer :: i
+
+  !$acc serial
+    !$acc loop gang(5) ! { dg-error "argument not permitted" }
+    DO i = 1,10
+    ENDDO
+
+    !$acc loop gang(num:5) ! { dg-error "argument not permitted" }
+    DO i = 1,10
+    ENDDO
+
+    !$acc loop worker(5) ! { dg-error "argument not permitted" }
+    DO i = 1,10
+    ENDDO
+
+    !$acc loop worker(num:5) ! { dg-error "argument not permitted" }
+    DO i = 1,10
+    ENDDO
+
+    !$acc loop vector(5) ! { dg-error "argument not permitted" }
+    DO i = 1,10
+    ENDDO
+
+    !$acc loop vector(length:5) ! { dg-error "argument not permitted" }
+    DO i = 1,10
+    ENDDO
+  !$acc end serial
+
+  !$acc serial loop gang(5) ! { dg-error "argument not permitted" }
+  DO i = 1,10
+  ENDDO
+
+  !$acc serial loop gang(num:5) ! { dg-error "argument not permitted" }
+  DO i = 1,10
+  ENDDO
+
+  !$acc serial loop worker(5) ! { dg-error "argument not permitted" }
+  DO i = 1,10
+  ENDDO
+
+  !$acc serial loop worker(num:5) ! { dg-error "argument not permitted" }
+  DO i = 1,10
+  ENDDO
+
+  !$acc serial loop vector(5) ! { dg-error "argument not permitted" }
+  DO i = 1,10
+  ENDDO
+
+  !$acc serial loop vector(length:5) ! { dg-error "argument not permitted" }
+  DO i = 1,10
+  ENDDO
+end
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-nested.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-nested.f95
new file mode 100644
index 0000000000000000000000000000000000000000..16f8407d7a43443b1258c5c528f4bca3bf63d0d7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-nested.f95
@@ -0,0 +1,34 @@
+program test
+  implicit none
+  integer :: i, j
+
+  !$acc serial loop gang
+  DO i = 1,10
+    !$acc serial loop gang ! { dg-bogus "OpenACC construct inside of non-OpenACC region" "TODO" { xfail *-*-* } }
+    DO j = 1,10
+    ENDDO
+  ENDDO
+
+  !$acc serial loop worker
+  DO i = 1,10
+    !$acc serial loop worker ! { dg-bogus "OpenACC construct inside of non-OpenACC region" "TODO" { xfail *-*-* } }
+    DO j = 1,10
+    ENDDO
+    !$acc serial loop gang ! { dg-bogus "OpenACC construct inside of non-OpenACC region" "TODO" { xfail *-*-* } }
+    DO j = 1,10
+    ENDDO
+  ENDDO
+
+  !$acc serial loop vector
+  DO i = 1,10
+    !$acc serial loop vector ! { dg-bogus "OpenACC construct inside of non-OpenACC region" "TODO" { xfail *-*-* } }
+    DO j = 1,10
+    ENDDO
+    !$acc serial loop worker ! { dg-bogus "OpenACC construct inside of non-OpenACC region" "TODO" { xfail *-*-* } }
+    DO j = 1,10
+    ENDDO
+    !$acc serial loop gang ! { dg-bogus "OpenACC construct inside of non-OpenACC region" "TODO" { xfail *-*-* } }
+    DO j = 1,10
+    ENDDO
+  ENDDO
+end
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-tile.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-tile.f95
new file mode 100644
index 0000000000000000000000000000000000000000..79d8d1b9d4778988594ef911a8c3212379661d1f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-2-serial-tile.f95
@@ -0,0 +1,110 @@
+program test
+  implicit none
+  integer :: i, j
+
+  !$acc serial
+    !$acc loop tile ! { dg-error "Failed to match clause" }
+    DO i = 1,10
+    ENDDO
+    !$acc loop tile() ! { dg-error "Syntax error" }
+    DO i = 1,10
+    ENDDO
+    !$acc loop tile(1) 
+    DO i = 1,10
+    ENDDO
+    !$acc loop tile(*) 
+    DO i = 1,10
+    ENDDO
+    !$acc loop tile(2) 
+    DO i = 1,10
+      DO j = 1,10
+      ENDDO
+    ENDDO
+    !$acc loop tile(-1) ! { dg-warning "must be positive" }
+    do i = 1,10
+    enddo
+    !$acc loop tile(i) ! { dg-error "constant expression" }
+    do i = 1,10
+    enddo
+    !$acc loop tile(2, 2, 1) ! { dg-error "not enough DO loops for tiled" }
+      do i = 1, 3
+          do j = 4, 6
+          end do
+      end do    
+      !$acc loop tile(2, 2)
+      do i = 1, 5, 2
+          do j = i + 1, 7, i  ! { dg-error "tiled loops don.t form rectangular iteration space" }
+          end do
+      end do
+    !$acc loop vector tile(*) 
+    DO i = 1,10
+    ENDDO
+    !$acc loop worker tile(*) 
+    DO i = 1,10
+    ENDDO
+    !$acc loop gang tile(*) 
+    DO i = 1,10
+    ENDDO
+    !$acc loop vector gang tile(*) 
+    DO i = 1,10
+    ENDDO
+    !$acc loop vector worker tile(*) 
+    DO i = 1,10
+    ENDDO
+    !$acc loop gang worker tile(*) 
+    DO i = 1,10
+    ENDDO
+  !$acc end serial
+
+  !$acc serial loop tile ! { dg-error "Failed to match clause" }
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop tile() ! { dg-error "Syntax error" }
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop tile(1) 
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop tile(*) 
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop tile(*, 1) 
+  DO i = 1,10
+    DO j = 1,10
+    ENDDO
+  ENDDO
+  !$acc serial loop tile(-1) ! { dg-warning "must be positive" }
+  do i = 1,10
+  enddo
+  !$acc serial loop tile(i) ! { dg-error "constant expression" }
+  do i = 1,10
+  enddo
+  !$acc serial loop tile(2, 2, 1) ! { dg-error "not enough DO loops for tiled" }
+    do i = 1, 3
+        do j = 4, 6
+        end do
+    end do    
+    !$acc serial loop tile(2, 2)
+    do i = 1, 5, 2
+        do j = i + 1, 7, i  ! { dg-error "tiled loops don.t form rectangular iteration space" }
+        end do
+    end do
+  !$acc serial loop vector tile(*) 
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop worker tile(*) 
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop gang tile(*) 
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop vector gang tile(*) 
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop vector worker tile(*) 
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop gang worker tile(*) 
+  DO i = 1,10
+  ENDDO
+end
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-2-serial.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-2-serial.f95
new file mode 100644
index 0000000000000000000000000000000000000000..5aef965cc3405858ec8ee51b3f87aefa2f35502f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-2-serial.f95
@@ -0,0 +1,154 @@
+! See also "../../c-c++-common/goacc/loop-2-serial.c".
+
+program test
+  implicit none
+  integer :: i, j
+
+  !$acc serial
+    !$acc loop auto
+    DO i = 1,10
+    ENDDO
+    !$acc loop gang
+    DO i = 1,10
+    ENDDO
+    !$acc loop gang(static:5)
+    DO i = 1,10
+    ENDDO
+    !$acc loop gang(static:*)
+    DO i = 1,10
+    ENDDO
+    !$acc loop gang
+    DO i = 1,10
+      !$acc loop vector 
+      DO j = 1,10
+      ENDDO
+      !$acc loop worker 
+      DO j = 1,10
+      ENDDO
+      !$acc loop gang ! { dg-error "inner loop uses same OpenACC parallelism as containing loop" }
+      DO j = 1,10
+      ENDDO
+    ENDDO
+    !$acc loop seq gang ! { dg-error "'seq' overrides other OpenACC loop specifiers" }
+    DO i = 1,10
+    ENDDO
+
+    !$acc loop worker
+    DO i = 1,10
+    ENDDO
+    !$acc loop worker
+    DO i = 1,10
+      !$acc loop vector 
+      DO j = 1,10
+      ENDDO
+      !$acc loop worker ! { dg-error "inner loop uses same OpenACC parallelism as containing loop" }
+      DO j = 1,10
+      ENDDO
+      !$acc loop gang ! { dg-error "incorrectly nested OpenACC loop parallelism" }
+      DO j = 1,10
+      ENDDO
+    ENDDO
+    !$acc loop seq worker ! { dg-error "'seq' overrides other OpenACC loop specifiers" }
+    DO i = 1,10
+    ENDDO
+    !$acc loop gang worker
+    DO i = 1,10
+    ENDDO
+
+    !$acc loop vector
+    DO i = 1,10
+    ENDDO
+    !$acc loop vector
+    DO i = 1,10
+      !$acc loop vector ! { dg-error "inner loop uses same OpenACC parallelism as containing loop" }
+      DO j = 1,10
+      ENDDO
+      !$acc loop worker ! { dg-error "incorrectly nested OpenACC loop parallelism" }
+      DO j = 1,10
+      ENDDO
+      !$acc loop gang ! { dg-error "incorrectly nested OpenACC loop parallelism" }
+      DO j = 1,10
+      ENDDO
+    ENDDO
+    !$acc loop seq vector ! { dg-error "'seq' overrides other OpenACC loop specifiers" }
+    DO i = 1,10
+    ENDDO
+    !$acc loop gang vector
+    DO i = 1,10
+    ENDDO
+    !$acc loop worker vector
+    DO i = 1,10
+    ENDDO
+
+    !$acc loop auto
+    DO i = 1,10
+    ENDDO
+    !$acc loop seq auto ! { dg-error "'seq' overrides other OpenACC loop specifiers" }
+    DO i = 1,10
+    ENDDO
+    !$acc loop gang auto ! { dg-error "'auto' conflicts with other OpenACC loop specifiers" }
+    DO i = 1,10
+    ENDDO
+    !$acc loop worker auto ! { dg-error "'auto' conflicts with other OpenACC loop specifiers" }
+    DO i = 1,10
+    ENDDO
+    !$acc loop vector auto ! { dg-error "'auto' conflicts with other OpenACC loop specifiers" }
+    DO i = 1,10
+    ENDDO
+  !$acc end serial
+
+  !$acc serial loop auto
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop gang
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop gang(static:5)
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop gang(static:*)
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop seq gang ! { dg-error "'seq' overrides other OpenACC loop specifiers" }
+  DO i = 1,10
+  ENDDO
+
+  !$acc serial loop worker
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop seq worker ! { dg-error "'seq' overrides other OpenACC loop specifiers" }
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop gang worker
+  DO i = 1,10
+  ENDDO
+
+  !$acc serial loop vector
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop seq vector ! { dg-error "'seq' overrides other OpenACC loop specifiers" }
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop gang vector
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop worker vector
+  DO i = 1,10
+  ENDDO
+
+  !$acc serial loop auto
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop seq auto ! { dg-error "'seq' overrides other OpenACC loop specifiers" }
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop gang auto ! { dg-error "'auto' conflicts with other OpenACC loop specifiers" }
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop worker auto ! { dg-error "'auto' conflicts with other OpenACC loop specifiers" }
+  DO i = 1,10
+  ENDDO
+  !$acc serial loop vector auto ! { dg-error "'auto' conflicts with other OpenACC loop specifiers" }
+  DO i = 1,10
+  ENDDO
+end
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-3-2.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-3-2.f95
index c091084a4f5e6a70650b563486df6bf1fd1f4338..bd6a714b196e47d6104ed1cfe002ee169ff4533e 100644
--- a/gcc/testsuite/gfortran.dg/goacc/loop-3-2.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-3-2.f95
@@ -27,6 +27,14 @@ subroutine test1
   !$acc end parallel
   !$acc end loop ! { dg-error "Unexpected" }
 
+  !$acc serial
+  !$acc loop
+  do i = 1,5
+  enddo
+  !$acc end serial
+  !$acc end loop ! { dg-error "Unexpected" }
+
+
   ! OpenACC does not support Fortran 2008 do concurrent statement
   !$acc loop
   do concurrent (i = 1:5) ! { dg-error "ACC LOOP cannot be a DO CONCURRENT loop" }
diff --git a/gcc/testsuite/gfortran.dg/goacc/loop-3.f95 b/gcc/testsuite/gfortran.dg/goacc/loop-3.f95
index ed3e8d50a769122832210a669d05f81df2fd03e7..4122cfa801cdfee04b0a2b2e791b60db9934baf2 100644
--- a/gcc/testsuite/gfortran.dg/goacc/loop-3.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/loop-3.f95
@@ -24,6 +24,14 @@ subroutine test1
   !$acc end parallel
   !$acc end loop ! { dg-error "Unexpected" }
 
+  !$acc serial
+  !$acc loop
+  do i = 1,5
+  enddo
+  !$acc end serial
+  !$acc end loop ! { dg-error "Unexpected" }
+
+
   ! OpenACC does not support Fortran 2008 do concurrent statement
   !$acc loop
   do concurrent (i = 1:5) ! { dg-error "ACC LOOP cannot be a DO CONCURRENT loop" }
diff --git a/gcc/testsuite/gfortran.dg/goacc/multi-clause.f90 b/gcc/testsuite/gfortran.dg/goacc/multi-clause.f90
index eebf95f6fecedbd112f78f33b98786f3a70a6dea..d383aebc3cfdd8f206d0c9618aef5260f13d36b5 100644
--- a/gcc/testsuite/gfortran.dg/goacc/multi-clause.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/multi-clause.f90
@@ -10,4 +10,10 @@ program combined
   do i = 1, 100
   end do
   !$acc end parallel loop
+
+  !$acc serial loop reduction (+:j) copy (j) copyout(j) ! { dg-error "Symbol 'j' present on multiple clauses" }
+  do i = 1, 100
+  end do
+  !$acc end serial loop
+
 end program combined
diff --git a/gcc/testsuite/gfortran.dg/goacc/nested-parallelism.f90 b/gcc/testsuite/gfortran.dg/goacc/nested-parallelism.f90
index 1c192892c160f983c4eca3aea238c11d4cf9cabc..1d3274fd95c945711ed91a5fdbb46c7ae28befd8 100644
--- a/gcc/testsuite/gfortran.dg/goacc/nested-parallelism.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/nested-parallelism.f90
@@ -48,4 +48,51 @@ program np
      do j = 1, n
      end do     
   end do
+
+
+  !$acc serial loop gang
+  do i = 1, n
+     !$acc loop gang ! { dg-error "inner loop uses same OpenACC parallelism as containing loop" }
+     do j = 1, n
+     end do
+
+     !$acc loop worker
+     do j = 1, n
+     end do
+
+     !$acc loop vector
+     do j = 1, n
+     end do     
+  end do
+  
+  !$acc serial loop worker
+  do i = 1, n
+     !$acc loop gang ! { dg-error "incorrectly nested OpenACC loop parallelism" }
+     do j = 1, n
+     end do
+
+     !$acc loop worker ! { dg-error "inner loop uses same OpenACC parallelism as containing loop" }
+     do j = 1, n
+     end do
+
+     !$acc loop vector
+     do j = 1, n
+     end do     
+  end do
+
+  !$acc serial loop vector
+  do i = 1, n
+     !$acc loop gang ! { dg-error "incorrectly nested OpenACC loop parallelism" }
+     do j = 1, n
+     end do
+
+     !$acc loop worker ! { dg-error "incorrectly nested OpenACC loop parallelism" }
+     do j = 1, n
+     end do
+
+     !$acc loop vector ! { dg-error "inner loop uses same OpenACC parallelism as containing loop" }
+     do j = 1, n
+     end do     
+  end do
+
 end program np
diff --git a/gcc/testsuite/gfortran.dg/goacc/nested-reductions-1-serial.f90 b/gcc/testsuite/gfortran.dg/goacc/nested-reductions-1-serial.f90
new file mode 100644
index 0000000000000000000000000000000000000000..ba9fb44280447c456f08cf666fed7d4ecd0fec4f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/nested-reductions-1-serial.f90
@@ -0,0 +1,418 @@
+! Test cases of nested 'reduction' clauses expected to compile cleanly.
+
+! See also 'c-c++-common/goacc/nested-reductions-1-serial.c'.
+
+! { dg-additional-options -Wuninitialized }
+
+subroutine acc_serial ()
+  implicit none (type, external)
+  integer :: i, j, k, sum, diff
+
+  !$acc serial
+  ! implicit 'copy (sum, diff)'
+  ! { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+  ! { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 }
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop collapse(2) reduction(+:sum)
+    do i = 1, 10
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop collapse(2) reduction(+:sum)
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum) reduction(-:diff)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop reduction(-:diff)
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+  !$acc end serial
+end subroutine acc_serial
+
+! The same tests as above, but using a combined serial loop construct.
+
+subroutine acc_serial_loop ()
+  implicit none (type, external)
+  integer :: h, i, j, k, l, sum, diff
+
+  !$acc serial loop
+  ! implicit 'copy (sum, diff)'
+  ! { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+  ! { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 }
+  do h = 1, 10
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop collapse(2) reduction(+:sum)
+    do i = 1, 10
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop collapse(2) reduction(+:sum)
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)  ! { dg-warning "insufficient partitioning available to parallelize loop" }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum) reduction(-:diff)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)  ! { dg-warning "insufficient partitioning available to parallelize loop" }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop reduction(-:diff)  ! { dg-warning "insufficient partitioning available to parallelize loop" }
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+  end do
+end subroutine acc_serial_loop
+
+! The same tests as above, but now the outermost reduction clause is on
+! the serial region, not the outermost loop.  */
+
+subroutine acc_serial_reduction ()
+  implicit none (type, external)
+  integer :: i, j, k, sum, diff
+
+  !$acc serial reduction(+:sum)
+  ! implicit 'copy (sum, diff)'
+  ! { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+  ! { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 }
+    do i = 1, 10
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    do i = 1, 10
+      !$acc loop
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    do i = 1, 10
+      do j = 1, 10
+        !$acc loop
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum) reduction(-:diff)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop reduction(-:diff)
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop reduction(-:diff)
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+  !$acc end serial
+end subroutine acc_serial_reduction
+
+! The same tests as above, but using a combined serial loop construct, and
+! the outermost reduction clause is on that one, not the outermost loop.  */
+subroutine acc_serial_loop_reduction ()
+  implicit none (type, external)
+  integer :: h, i, j, k, sum, diff
+
+  !$acc serial loop reduction(+:sum)
+  ! implicit 'copy (sum, diff)'
+  ! { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+  ! { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 }
+  do h = 1, 10
+    do i = 1, 10
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    do i = 1, 10
+      !$acc loop
+      do j = 1, 10
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    do i = 1, 10
+      do j = 1, 10
+        !$acc loop
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)  ! { dg-warning "insufficient partitioning available to parallelize loop" }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum) reduction(-:diff)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)  ! { dg-warning "insufficient partitioning available to parallelize loop" }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop reduction(-:diff)  ! { dg-warning "insufficient partitioning available to parallelize loop" }
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)  ! { dg-warning "insufficient partitioning available to parallelize loop" }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop reduction(-:diff)  ! { dg-warning "insufficient partitioning available to parallelize loop" }
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(+:sum)  ! { dg-warning "insufficient partitioning available to parallelize loop" }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop  ! { dg-warning "insufficient partitioning available to parallelize loop" }
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+  end do
+end subroutine acc_serial_loop_reduction
diff --git a/gcc/testsuite/gfortran.dg/goacc/nested-reductions-2-serial.f90 b/gcc/testsuite/gfortran.dg/goacc/nested-reductions-2-serial.f90
new file mode 100644
index 0000000000000000000000000000000000000000..8c927ac63cade41076fb6f49c1ad225aa5f40ef9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/nested-reductions-2-serial.f90
@@ -0,0 +1,513 @@
+! Test erroneous cases of nested 'reduction' clauses.
+
+! See also 'c-c++-common/goacc/nested-reductions-2-serial.c'.
+
+! { dg-additional-options -Wuninitialized }
+
+subroutine acc_serial ()
+  implicit none (type, external)
+  integer :: i, j, k, l, sum, diff
+
+  !$acc serial
+  ! implicit 'copy (sum, diff)'
+  ! { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+  ! { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 }
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop collapse(2)  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      do j = 1, 10
+        do k = 1, 10
+          !$acc loop reduction(+:sum)
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      do j = 1, 10
+        !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(+:sum)
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      do j = 1, 10
+        !$acc loop reduction(-:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      do j = 1, 10
+        !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(*:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(*:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum) reduction(-:diff)
+    do i = 1, 10
+      !$acc loop reduction(-:diff)  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop reduction(+:sum)  ! { dg-warning "nested loop in reduction needs reduction clause for .diff." }
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+  !$acc end serial
+end subroutine acc_serial
+
+! The same tests as above, but using a combined serial loop construct.
+
+subroutine acc_serial_loop ()
+  implicit none (type, external)
+  integer :: h, i, j, k, l, sum, diff
+
+  !$acc serial loop
+  ! implicit 'copy (sum, diff)'
+  ! { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+  ! { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 }
+  do h = 1, 10
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop collapse(2)  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        do k = 1, 10
+          !$acc loop reduction(+:sum)
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(+:sum)
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(-:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(*:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum)
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(*:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(+:sum) reduction(-:diff)
+    do i = 1, 10
+      !$acc loop reduction(-:diff)  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop reduction(+:sum)  ! { dg-warning "nested loop in reduction needs reduction clause for .diff." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+  end do
+end subroutine acc_serial_loop
+
+! The same tests as above, but now the outermost reduction clause is on
+! the serial region, not the outermost loop.
+
+subroutine acc_serial_reduction ()
+  implicit none (type, external)
+  integer :: i, j, k, l, sum, diff
+
+  !$acc serial reduction(+:sum)
+  ! implicit 'copy (sum, diff)'
+  ! { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+  ! { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 }
+    !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop collapse(2)  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      do j = 1, 10
+        do k = 1, 10
+          !$acc loop reduction(+:sum)
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      do j = 1, 10
+        !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(+:sum)
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      do j = 1, 10
+        !$acc loop reduction(-:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(max:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      do j = 1, 10
+        !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(*:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(max:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(*:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(-:diff)  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop reduction(-:diff)  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop reduction(+:sum)  ! { dg-warning "nested loop in reduction needs reduction clause for .diff." }
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+  !$acc end serial
+end subroutine acc_serial_reduction
+
+! The same tests as above, but using a combined serial loop construct, and
+! the outermost reduction clause is on that one, not the outermost loop.  */
+subroutine acc_serial_loop_reduction ()
+  implicit none (type, external)
+  integer :: h, i, j, k, l, sum, diff
+
+  !$acc serial loop reduction(+:sum)
+  ! implicit 'copy (sum, diff)'
+  ! { dg-warning {'sum' is used uninitialized} TODO { xfail *-*-* } .-2 }
+  ! { dg-warning {'diff' is used uninitialized} TODO { xfail *-*-* } .-3 }
+  do h = 1, 10
+    !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop collapse(2)  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        do k = 1, 10
+          !$acc loop reduction(+:sum)
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(+:sum)
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)  ! { dg-warning "conflicting reduction operations for .sum." }  
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(-:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(max:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(*:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(max:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+    do i = 1, 10
+      !$acc loop reduction(-:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+        ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+        do k = 1, 10
+          !$acc loop reduction(*:sum)  ! { dg-warning "conflicting reduction operations for .sum." }
+          do l = 1, 10
+            sum = 1
+          end do
+        end do
+      end do
+    end do
+
+    !$acc loop reduction(-:diff)  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+    do i = 1, 10
+      !$acc loop reduction(-:diff)  ! { dg-warning "nested loop in reduction needs reduction clause for .sum." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(+:sum)
+        do k = 1, 10
+          sum = 1
+        end do
+      end do
+
+      !$acc loop reduction(+:sum)  ! { dg-warning "nested loop in reduction needs reduction clause for .diff." }
+      ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do j = 1, 10
+        !$acc loop reduction(-:diff)
+        do k = 1, 10
+          diff = 1
+        end do
+      end do
+    end do
+  end do
+end subroutine acc_serial_loop_reduction
diff --git a/gcc/testsuite/gfortran.dg/goacc/nesting-fail-1.f95 b/gcc/testsuite/gfortran.dg/goacc/nesting-fail-1.f95
new file mode 100644
index 0000000000000000000000000000000000000000..9f981007e516379ff8587c53613ac370d437f787
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/nesting-fail-1.f95
@@ -0,0 +1,101 @@
+! { dg-do compile } 
+
+! The OpenACC specification allows nested compute constructs, but we don't
+! support that yet.  */
+
+program test
+  implicit none
+
+  integer :: i
+
+  !$acc parallel
+    !$acc kernels ! { dg-bogus ".kernels. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
+    !$acc end kernels
+  !$acc end parallel
+
+  !$acc parallel
+    !$acc parallel ! { dg-bogus ".parallel. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
+    !$acc end parallel
+  !$acc end parallel
+
+  !$acc parallel
+    !$acc serial ! { dg-bogus ".serial. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
+    !$acc end serial
+  !$acc end parallel
+
+  !$acc parallel
+    !$acc parallel ! { dg-bogus ".parallel. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
+    !$acc end parallel
+    !$acc kernels ! { dg-bogus ".kernels. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
+    !$acc end kernels
+    !$acc serial ! { dg-bogus ".serial. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
+    !$acc end serial
+  !$acc end parallel
+
+
+  !$acc kernels
+    !$acc kernels ! { dg-bogus ".kernels. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
+    !$acc end kernels
+  !$acc end kernels
+
+  !$acc kernels
+    !$acc parallel ! { dg-bogus ".parallel. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
+    !$acc end parallel
+  !$acc end kernels
+
+  !$acc kernels
+    !$acc serial ! { dg-bogus ".serial. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
+    !$acc end serial
+  !$acc end kernels
+
+  !$acc kernels
+    !$acc parallel ! { dg-bogus ".parallel. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
+    !$acc end parallel
+    !$acc kernels ! { dg-bogus ".kernels. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
+    !$acc end kernels
+    !$acc serial ! { dg-bogus ".serial. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
+    !$acc end serial
+  !$acc end kernels
+
+
+  !$acc serial
+    !$acc kernels ! { dg-bogus ".kernels. construct inside of .serial. region" "not implemented" { xfail *-*-* } }
+    !$acc end kernels
+  !$acc end serial
+
+  !$acc serial
+    !$acc parallel ! { dg-bogus ".parallel. construct inside of .serial. region" "not implemented" { xfail *-*-* } }
+    !$acc end parallel
+  !$acc end serial
+
+  !$acc serial
+    !$acc serial ! { dg-bogus ".serial. construct inside of .serial. region" "not implemented" { xfail *-*-* } }
+    !$acc end serial
+  !$acc end serial
+
+  !$acc serial
+    !$acc parallel ! { dg-bogus ".parallel. construct inside of .serial. region" "not implemented" { xfail *-*-* } }
+    !$acc end parallel
+    !$acc kernels ! { dg-bogus ".kernels. construct inside of .serial. region" "not implemented" { xfail *-*-* } }
+    !$acc end kernels
+    !$acc serial ! { dg-bogus ".serial. construct inside of .serial. region" "not implemented" { xfail *-*-* } }
+    !$acc end serial
+  !$acc end serial
+
+
+  !$acc parallel
+    !$acc data ! { dg-error ".data. construct inside of .parallel. region" }
+    !$acc end data
+  !$acc end parallel
+
+  !$acc kernels
+    !$acc data ! { dg-error ".data. construct inside of .kernels. region" }
+    !$acc end data
+  !$acc end kernels
+  
+  !$acc serial
+    !$acc data ! { dg-error ".data. construct inside of .serial. region" }
+    !$acc end data
+  !$acc end serial
+
+end program test
diff --git a/gcc/testsuite/gfortran.dg/goacc/parallel-kernels-regions.f95 b/gcc/testsuite/gfortran.dg/goacc/parallel-kernels-regions.f95
deleted file mode 100644
index 7d8fb928659708d604f32e5769a95ab58ebf2209..0000000000000000000000000000000000000000
--- a/gcc/testsuite/gfortran.dg/goacc/parallel-kernels-regions.f95
+++ /dev/null
@@ -1,55 +0,0 @@
-! { dg-do compile } 
-
-! OpenACC 2.0 allows nested parallel/kernels regions, but this is not yet
-! supported.
-
-program test
-  implicit none
-
-  integer :: i
-
-  !$acc parallel
-    !$acc kernels ! { dg-bogus ".kernels. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
-    !$acc end kernels
-  !$acc end parallel
-
-  !$acc parallel
-    !$acc parallel ! { dg-bogus ".parallel. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
-    !$acc end parallel
-  !$acc end parallel
-
-  !$acc parallel
-    !$acc parallel ! { dg-bogus ".parallel. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
-    !$acc end parallel
-    !$acc kernels ! { dg-bogus ".kernels. construct inside of .parallel. region" "not implemented" { xfail *-*-* } }
-    !$acc end kernels
-  !$acc end parallel
-
-  !$acc kernels
-    !$acc kernels ! { dg-bogus ".kernels. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
-    !$acc end kernels
-  !$acc end kernels
-
-  !$acc kernels
-    !$acc parallel ! { dg-bogus ".parallel. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
-    !$acc end parallel
-  !$acc end kernels
-
-  !$acc kernels
-    !$acc parallel ! { dg-bogus ".parallel. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
-    !$acc end parallel
-    !$acc kernels ! { dg-bogus ".kernels. construct inside of .kernels. region" "not implemented" { xfail *-*-* } }
-    !$acc end kernels
-  !$acc end kernels
-
-  !$acc parallel
-    !$acc data ! { dg-error ".data. construct inside of .parallel. region" }
-    !$acc end data
-  !$acc end parallel
-
-  !$acc kernels
-    !$acc data ! { dg-error ".data. construct inside of .kernels. region" }
-    !$acc end data
-  !$acc end kernels
-  
-end program test
diff --git a/gcc/testsuite/gfortran.dg/goacc/parameter.f95 b/gcc/testsuite/gfortran.dg/goacc/parameter.f95
index cbe67dba7889ef8fe430c3ddb0621345b95cb3fd..b5813386721748bede1ad95c31f703e368dbaa2a 100644
--- a/gcc/testsuite/gfortran.dg/goacc/parameter.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/parameter.f95
@@ -13,17 +13,28 @@ contains
     !$acc end data
     !$acc parallel private (a) ! { dg-error "not a variable" }
     !$acc end parallel
+    !$acc serial private (a) ! { dg-error "not a variable" }
+    !$acc end serial
     !$acc host_data use_device (a) ! { dg-error "not a variable" }
     !$acc end host_data
     !$acc parallel loop reduction(+:a) ! { dg-error "not a variable" }
     do i = 1,5
     enddo
     !$acc end parallel loop
+    !$acc serial loop reduction(+:a) ! { dg-error "not a variable" }
+    do i = 1,5
+    enddo
+    !$acc end serial loop
     !$acc parallel loop
     do i = 1,5
       !$acc cache (a) ! { dg-error "not a variable" }
     enddo
     !$acc end parallel loop
+    !$acc serial loop
+    do i = 1,5
+      !$acc cache (a) ! { dg-error "not a variable" }
+    enddo
+    !$acc end serial loop
     !$acc update device (a) ! { dg-error "not a variable" }
     !$acc update host (a) ! { dg-error "not a variable" }
     !$acc update self (a) ! { dg-error "not a variable" }
diff --git a/gcc/testsuite/gfortran.dg/goacc/pr71704.f90 b/gcc/testsuite/gfortran.dg/goacc/pr71704.f90
index 31724c8b046a1c410b3f1aa8a1430e87f30fef6d..8f15477e1d4f95d3e1e3f093171a3d7fa77d3d21 100644
--- a/gcc/testsuite/gfortran.dg/goacc/pr71704.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/pr71704.f90
@@ -41,6 +41,12 @@ real function f7 ()
   f7 = 1
 end
 
+real function f_serial ()
+!$acc serial
+!$acc end serial
+  f_serial = 1
+end
+
 real function f8 ()
 !$acc data
 !$acc end data
diff --git a/gcc/testsuite/gfortran.dg/goacc/private-3.f95 b/gcc/testsuite/gfortran.dg/goacc/private-3.f95
index 1bfb4f1554de300aa8fa289342f454f59216e774..9056403a91f2ee56e23e02602e2c534cc50cd3d2 100644
--- a/gcc/testsuite/gfortran.dg/goacc/private-3.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/private-3.f95
@@ -23,4 +23,21 @@ program test
      k = k + 1
   end do
   !$acc end parallel
+
+
+!  !$acc serial private (k) reduction (+:k)
+!  do i = 1, n
+!     k = k + 1
+!  end do
+!  !$acc end serial
+
+  !$acc serial private (k)
+  k = 0
+  !$acc loop reduction (+:k)
+  ! { dg-note {variable 'i' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} "" { target *-*-* } .-1 }
+  do i = 1, n
+     k = k + 1
+  end do
+  !$acc end serial
+
 end program test
diff --git a/gcc/testsuite/gfortran.dg/goacc/private-explicit-serial-1.f95 b/gcc/testsuite/gfortran.dg/goacc/private-explicit-serial-1.f95
new file mode 100644
index 0000000000000000000000000000000000000000..56b14c7791178b13a300506a8f98689a0c9c2159
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/private-explicit-serial-1.f95
@@ -0,0 +1,247 @@
+! Explicit 'private' clauses related to 'do' loops inside an OpenACC
+! 'serial' construct.
+
+! { dg-additional-options "-fdump-tree-original -fdump-tree-gimple" }
+
+! (The 'independent' clauses are used as end of directive markers in tree dump
+! scanning.)
+
+program test
+  implicit none
+  integer :: i0_1
+  integer :: i0_2, j0_2
+  integer :: i1_s
+  integer :: i1_c
+  integer :: i2_1_s, j2_1_s
+  integer :: i2_1_c, j2_1_c
+  integer :: i2_2_s, j2_2_s
+  integer :: i2_3_s, j2_3_s
+  integer :: i2_3_c, j2_3_c
+  integer :: i3_1_s, j3_1_s, k3_1_s
+  integer :: i3_1_c, j3_1_c, k3_1_c
+  integer :: i3_2_s, j3_2_s, k3_2_s
+  integer :: i3_2_c, j3_2_c, k3_2_c
+  integer :: i3_3_s, j3_3_s, k3_3_s
+  integer :: i3_3_c, j3_3_c, k3_3_c
+  integer :: i3_4_s, j3_4_s, k3_4_s
+  integer :: i3_4_c, j3_4_c, k3_4_c
+  integer :: i3_5_s, j3_5_s, k3_5_s
+
+  !$acc serial private(i0_1)
+  ! { dg-final { scan-tree-dump-times "#pragma acc serial private\\(i0_1\\)" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma omp target oacc_serial private\\(i0_1\\)" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "firstprivate\\(i0_1\\)" 0 "gimple" } }
+  do i0_1 = 1, 100
+  end do
+  !$acc end serial
+
+  !$acc serial private(i0_2, j0_2)
+  ! { dg-final { scan-tree-dump-times "#pragma acc serial private\\(i0_2\\) private\\(j0_2\\)" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma omp target oacc_serial private\\(i0_2\\) private\\(j0_2\\)" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "firstprivate\\(i0_2\\)" 0 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "firstprivate\\(j0_2\\)" 0 "gimple" } }
+  do i0_2 = 1, 100
+     do j0_2 = 1, 100
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial
+  !$acc loop private(i1_s) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i1_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i1_s\\) independent" 1 "gimple" } }
+  do i1_s = 1, 100
+  end do
+  !$acc end serial
+
+  !$acc serial loop private(i1_c) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i1_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i1_c\\) independent" 1 "gimple" } }
+  do i1_c = 1, 100
+  end do
+
+  !$acc serial
+  !$acc loop private(i2_1_s, j2_1_s) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_1_s\\) private\\(j2_1_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_1_s\\) private\\(j2_1_s\\) independent" 1 "gimple" } }
+  do i2_1_s = 1, 100
+     do j2_1_s = 1, 100
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop private(i2_1_c, j2_1_c) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_1_c\\) private\\(j2_1_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_1_c\\) private\\(j2_1_c\\) independent" 1 "gimple" } }
+  do i2_1_c = 1, 100
+     do j2_1_c = 1, 100
+     end do
+  end do
+
+  !$acc serial private(i2_2_s)
+  ! { dg-final { scan-tree-dump-times "#pragma acc serial private\\(i2_2_s\\)" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma omp target oacc_serial private\\(i2_2_s\\)" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "firstprivate\\(i2_2_s\\)" 0 "gimple" } }
+  do i2_2_s = 1, 100
+     !$acc loop private(j2_2_s) independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_2_s\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_2_s\\) independent" 1 "gimple" } }
+     do j2_2_s = 1, 100
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial
+  !$acc loop private(i2_3_s) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_3_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_3_s\\) independent" 1 "gimple" } }
+  do i2_3_s = 1, 100
+     !$acc loop private(j2_3_s) independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_3_s\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_3_s\\) independent" 1 "gimple" } }
+     do j2_3_s = 1, 100
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop private(i2_3_c) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_3_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_3_c\\) independent" 1 "gimple" } }
+  do i2_3_c = 1, 100
+     !$acc loop private(j2_3_c) independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_3_c\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_3_c\\) independent" 1 "gimple" } }
+     do j2_3_c = 1, 100
+     end do
+  end do
+
+  !$acc serial
+  !$acc loop private(i3_1_s, j3_1_s, k3_1_s) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_1_s\\) private\\(j3_1_s\\) private\\(k3_1_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_1_s\\) private\\(j3_1_s\\) private\\(k3_1_s\\) independent" 1 "gimple" } }
+  do i3_1_s = 1, 100
+     do j3_1_s = 1, 100
+        do k3_1_s = 1, 100
+        end do
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop private(i3_1_c, j3_1_c, k3_1_c) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_1_c\\) private\\(j3_1_c\\) private\\(k3_1_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_1_c\\) private\\(j3_1_c\\) private\\(k3_1_c\\) independent" 1 "gimple" } }
+  do i3_1_c = 1, 100
+     do j3_1_c = 1, 100
+        do k3_1_c = 1, 100
+        end do
+     end do
+  end do
+
+  !$acc serial
+  !$acc loop private(i3_2_s) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_2_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_2_s\\) independent" 1 "gimple" } }
+  do i3_2_s = 1, 100
+     !$acc loop private(j3_2_s, k3_2_s) independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_2_s\\) private\\(k3_2_s\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_2_s\\) private\\(k3_2_s\\) independent" 1 "gimple" } }
+     do j3_2_s = 1, 100
+        do k3_2_s = 1, 100
+        end do
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop private(i3_2_c) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_2_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_2_c\\) independent" 1 "gimple" } }
+  do i3_2_c = 1, 100
+     !$acc loop private(j3_2_c, k3_2_c) independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_2_c\\) private\\(k3_2_c\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_2_c\\) private\\(k3_2_c\\) independent" 1 "gimple" } }
+     do j3_2_c = 1, 100
+        do k3_2_c = 1, 100
+        end do
+     end do
+  end do
+
+  !$acc serial
+  !$acc loop private(i3_3_s, j3_3_s) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_3_s\\) private\\(j3_3_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_3_s\\) private\\(j3_3_s\\) independent" 1 "gimple" } }
+  do i3_3_s = 1, 100
+     do j3_3_s = 1, 100
+        !$acc loop private(k3_3_s) independent
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_3_s\\) independent" 1 "original" } }
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_3_s\\) independent" 1 "gimple" } }
+        do k3_3_s = 1, 100
+        end do
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop private(i3_3_c, j3_3_c) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_3_c\\) private\\(j3_3_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_3_c\\) private\\(j3_3_c\\) independent" 1 "gimple" } }
+  do i3_3_c = 1, 100
+     do j3_3_c = 1, 100
+        !$acc loop private(k3_3_c) independent
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_3_c\\) independent" 1 "original" } }
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_3_c\\) independent" 1 "gimple" } }
+        do k3_3_c = 1, 100
+        end do
+     end do
+  end do
+
+  !$acc serial
+  !$acc loop private(i3_4_s) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_4_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_4_s\\) independent" 1 "gimple" } }
+  do i3_4_s = 1, 100
+     !$acc loop private(j3_4_s) independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_4_s\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_4_s\\) independent" 1 "gimple" } }
+     do j3_4_s = 1, 100
+        !$acc loop private(k3_4_s) independent
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_4_s\\) independent" 1 "original" } }
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_4_s\\) independent" 1 "gimple" } }
+        do k3_4_s = 1, 100
+        end do
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop private(i3_4_c) independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_4_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_4_c\\) independent" 1 "gimple" } }
+  do i3_4_c = 1, 100
+     !$acc loop private(j3_4_c) independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_4_c\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_4_c\\) independent" 1 "gimple" } }
+     do j3_4_c = 1, 100
+        !$acc loop private(k3_4_c) independent
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_4_c\\) independent" 1 "original" } }
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_4_c\\) independent" 1 "gimple" } }
+        do k3_4_c = 1, 100
+        end do
+     end do
+  end do
+
+  !$acc serial private(i3_5_s)
+  ! { dg-final { scan-tree-dump-times "#pragma acc serial private\\(i3_5_s\\)" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma omp target oacc_serial private\\(i3_5_s\\)" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "firstprivate\\(i3_5_s\\)" 0 "gimple" } }
+  do i3_5_s = 1, 100
+     !$acc loop private(j3_5_s) independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_5_s\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_5_s\\) independent" 1 "gimple" } }
+     do j3_5_s = 1, 100
+        !$acc loop private(k3_5_s) independent
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_5_s\\) independent" 1 "original" } }
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_5_s\\) independent" 1 "gimple" } }
+        do k3_5_s = 1, 100
+        end do
+     end do
+  end do
+  !$acc end serial
+end program test
diff --git a/gcc/testsuite/gfortran.dg/goacc/private-predetermined-serial-1.f95 b/gcc/testsuite/gfortran.dg/goacc/private-predetermined-serial-1.f95
new file mode 100644
index 0000000000000000000000000000000000000000..5379ac6d6c87f46fd778a8e637cbfe27fa3daf86
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/private-predetermined-serial-1.f95
@@ -0,0 +1,253 @@
+! Predetermined 'private' clauses related to 'do' loops inside an OpenACC
+! 'serial' construct.
+
+! { dg-additional-options "-fdump-tree-original -fdump-tree-gimple" }
+
+! (The 'independent' clauses are used as end of directive markers in tree dump
+! scanning.)
+
+program test
+  implicit none
+  integer :: i0_1
+  integer :: i0_2, j0_2
+  integer :: i1_s
+  integer :: i1_c
+  integer :: i2_1_s, j2_1_s
+  integer :: i2_1_c, j2_1_c
+  integer :: i2_2_s, j2_2_s
+  integer :: i2_3_s, j2_3_s
+  integer :: i2_3_c, j2_3_c
+  integer :: i3_1_s, j3_1_s, k3_1_s
+  integer :: i3_1_c, j3_1_c, k3_1_c
+  integer :: i3_2_s, j3_2_s, k3_2_s
+  integer :: i3_2_c, j3_2_c, k3_2_c
+  integer :: i3_3_s, j3_3_s, k3_3_s
+  integer :: i3_3_c, j3_3_c, k3_3_c
+  integer :: i3_4_s, j3_4_s, k3_4_s
+  integer :: i3_4_c, j3_4_c, k3_4_c
+  integer :: i3_5_s, j3_5_s, k3_5_s
+
+  !$acc serial
+  ! { dg-final { scan-tree-dump-times "private\\(i0_1\\)" 1 "original" { xfail *-*-* } } } ! PR90067
+  ! { dg-final { scan-tree-dump-times "private\\(i0_1\\)" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "firstprivate\\(i0_1\\)" 0 "gimple" { xfail *-*-* } } } ! PR90067
+  ! { dg-final { scan-tree-dump-times "#pragma omp target oacc_serial firstprivate\\(i0_1\\)" 0 "gimple" { xfail *-*-* } } } ! PR90067
+  do i0_1 = 1, 100
+  end do
+  !$acc end serial
+
+  !$acc serial
+  ! { dg-final { scan-tree-dump-times "private\\(i0_2\\)" 1 "original" { xfail *-*-* } } } ! PR90067
+  ! { dg-final { scan-tree-dump-times "private\\(j0_2\\)" 1 "original" { xfail *-*-* } } } ! PR90067
+  ! { dg-final { scan-tree-dump-times "private\\(i0_2\\)" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "private\\(j0_2\\)" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "firstprivate\\(i0_2\\)" 0 "gimple" { xfail *-*-* } } } ! PR90067
+  ! { dg-final { scan-tree-dump-times "firstprivate\\(j0_2\\)" 0 "gimple" { xfail *-*-* } } } ! PR90067
+  ! { dg-final { scan-tree-dump-times "#pragma omp target oacc_serial firstprivate\\(j0_2\\) firstprivate\\(i0_2\\)" 0 "gimple" { xfail *-*-* } } } ! PR90067
+  do i0_2 = 1, 100
+     do j0_2 = 1, 100
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial
+  !$acc loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i1_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i1_s\\) independent" 1 "gimple" } }
+  do i1_s = 1, 100
+  end do
+  !$acc end serial
+
+  !$acc serial loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i1_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i1_c\\) independent" 1 "gimple" } }
+  do i1_c = 1, 100
+  end do
+
+  !$acc serial
+  !$acc loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_1_s\\) private\\(j2_1_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_1_s\\) private\\(j2_1_s\\) independent" 1 "gimple" } }
+  do i2_1_s = 1, 100
+     do j2_1_s = 1, 100
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_1_c\\) private\\(j2_1_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_1_c\\) private\\(j2_1_c\\) independent" 1 "gimple" } }
+  do i2_1_c = 1, 100
+     do j2_1_c = 1, 100
+     end do
+  end do
+
+  !$acc serial
+  ! { dg-final { scan-tree-dump-times "private\\(i2_2_s\\)" 1 "original" { xfail *-*-* } } } ! PR90067
+  ! { dg-final { scan-tree-dump-times "private\\(i2_2_s\\)" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "firstprivate\\(i2_2_s\\)" 0 "gimple" { xfail *-*-* } } } ! PR90067
+  ! { dg-final { scan-tree-dump-times "#pragma omp target oacc_serial firstprivate\\(i2_2_s\\)" 0 "gimple" { xfail *-*-* } } } ! PR90067
+  do i2_2_s = 1, 100
+     !$acc loop independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_2_s\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_2_s\\) independent" 1 "gimple" } }
+     do j2_2_s = 1, 100
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial
+  !$acc loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_3_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_3_s\\) independent" 1 "gimple" } }
+  do i2_3_s = 1, 100
+     !$acc loop independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_3_s\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_3_s\\) independent" 1 "gimple" } }
+     do j2_3_s = 1, 100
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_3_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i2_3_c\\) independent" 1 "gimple" } }
+  do i2_3_c = 1, 100
+     !$acc loop independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_3_c\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j2_3_c\\) independent" 1 "gimple" } }
+     do j2_3_c = 1, 100
+     end do
+  end do
+
+  !$acc serial
+  !$acc loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_1_s\\) private\\(j3_1_s\\) private\\(k3_1_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_1_s\\) private\\(j3_1_s\\) private\\(k3_1_s\\) independent" 1 "gimple" } }
+  do i3_1_s = 1, 100
+     do j3_1_s = 1, 100
+        do k3_1_s = 1, 100
+        end do
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_1_c\\) private\\(j3_1_c\\) private\\(k3_1_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_1_c\\) private\\(j3_1_c\\) private\\(k3_1_c\\) independent" 1 "gimple" } }
+  do i3_1_c = 1, 100
+     do j3_1_c = 1, 100
+        do k3_1_c = 1, 100
+        end do
+     end do
+  end do
+
+  !$acc serial
+  !$acc loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_2_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_2_s\\) independent" 1 "gimple" } }
+  do i3_2_s = 1, 100
+     !$acc loop independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_2_s\\) private\\(k3_2_s\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_2_s\\) private\\(k3_2_s\\) independent" 1 "gimple" } }
+     do j3_2_s = 1, 100
+        do k3_2_s = 1, 100
+        end do
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_2_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_2_c\\) independent" 1 "gimple" } }
+  do i3_2_c = 1, 100
+     !$acc loop independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_2_c\\) private\\(k3_2_c\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_2_c\\) private\\(k3_2_c\\) independent" 1 "gimple" } }
+     do j3_2_c = 1, 100
+        do k3_2_c = 1, 100
+        end do
+     end do
+  end do
+
+  !$acc serial
+  !$acc loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_3_s\\) private\\(j3_3_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_3_s\\) private\\(j3_3_s\\) independent" 1 "gimple" } }
+  do i3_3_s = 1, 100
+     do j3_3_s = 1, 100
+        !$acc loop independent
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_3_s\\) independent" 1 "original" } }
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_3_s\\) independent" 1 "gimple" } }
+        do k3_3_s = 1, 100
+        end do
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_3_c\\) private\\(j3_3_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_3_c\\) private\\(j3_3_c\\) independent" 1 "gimple" } }
+  do i3_3_c = 1, 100
+     do j3_3_c = 1, 100
+        !$acc loop independent
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_3_c\\) independent" 1 "original" } }
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_3_c\\) independent" 1 "gimple" } }
+        do k3_3_c = 1, 100
+        end do
+     end do
+  end do
+
+  !$acc serial
+  !$acc loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_4_s\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_4_s\\) independent" 1 "gimple" } }
+  do i3_4_s = 1, 100
+     !$acc loop independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_4_s\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_4_s\\) independent" 1 "gimple" } }
+     do j3_4_s = 1, 100
+        !$acc loop independent
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_4_s\\) independent" 1 "original" } }
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_4_s\\) independent" 1 "gimple" } }
+        do k3_4_s = 1, 100
+        end do
+     end do
+  end do
+  !$acc end serial
+
+  !$acc serial loop independent
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_4_c\\) independent" 1 "original" } }
+  ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(i3_4_c\\) independent" 1 "gimple" } }
+  do i3_4_c = 1, 100
+     !$acc loop independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_4_c\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_4_c\\) independent" 1 "gimple" } }
+     do j3_4_c = 1, 100
+        !$acc loop independent
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_4_c\\) independent" 1 "original" } }
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_4_c\\) independent" 1 "gimple" } }
+        do k3_4_c = 1, 100
+        end do
+     end do
+  end do
+
+  !$acc serial
+  ! { dg-final { scan-tree-dump-times "private\\(i3_5_s\\)" 1 "original" { xfail *-*-* } } } ! PR90067
+  ! { dg-final { scan-tree-dump-times "private\\(i3_5_s\\)" 1 "gimple" } }
+  ! { dg-final { scan-tree-dump-times "firstprivate\\(i3_5_s\\)" 0 "gimple" { xfail *-*-* } } } ! PR90067
+  ! { dg-final { scan-tree-dump-times "#pragma omp target oacc_serial firstprivate\\(i3_5_s\\)" 0 "gimple" { xfail *-*-* } } } ! PR90067
+  do i3_5_s = 1, 100
+     !$acc loop independent
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_5_s\\) independent" 1 "original" } }
+     ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(j3_5_s\\) independent" 1 "gimple" } }
+     do j3_5_s = 1, 100
+        !$acc loop independent
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_5_s\\) independent" 1 "original" } }
+        ! { dg-final { scan-tree-dump-times "#pragma acc loop private\\(k3_5_s\\) independent" 1 "gimple" } }
+        do k3_5_s = 1, 100
+        end do
+     end do
+  end do
+  !$acc end serial
+end program test
diff --git a/gcc/testsuite/gfortran.dg/goacc/pure-elemental-procedures.f95 b/gcc/testsuite/gfortran.dg/goacc/pure-elemental-procedures.f95
index 726e8e98b22e7947576fbcdda52cd9378208a042..b30d4f07903d8ebb1b22eb080eb275162b15ee31 100644
--- a/gcc/testsuite/gfortran.dg/goacc/pure-elemental-procedures.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/pure-elemental-procedures.f95
@@ -6,22 +6,26 @@ module test
 contains
   elemental subroutine test1
     !$acc parallel ! { dg-error "may not appear in PURE procedures" }
+    !$acc serial ! { dg-error "may not appear in PURE procedures" }
   end subroutine test1
 
   pure subroutine test2
     !$acc parallel ! { dg-error "may not appear in PURE procedures" }
+    !$acc serial ! { dg-error "may not appear in PURE procedures" }
   end subroutine test2
 
   ! Implicit pure
   elemental real function test3(x)
     real, intent(in) :: x
     !$acc parallel ! { dg-error "may not appear in PURE procedures" }
+    !$acc serial ! { dg-error "may not appear in PURE procedures" }
     test3 = x*x
   end function test3
 
   pure real function test4(x)
     real, intent(in) :: x
     !$acc parallel ! { dg-error "may not appear in PURE procedures" }
+    !$acc serial ! { dg-error "may not appear in PURE procedures" }
     test4 = x
   end function test4
 
@@ -32,6 +36,10 @@ contains
     do i = 1,10
       x = x + 0.3
     enddo
+    !$acc serial loop collapse(1) reduction(+:x)
+    do i = 1,10
+      x = x + 0.3
+    enddo
     print *, x
   end subroutine test5
 
@@ -42,6 +50,10 @@ contains
     do i = 1,10
       x = x + 0.3
     enddo
+    !$acc serial loop collapse(1) reduction(+:x)
+    do i = 1,10
+      x = x + 0.3
+    enddo
     test6 = x
   end function test6
 
@@ -50,6 +62,9 @@ contains
     !$acc parallel 
     test7 = x
     !$acc end parallel
+    !$acc serial 
+    test7 = x
+    !$acc end serial
   end function test7
 
   subroutine test8
@@ -61,6 +76,12 @@ contains
         x = x + 0.3
       end critical
     enddo
+    !$acc serial loop collapse(1) reduction(+:x)
+    do i = 1,10
+      critical ! { dg-error "CRITICAL block inside of" }
+        x = x + 0.3
+      end critical
+    enddo
     print *, x
   end subroutine test8
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/reduction-2.f95 b/gcc/testsuite/gfortran.dg/goacc/reduction-2.f95
index 4d40998958c9eff0db1a804811c0c030daadd00b..a1f6500551de3ca0c488475796767141f84736dc 100644
--- a/gcc/testsuite/gfortran.dg/goacc/reduction-2.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/reduction-2.f95
@@ -1,22 +1,34 @@
 ! { dg-do compile } 
 ! { dg-additional-options "-fdump-tree-gimple" }
 
+! See also '../../c-c++-common/goacc/combined-reduction.c'.
+
 subroutine foo ()
   implicit none
-  integer :: p,k
+  integer :: p, k, s
   integer  :: a
+
   !$acc parallel loop reduction(+:a)
   do p = 1,5
   enddo
   !$acc end parallel loop
+
   !$acc kernels loop reduction(+:a)
   do k = 2,6
   enddo
   !$acc end kernels loop
+
+  !$acc serial loop reduction(+:a)
+  do s = 1,5
+  enddo
+  !$acc end serial loop
+
 end subroutine
 
 ! { dg-final { scan-tree-dump-times "target oacc_parallel reduction..:a. map.tofrom.a." 1 "gimple" } }
 ! { dg-final { scan-tree-dump-times "acc loop private.p. reduction..:a." 1 "gimple" } }
 ! { dg-final { scan-tree-dump-times "target oacc_kernels map.force_tofrom:a .len: 4.." 1 "gimple" } }
 ! { dg-final { scan-tree-dump-times "acc loop private.k. reduction..:a." 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "target oacc_serial reduction..:a. map.tofrom.a." 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "acc loop private.s. reduction..:a." 1 "gimple" } }
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/reduction-3.f95 b/gcc/testsuite/gfortran.dg/goacc/reduction-3.f95
index 72f0eb95a9861e23330d4f733a85f12b06c4d6c2..4acc9bdb4b9d16124f5bad78cb77f81c5ef281f4 100644
--- a/gcc/testsuite/gfortran.dg/goacc/reduction-3.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/reduction-3.f95
@@ -7,4 +7,10 @@ integer :: i1, i2
 !$acc end parallel
 !$acc parallel reduction (+:i2) firstprivate(i2) ! { dg-error "invalid private reduction on .i2." }
 !$acc end parallel
+
+!$acc serial reduction (+:i1) private(i1) ! { dg-error "invalid private reduction on .i1." }
+!$acc end serial
+!$acc serial reduction (+:i2) firstprivate(i2) ! { dg-error "invalid private reduction on .i2." }
+!$acc end serial
+
 end subroutine foo
diff --git a/gcc/testsuite/gfortran.dg/goacc/reduction-promotions.f90 b/gcc/testsuite/gfortran.dg/goacc/reduction-promotions.f90
index 1d247ca238e217314e87df600316ee1d03627397..71cd40271a3b5c359dde23e9c806eb5738e2070a 100644
--- a/gcc/testsuite/gfortran.dg/goacc/reduction-promotions.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/reduction-promotions.f90
@@ -36,9 +36,41 @@ program test
 
   !$acc parallel reduction(+:v1,v2) pcreate(v1,v2) ! { dg-warning "incompatible data clause" }
   !$acc end parallel
+
+
+  !$acc serial reduction(+:v1,v2)
+  !$acc end serial
+
+  !$acc serial reduction(+:v1,v2) copy(v1,v2)
+  !$acc end serial
+
+  !$acc serial reduction(+:v1,v2) pcopy(v1,v2)
+  !$acc end serial
+
+  !$acc serial reduction(+:v1,v2) present(v1,v2)
+  !$acc end serial
+
+  !$acc serial reduction(+:v1,v2) copyin(v1,v2) ! { dg-warning "incompatible data clause" }
+  !$acc end serial
+
+  !$acc serial reduction(+:v1,v2) pcopyin(v1,v2) ! { dg-warning "incompatible data clause" }
+  !$acc end serial
+
+  !$acc serial reduction(+:v1,v2) copyout(v1,v2) ! { dg-warning "incompatible data clause" }
+  !$acc end serial
+
+  !$acc serial reduction(+:v1,v2) pcopyout(v1,v2) ! { dg-warning "incompatible data clause" }
+  !$acc end serial
+
+  !$acc serial reduction(+:v1,v2) create(v1,v2) ! { dg-warning "incompatible data clause" }
+  !$acc end serial
+
+  !$acc serial reduction(+:v1,v2) pcreate(v1,v2) ! { dg-warning "incompatible data clause" }
+  !$acc end serial
+
 end program test
 
-! { dg-final { scan-tree-dump-times "map.tofrom:v1" 9 "gimple" } }
-! { dg-final { scan-tree-dump-times "map.tofrom:v2" 9 "gimple" } }
-! { dg-final { scan-tree-dump-times "map.force_present:v1" 1 "gimple" } }
-! { dg-final { scan-tree-dump-times "map.force_present:v2" 1 "gimple" } }
+! { dg-final { scan-tree-dump-times "map.tofrom:v1" 18 "gimple" } }
+! { dg-final { scan-tree-dump-times "map.tofrom:v2" 18 "gimple" } }
+! { dg-final { scan-tree-dump-times "map.force_present:v1" 2 "gimple" } }
+! { dg-final { scan-tree-dump-times "map.force_present:v2" 2 "gimple" } }
diff --git a/gcc/testsuite/gfortran.dg/goacc/reduction.f95 b/gcc/testsuite/gfortran.dg/goacc/reduction.f95
index aaa82980e16dea25c7a8d202f4b65f0f53213c1e..2d9a111645cc72c8047e5c9087cd00ccbbc98775 100644
--- a/gcc/testsuite/gfortran.dg/goacc/reduction.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/reduction.f95
@@ -1,5 +1,5 @@
 ! { dg-do compile } 
-! { dg-additional-options "-fmax-errors=100" } 
+! { dg-additional-options "-fmax-errors=0" } 
 
 subroutine foo (ia1)
 integer :: i1, i2, i3
@@ -157,4 +157,137 @@ common /blk/ i1
 ! { dg-error "Array 'ta1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
 !$acc end parallel
 
+!$acc serial reduction (+:ia2)
+! { dg-error "Array 'ia2' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (+:ra1)
+! { dg-error "Array 'ra1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (+:ca1)
+! { dg-error "Array 'ca1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (+:da1)
+! { dg-error "Array 'da1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (.and.:la1)
+! { dg-error "Array 'la1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (+:i3, r1, d1, c1)
+!$acc end serial
+!$acc serial reduction (*:i3, r1, d1, c1)
+!$acc end serial
+!$acc serial reduction (-:i3, r1, d1, c1)
+!$acc end serial
+!$acc serial reduction (.and.:l1)
+!$acc end serial
+!$acc serial reduction (.or.:l1)
+!$acc end serial
+!$acc serial reduction (.eqv.:l1)
+!$acc end serial
+!$acc serial reduction (.neqv.:l1)
+!$acc end serial
+!$acc serial reduction (min:i3, r1, d1)
+!$acc end serial
+!$acc serial reduction (max:i3, r1, d1)
+!$acc end serial
+!$acc serial reduction (iand:i3)
+!$acc end serial
+!$acc serial reduction (ior:i3)
+!$acc end serial
+!$acc serial reduction (ieor:i3)
+!$acc end serial
+!$acc serial reduction (+:/blk/)	! { dg-error "Syntax error" }
+!$acc end serial			! { dg-error "Unexpected" }
+!$acc serial reduction (*:p1)		! { dg-error "POINTER object" }
+!$acc end serial
+!$acc serial reduction (-:aa1)
+! { dg-error "Array 'aa1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (*:ia1)	! { dg-error "Assumed size" }
+! { dg-error "Array 'ia1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (+:l1)		! { dg-error "OMP DECLARE REDUCTION \\+ not found for type LOGICAL" }
+!$acc end serial
+!$acc serial reduction (*:la1)	! { dg-error "OMP DECLARE REDUCTION \\* not found for type LOGICAL" }
+! { dg-error "Array 'la1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (-:a1)		! { dg-error "OMP DECLARE REDUCTION - not found for type CHARACTER" }
+!$acc end serial
+!$acc serial reduction (+:t1)		! { dg-error "OMP DECLARE REDUCTION \\+ not found for type TYPE" }
+!$acc end serial
+!$acc serial reduction (*:ta1)	! { dg-error "OMP DECLARE REDUCTION \\* not found for type TYPE" }
+! { dg-error "Array 'ta1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (.and.:i3)	! { dg-error "OMP DECLARE REDUCTION \\.and\\. not found for type INTEGER" }
+!$acc end serial
+!$acc serial reduction (.or.:ia2)	! { dg-error "OMP DECLARE REDUCTION \\.or\\. not found for type INTEGER" }
+! { dg-error "Array 'ia2' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (.eqv.:r1)	! { dg-error "OMP DECLARE REDUCTION \\.eqv\\. not found for type REAL" }
+!$acc end serial
+!$acc serial reduction (.neqv.:ra1)	! { dg-error "OMP DECLARE REDUCTION \\.neqv\\. not found for type REAL" }
+! { dg-error "Array 'ra1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (.and.:d1)	! { dg-error "OMP DECLARE REDUCTION \\.and\\. not found for type REAL" }
+!$acc end serial
+!$acc serial reduction (.or.:da1)	! { dg-error "OMP DECLARE REDUCTION \\.or\\. not found for type REAL" }
+! { dg-error "Array 'da1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (.eqv.:c1)	! { dg-error "OMP DECLARE REDUCTION \\.eqv\\. not found for type COMPLEX" }
+!$acc end serial
+!$acc serial reduction (.neqv.:ca1)	! { dg-error "OMP DECLARE REDUCTION \\.neqv\\. not found for type COMPLEX" }
+! { dg-error "Array 'ca1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (.and.:a1)	! { dg-error "OMP DECLARE REDUCTION \\.and\\. not found for type CHARACTER" }
+!$acc end serial
+!$acc serial reduction (.or.:t1)	! { dg-error "OMP DECLARE REDUCTION \\.or\\. not found for type TYPE" }
+!$acc end serial
+!$acc serial reduction (.eqv.:ta1)	! { dg-error "OMP DECLARE REDUCTION \\.eqv\\. not found for type TYPE" }
+! { dg-error "Array 'ta1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (min:c1)	! { dg-error "OMP DECLARE REDUCTION min not found for type COMPLEX" }
+!$acc end serial
+!$acc serial reduction (max:ca1)	! { dg-error "OMP DECLARE REDUCTION max not found for type COMPLEX" }
+! { dg-error "Array 'ca1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (max:l1)	! { dg-error "OMP DECLARE REDUCTION max not found for type LOGICAL" }
+!$acc end serial
+!$acc serial reduction (min:la1)	! { dg-error "OMP DECLARE REDUCTION min not found for type LOGICAL" }
+! { dg-error "Array 'la1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (max:a1)	! { dg-error "OMP DECLARE REDUCTION max not found for type CHARACTER" }
+!$acc end serial
+!$acc serial reduction (min:t1)	! { dg-error "OMP DECLARE REDUCTION min not found for type TYPE" }
+!$acc end serial
+!$acc serial reduction (max:ta1)	! { dg-error "OMP DECLARE REDUCTION max not found for type TYPE" }
+! { dg-error "Array 'ta1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (iand:r1)	! { dg-error "OMP DECLARE REDUCTION iand not found for type REAL" }
+!$acc end serial
+!$acc serial reduction (ior:ra1)	! { dg-error "OMP DECLARE REDUCTION ior not found for type REAL" }
+! { dg-error "Array 'ra1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (ieor:d1)	! { dg-error "OMP DECLARE REDUCTION ieor not found for type REAL" }
+!$acc end serial
+!$acc serial reduction (ior:da1)	! { dg-error "OMP DECLARE REDUCTION ior not found for type REAL" }
+! { dg-error "Array 'da1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (iand:c1)	! { dg-error "OMP DECLARE REDUCTION iand not found for type COMPLEX" }
+!$acc end serial
+!$acc serial reduction (ior:ca1)	! { dg-error "OMP DECLARE REDUCTION ior not found for type COMPLEX" }
+! { dg-error "Array 'ca1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (ieor:l1)	! { dg-error "OMP DECLARE REDUCTION ieor not found for type LOGICAL" }
+!$acc end serial
+!$acc serial reduction (iand:la1)	! { dg-error "OMP DECLARE REDUCTION iand not found for type LOGICAL" }
+! { dg-error "Array 'la1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+!$acc serial reduction (ior:a1)	! { dg-error "OMP DECLARE REDUCTION ior not found for type CHARACTER" }
+!$acc end serial
+!$acc serial reduction (ieor:t1)	! { dg-error "OMP DECLARE REDUCTION ieor not found for type TYPE" }
+!$acc end serial
+!$acc serial reduction (iand:ta1)	! { dg-error "OMP DECLARE REDUCTION iand not found for type TYPE" }
+! { dg-error "Array 'ta1' is not permitted in reduction" "" { target "*-*-*" } .-1 }
+!$acc end serial
+
 end subroutine
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-3.f90 b/gcc/testsuite/gfortran.dg/goacc/routine-3.f90
index 6773f62f0f45d79df336d79767638f9144396a83..fe11c76daa0a84c981ba5a72d3306162bf0d859c 100644
--- a/gcc/testsuite/gfortran.dg/goacc/routine-3.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-3.f90
@@ -15,5 +15,12 @@ CONTAINS
        un(i) = ua(i)
     END DO
     !$acc end parallel
+
+    !$acc serial
+    DO jj = 1, 100
+       un(i) = ua(i)
+    END DO
+    !$acc end serial
+
   END SUBROUTINE gwv
 END PROGRAM nested_gwv
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-1.f b/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-1-parallel.f
similarity index 99%
rename from gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-1.f
rename to gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-1-parallel.f
index c27fe7924ed51b7597642ddd4be1aa9ec0dc8fcc..cd5240ba4486fedfbc8b55f6e8d64c2898363bec 100644
--- a/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-1.f
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-1-parallel.f
@@ -1,4 +1,5 @@
-! Check valid calls to 'external' OpenACC routines.
+! Check valid calls to 'external' OpenACC routines from OpenACC
+! 'parallel' constructs.
 
 ! { dg-additional-options "-fopt-info-optimized-omp" }
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-1-serial.f b/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-1-serial.f
new file mode 100644
index 0000000000000000000000000000000000000000..df0bd10f3df97ca971f426fb3096a88f526997ca
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-1-serial.f
@@ -0,0 +1,348 @@
+! Check valid calls to 'external' OpenACC routines from OpenACC
+! 'serial' constructs.
+
+! { dg-additional-options "-fopt-info-optimized-omp" }
+
+      subroutine sub
+      implicit none
+      integer, parameter :: n = 100
+      integer :: a(n), i, j
+      external :: gangr, workerr, vectorr, seqr
+!$acc routine (gangr) gang
+!$acc routine (workerr) worker
+!$acc routine (vectorr) vector
+!$acc routine (seqr) seq
+
+!
+! Test subroutine calls inside nested loops.
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+!$acc loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+         do j = 1, n
+            call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+         end do
+      end do
+!$acc end serial loop
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do i = 1, n
+!$acc loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+         do j = 1, n
+            call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+         end do
+      end do
+!$acc end serial loop
+
+!
+! Test calls to seq routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang vector loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to gang routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do i = 1, n
+         call gangr (a, n) ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         call gangr (a, n) ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to worker routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to vector routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang worker loop parallelism" }
+      do i = 1, n
+         call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+      end subroutine sub
+
+      subroutine func
+      implicit none
+      integer, parameter :: n = 100
+      integer :: a(n), i, j
+      integer, external :: gangf, workerf, vectorf, seqf
+!$acc routine (gangf) gang
+!$acc routine (workerf) worker
+!$acc routine (vectorf) vector
+!$acc routine (seqf) seq
+
+!
+! Test subroutine calls inside nested loops.
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+!$acc loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+         do j = 1, n
+            a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+         end do
+      end do
+!$acc end serial loop
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do i = 1, n
+!$acc loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+         do j = 1, n
+            a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+         end do
+      end do
+!$acc end serial loop
+
+!
+! Test calls to seq routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang vector loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to gang routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do i = 1, n
+         a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to worker routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to vector routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang worker loop parallelism" }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+      end subroutine func
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-2.f b/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-2-parallel.f
similarity index 99%
rename from gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-2.f
rename to gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-2-parallel.f
index 35f67cbd0b873e364fa941d57521d45c2544b384..1bd15bec85949f84976aa0d744b994d03685d92f 100644
--- a/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-2.f
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-2-parallel.f
@@ -1,4 +1,5 @@
-! Check invalid calls to 'external' OpenACC routines.
+! Check invalid calls to 'external' OpenACC routines from OpenACC
+! 'parallel' constructs.
 
 ! { dg-additional-options "-fopt-info-optimized-omp" }
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-2-serial.f b/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-2-serial.f
new file mode 100644
index 0000000000000000000000000000000000000000..879be364558316cd79dbfc04769002b45fe073f7
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-external-level-of-parallelism-2-serial.f
@@ -0,0 +1,392 @@
+! Check invalid calls to 'external' OpenACC routines from OpenACC
+! 'serial' constructs.
+
+! { dg-additional-options "-fopt-info-optimized-omp" }
+
+      subroutine sub
+      implicit none
+      integer, parameter :: n = 100
+      integer :: a(n), i, j
+      external :: gangr, workerr, vectorr, seqr
+! { dg-note "routine 'gangr' declared here" "" { target { ! offloading_enabled } } .-1 }
+! { dg-note "routine 'gangr_' declared here" "" { target offloading_enabled } .-2 }
+! { dg-note "routine 'workerr' declared here" "" { target { ! offloading_enabled } } .-3 }
+! { dg-note "routine 'workerr_' declared here" "" { target offloading_enabled } .-4 }
+! { dg-note "routine 'vectorr' declared here" "" { target { ! offloading_enabled } } .-5 }
+! { dg-note "routine 'vectorr_' declared here" "" { target offloading_enabled } .-6 }
+!TODO See PR101551 for 'offloading_enabled' differences.
+
+!$acc routine (gangr) gang
+!$acc routine (workerr) worker
+!$acc routine (vectorr) vector
+!$acc routine (seqr) seq
+
+!
+! Test subroutine calls inside nested loops.
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+!$acc loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+         do j = 1, n
+            call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+         end do
+      end do
+!$acc end serial loop
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do i = 1, n
+!$acc loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+         do j = 1, n
+            call gangr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+         end do
+      end do
+!$acc end serial loop
+
+!
+! Test calls to seq routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang vector loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         call seqr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to gang routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do i = 1, n
+         call gangr (a, n) ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         call gangr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         call gangr (a, n) ! { dg-message "optimized: assigned OpenACC gang vector loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         call gangr (a, n) ! { dg-message "optimized: assigned OpenACC gang worker loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         call gangr (a, n) ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to worker routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         call workerr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         call workerr (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to vector routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang worker loop parallelism" }
+      do i = 1, n
+         call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         call vectorr (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+      end subroutine sub
+
+      subroutine func
+      implicit none
+      integer, parameter :: n = 100
+      integer :: a(n), i, j
+      integer, external :: gangf, workerf, vectorf, seqf
+! { dg-note "routine 'gangf' declared here" "" { target { ! offloading_enabled } } .-1 }
+! { dg-note "routine 'gangf_' declared here" "" { target offloading_enabled } .-2 }
+! { dg-note "routine 'workerf' declared here" "" { target { ! offloading_enabled } } .-3 }
+! { dg-note "routine 'workerf_' declared here" "" { target offloading_enabled } .-4 }
+! { dg-note "routine 'vectorf' declared here" "" { target { ! offloading_enabled } } .-5 }
+! { dg-note "routine 'vectorf_' declared here" "" { target offloading_enabled } .-6 }
+!TODO See PR101551 for 'offloading_enabled' differences.
+
+!$acc routine (gangf) gang
+!$acc routine (workerf) worker
+!$acc routine (vectorf) vector
+!$acc routine (seqf) seq
+
+!
+! Test subroutine calls inside nested loops.
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+!$acc loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+         do j = 1, n
+            a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+         end do
+      end do
+!$acc end serial loop
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do i = 1, n
+!$acc loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+         do j = 1, n
+            a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+        end do
+      end do
+!$acc end serial loop
+
+!
+! Test calls to seq routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang vector loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         a(i) = seqf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to gang routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+      do i = 1, n
+         a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC gang vector loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC gang worker loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         a(i) = gangf (a, n) ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to worker routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         a(i) = workerf (a, n) ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!
+! Test calls to vector routines
+!
+
+!$acc serial loop ! { dg-message "optimized: assigned OpenACC gang worker loop parallelism" }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+
+!$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+! { dg-note "containing loop here" "" { target *-*-* } .-1 }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+! { dg-error "routine call uses same OpenACC parallelism as containing loop" "" { target *-*-* } .-1 }
+      end do
+!$acc end serial loop
+
+!$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+      do i = 1, n
+         a(i) = vectorf (a, n) ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+      end do
+!$acc end serial loop
+      end subroutine func
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-module-1.f90 b/gcc/testsuite/gfortran.dg/goacc/routine-module-1.f90
index 46eec3d748864b42f16ea9ea22c5ab7625f7fba4..efb884d4c1bbeb0580103aa39a5a23ad7fcc53b9 100644
--- a/gcc/testsuite/gfortran.dg/goacc/routine-module-1.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-module-1.f90
@@ -9,8 +9,12 @@ program main
 
   integer :: i
 
+
   call pl_1
 
+  call sl_1
+
+
   !$acc parallel loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
   do i = 1, 10
      call s_1 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
@@ -58,4 +62,54 @@ program main
      call s_2_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
   end do
   !$acc end parallel loop
+
+
+  !$acc serial loop seq ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+  do i = 1, 10
+     call s_1 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_1_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_2 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_2_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call g_1 ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+     call g_1_nh ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+     call w_1 ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+     call w_1_nh ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+     call v_1 ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+     call v_1_nh ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop gang ! { dg-message "optimized: assigned OpenACC gang loop parallelism" }
+  do i = 1, 10
+     call s_1 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_1_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_2 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_2_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call w_1 ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+     call w_1_nh ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+     call v_1 ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+     call v_1_nh ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop worker ! { dg-message "optimized: assigned OpenACC worker loop parallelism" }
+  do i = 1, 10
+     call s_1 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_1_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_2 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_2_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call v_1 ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+     call v_1_nh ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop vector ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+  do i = 1, 10
+     call s_1 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_1_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_2 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+     call s_2_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+  end do
+  !$acc end serial loop
+
 end program main
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-module-2.f90 b/gcc/testsuite/gfortran.dg/goacc/routine-module-2.f90
index e796c1da300499833f38c0bf9b2872d11eb5b921..a2e3b1f7f32f7986c03a71d2b1fe0f5852827aa7 100644
--- a/gcc/testsuite/gfortran.dg/goacc/routine-module-2.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-module-2.f90
@@ -8,6 +8,7 @@ program main
 
   integer :: i
 
+
   !$acc parallel loop gang
   do i = 1, 10
      call g_1 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
@@ -34,4 +35,33 @@ program main
      call v_1_nh ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
   end do
   !$acc end parallel loop
+
+
+  !$acc serial loop gang
+  do i = 1, 10
+     call g_1 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+     call g_1_nh ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop worker
+  do i = 1, 10
+     call g_1 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+     call g_1_nh ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+     call w_1 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+     call w_1_nh ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+  end do
+  !$acc end serial loop
+
+  !$acc serial loop vector
+  do i = 1, 10
+     call g_1 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+     call g_1_nh ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+     call w_1 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+     call w_1_nh ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+     call v_1 ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+     call v_1_nh ! { dg-error "routine call uses same OpenACC parallelism as containing loop" }
+  end do
+  !$acc end serial loop
+
 end program main
diff --git a/gcc/testsuite/gfortran.dg/goacc/routine-module-mod-1.f90 b/gcc/testsuite/gfortran.dg/goacc/routine-module-mod-1.f90
index 10e109675dcc399e86c3baa06c1c89722b8332d3..2dd961ceff3eb3db6e022e80c076ca99f0ae8580 100644
--- a/gcc/testsuite/gfortran.dg/goacc/routine-module-mod-1.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/routine-module-mod-1.f90
@@ -140,4 +140,29 @@ contains
        call g_1_nh ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
     end do
   end subroutine pl_1
+
+  subroutine sl_1
+    implicit none
+
+    integer :: i
+
+    !$acc serial loop ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+    ! { dg-warning "insufficient partitioning available to parallelize loop" "" { target *-*-* } .-1 }
+    ! { dg-warning "region contains gang partitioned code but is not gang partitioned" "" { target *-*-* } .-2 }
+    ! { dg-warning "region contains worker partitioned code but is not worker partitioned" "" { target *-*-* } .-3 }
+    ! { dg-warning "region contains vector partitioned code but is not vector partitioned" "" { target *-*-* } .-4 }
+    do i = 1, 3
+       call s_1 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+       call s_1_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+       call s_2 ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+       call s_2_nh ! { dg-message "optimized: assigned OpenACC seq loop parallelism" }
+       call v_1 ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+       call v_1_nh ! { dg-message "optimized: assigned OpenACC vector loop parallelism" }
+       call w_1 ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+       call w_1_nh ! { dg-message "optimized: assigned OpenACC worker vector loop parallelism" }
+       call g_1 ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+       call g_1_nh ! { dg-message "optimized: assigned OpenACC gang worker vector loop parallelism" }
+    end do
+  end subroutine sl_1
+
 end module routine_module_mod_1
diff --git a/gcc/testsuite/gfortran.dg/goacc/serial-tree.f95 b/gcc/testsuite/gfortran.dg/goacc/serial-tree.f95
new file mode 100644
index 0000000000000000000000000000000000000000..d9b787331958dd6c37af32a2c6ea242cfca797c5
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/goacc/serial-tree.f95
@@ -0,0 +1,45 @@
+! { dg-additional-options "-fdump-tree-original" }
+
+! test for tree-dump-original and spaces-commas
+
+! { dg-additional-options -Wuninitialized }
+
+! { dg-additional-options "-Wopenacc-parallelism" } for testing/documenting
+! aspects of that functionality.
+
+program test
+  implicit none
+  integer :: q, i, j, k, m, n, o, p, r, s, t, u, v, w
+  ! { dg-note {'i' was declared here} {} { xfail *-*-* } .-1 }
+  logical :: l = .true.
+
+  !$acc serial if(l) async &
+  !$acc self &
+  !$acc reduction(max:q), copy(i), copyin(j), copyout(k), create(m) &
+  !$acc no_create(n) &
+  !$acc present(o), pcopy(p), pcopyin(r), pcopyout(s), pcreate(t) &
+  !$acc deviceptr(u), private(v), firstprivate(w)
+  ! { dg-warning {'i' is used uninitialized} {} { xfail *-*-* } .-1 }
+  !$acc end serial
+
+end program test
+
+! { dg-final { scan-tree-dump-times "pragma acc serial" 1 "original" } } 
+
+! { dg-final { scan-tree-dump-times "if" 1 "original" } }
+! { dg-final { scan-tree-dump-times "async" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "self\\(1\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "reduction\\(max:q\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "map\\(tofrom:i\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "map\\(to:j\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "map\\(from:k\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "map\\(alloc:m\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "map\\(no_alloc:n\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "map\\(force_present:o\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "map\\(tofrom:p\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "map\\(to:r\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "map\\(from:s\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "map\\(alloc:t\\)" 1 "original" } } 
+
+! { dg-final { scan-tree-dump-times "map\\(force_deviceptr:u\\)" 1 "original" } } 
+! { dg-final { scan-tree-dump-times "private\\(v\\)" 1 "original" } } 
diff --git a/gcc/testsuite/gfortran.dg/goacc/sie.f95 b/gcc/testsuite/gfortran.dg/goacc/sie.f95
index 5982d5d229faccfc3927fc457bc63d737932ae24..78b4601004c79ff8428a4941aed31c8bef23d155 100644
--- a/gcc/testsuite/gfortran.dg/goacc/sie.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/sie.f95
@@ -66,6 +66,35 @@ program test
   !$acc kernels async("1") ! { dg-error "scalar INTEGER expression" }
   !$acc end kernels
 
+  !$acc serial async
+  !$acc end serial
+
+  !$acc serial async(3)
+  !$acc end serial
+
+  !$acc serial async(i)
+  !$acc end serial
+
+  !$acc serial async(i+1)
+  !$acc end serial
+
+  !$acc serial async(-1) 
+  !$acc end serial
+
+  !$acc serial async(0) 
+  !$acc end serial
+
+  !$acc serial async() ! { dg-error "Invalid character in name" }
+
+  !$acc serial async(1.5) ! { dg-error "scalar INTEGER expression" }
+  !$acc end serial
+
+  !$acc serial async(.true.) ! { dg-error "scalar INTEGER expression" }
+  !$acc end serial
+
+  !$acc serial async("1") ! { dg-error "scalar INTEGER expression" }
+  !$acc end serial
+
 
   !$acc parallel num_gangs ! { dg-error "Expected '\\(' after 'num_gangs'" }
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/subarrays.f95 b/gcc/testsuite/gfortran.dg/goacc/subarrays.f95
index fa0378550e9a861b79817b2e86c8bd3bbed33fca..031eb8befabde65eef598cba26afa3f61594715a 100644
--- a/gcc/testsuite/gfortran.dg/goacc/subarrays.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/subarrays.f95
@@ -38,4 +38,42 @@ program test
 
   !$acc parallel copy (c(2:)) ! { dg-warning "Lower array reference" }
   !$acc end parallel
+
+
+  !$acc serial copy(a(1:5))
+  !$acc end serial
+  !$acc serial copy(a(1 + 0 : 5 + 2))
+  !$acc end serial
+  !$acc serial copy(a(:3))
+  !$acc end serial
+  !$acc serial copy(a(3:))
+  !$acc end serial
+  !$acc serial copy(a(:))
+  !$acc end serial
+  !$acc serial copy(a(2:3,2:3))
+  ! { dg-error "Rank mismatch" "" { target *-*-* } .-1 }
+  ! { dg-error "'a' in MAP clause" "" { target *-*-* } .-2 }
+  !$acc end serial
+  !$acc serial copy (a(:11)) ! { dg-warning "Upper array reference" }
+  !$acc end serial
+  !$acc serial copy (a(i:))
+  !$acc end serial
+
+  !$acc serial copy (a(:b))
+  ! { dg-error "Array index" "" { target *-*-* } .-1 }
+  ! { dg-error "'a' in MAP clause" "" { target *-*-* } .-2 }
+  !$acc end serial
+
+  !$acc serial copy (b(1:3,2:4)) ! { dg-error "Array is not contiguous" }
+  !$acc end serial
+  !$acc serial copy (b(2:3))
+  ! { dg-error "Rank mismatch" "" { target *-*-* } .-1 }
+  ! { dg-error "'b' in MAP clause" "" { target *-*-* } .-2 }
+  !$acc end serial
+  !$acc serial copy (b(1:, 4:6))
+  !$acc end serial
+
+  !$acc serial copy (c(2:)) ! { dg-warning "Lower array reference" }
+  !$acc end serial
+
 end program test
diff --git a/gcc/testsuite/gfortran.dg/goacc/uninit-firstprivate-clause.f95 b/gcc/testsuite/gfortran.dg/goacc/uninit-firstprivate-clause.f95
index 9615fee4487d3cf5f32e979aabde6a807056dd5b..2e34d6d096f2657b670feb92f009cb2963e72541 100644
--- a/gcc/testsuite/gfortran.dg/goacc/uninit-firstprivate-clause.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/uninit-firstprivate-clause.f95
@@ -1,19 +1,37 @@
 ! { dg-do compile }
 ! { dg-additional-options "-Wuninitialized" }
 
-subroutine test
+subroutine test_parallel
   INTEGER :: i
 
   !$acc parallel
   i = 1
   !$acc end parallel
-end subroutine test
+end subroutine test_parallel
 
-subroutine test2
+subroutine test_serial
+  INTEGER :: i
+
+  !$acc serial
+  i = 1
+  !$acc end serial
+end subroutine test_serial
+
+
+subroutine test2_parallel
   INTEGER :: i
   ! { dg-note {'i' was declared here} {} { target *-*-* } .-1 }
 
   !$acc parallel firstprivate (i) ! { dg-warning "is used uninitialized" }
   i = 1
   !$acc end parallel
-end subroutine test2
+end subroutine test2_parallel
+
+subroutine test2_serial
+  INTEGER :: i
+  ! { dg-note {'i' was declared here} {} { target *-*-* } .-1 }
+
+  !$acc serial firstprivate (i) ! { dg-warning "is used uninitialized" }
+  i = 1
+  !$acc end serial
+end subroutine test2_serial
diff --git a/gcc/testsuite/gfortran.dg/goacc/uninit-if-clause.f95 b/gcc/testsuite/gfortran.dg/goacc/uninit-if-clause.f95
index a059bd986ebcf946b8bf96281a93513c336562b0..940fe841c2004b09d9509aaf4ce922bbd0c22a8d 100644
--- a/gcc/testsuite/gfortran.dg/goacc/uninit-if-clause.f95
+++ b/gcc/testsuite/gfortran.dg/goacc/uninit-if-clause.f95
@@ -3,11 +3,12 @@
 
 program test
   implicit none
-  logical :: b, b2, b3, b4
+  logical :: b, b2, bs, b3, b4
   ! { dg-note {'b' was declared here} {} { target *-*-* } .-1 }
   ! { dg-note {'b2' was declared here} {} { target *-*-* } .-2 }
-  ! { dg-note {'b3' was declared here} {} { target *-*-* } .-3 }
-  ! { dg-note {'b4' was declared here} {} { target *-*-* } .-4 }
+  ! { dg-note {'bs' was declared here} {} { target *-*-* } .-3 }
+  ! { dg-note {'b3' was declared here} {} { target *-*-* } .-4 }
+  ! { dg-note {'b4' was declared here} {} { target *-*-* } .-5 }
   integer :: data, data2
 
   !$acc parallel if(b) ! { dg-warning "is used uninitialized" }
@@ -16,6 +17,9 @@ program test
   !$acc kernels if(b2) ! { dg-warning "is used uninitialized" }
   !$acc end kernels
 
+  !$acc serial if(bs) ! { dg-warning "is used uninitialized" }
+  !$acc end serial
+
   !$acc data if(b3) ! { dg-warning "is used uninitialized" }
   !$acc end data
 
diff --git a/gcc/testsuite/gfortran.dg/goacc/update-if_present-2.f90 b/gcc/testsuite/gfortran.dg/goacc/update-if_present-2.f90
index 368e9370c60b327d970fc4234544b9f22c11178f..052d2abe888bea38825f071cd0fc5f4e97b46150 100644
--- a/gcc/testsuite/gfortran.dg/goacc/update-if_present-2.f90
+++ b/gcc/testsuite/gfortran.dg/goacc/update-if_present-2.f90
@@ -49,4 +49,10 @@ subroutine t2
   do b = 1, 10
   end do
   !$acc end parallel loop   ! { dg-error "Unexpected ..ACC END PARALLEL LOOP statement" }
+
+  !$acc serial loop if_present ! { dg-error "Expected '\\(' after 'if'" }
+  do b = 1, 10
+  end do
+  !$acc end serial loop   ! { dg-error "Unexpected ..ACC END SERIAL LOOP statement" }
+
 end subroutine t2