public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Backports to gcc-9-branch
@ 2019-06-05 12:24 Jakub Jelinek
  0 siblings, 0 replies; 4+ messages in thread
From: Jakub Jelinek @ 2019-06-05 12:24 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 139 bytes --]

Hi!

I've backported following 4 patches from trunk to 9 branch,
bootstrapped/regtested on x86_64-linux and i686-linux, committed.

	Jakub

[-- Attachment #2: r271597 --]
[-- Type: text/plain, Size: 2430 bytes --]

2019-06-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-24  Jakub Jelinek  <jakub@redhat.com>

	PR libgomp/90585
	* plugin/plugin-hsa.c (print_kernel_dispatch, run_kernel): Use PRIu64
	macro instead of "lu".
	(release_kernel_dispatch): Likewise.  Cast shadow->debug to uintptr_t
	before casting to void *.

--- libgomp/plugin/plugin-hsa.c	(revision 271596)
+++ libgomp/plugin/plugin-hsa.c	(revision 271597)
@@ -1154,8 +1164,9 @@ create_single_kernel_dispatch (struct ke
 static void
 release_kernel_dispatch (struct GOMP_hsa_kernel_dispatch *shadow)
 {
-  HSA_DEBUG ("Released kernel dispatch: %p has value: %lu (%p)\n", shadow,
-	     shadow->debug, (void *) shadow->debug);
+  HSA_DEBUG ("Released kernel dispatch: %p has value: %" PRIu64 " (%p)\n",
+	     shadow, shadow->debug,
+	     (void *) (uintptr_t) shadow->debug);
 
   hsa_fns.hsa_memory_free_fn (shadow->kernarg_address);
 
@@ -1276,9 +1287,9 @@ print_kernel_dispatch (struct GOMP_hsa_k
   indent_stream (stderr, indent);
   fprintf (stderr, "kernarg_address: %p\n", dispatch->kernarg_address);
   indent_stream (stderr, indent);
-  fprintf (stderr, "object: %lu\n", dispatch->object);
+  fprintf (stderr, "object: %" PRIu64 "\n", dispatch->object);
   indent_stream (stderr, indent);
-  fprintf (stderr, "signal: %lu\n", dispatch->signal);
+  fprintf (stderr, "signal: %" PRIu64 "\n", dispatch->signal);
   indent_stream (stderr, indent);
   fprintf (stderr, "private_segment_size: %u\n",
 	   dispatch->private_segment_size);
@@ -1286,8 +1297,8 @@ print_kernel_dispatch (struct GOMP_hsa_k
   fprintf (stderr, "group_segment_size: %u\n",
 	   dispatch->group_segment_size);
   indent_stream (stderr, indent);
-  fprintf (stderr, "children dispatches: %lu\n",
-	   dispatch->kernel_dispatch_count);
+  fprintf (stderr, "children dispatches: %" PRIu64 "\n",
+	   dispatch->kernel_dispatch_count);
   indent_stream (stderr, indent);
   fprintf (stderr, "omp_num_threads: %u\n",
 	   dispatch->omp_num_threads);
@@ -1594,8 +1605,8 @@ run_kernel (struct kernel_info *kernel,
 	hsa_signal_t child_s;
 	child_s.handle = shadow->children_dispatches[i]->signal;
 
-	HSA_DEBUG ("Waiting for children completion signal: %lu\n",
-		   shadow->children_dispatches[i]->signal);
+	HSA_DEBUG ("Waiting for children completion signal: %" PRIu64 "\n",
+		   shadow->children_dispatches[i]->signal);
 	hsa_fns.hsa_signal_load_acquire_fn (child_s);
       }
 

[-- Attachment #3: r271671 --]
[-- Type: text/plain, Size: 6248 bytes --]

2019-06-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-27  Jakub Jelinek  <jakub@redhat.com>

	PR libgomp/90641
	* work.c (gomp_init_work_share): Instead of aligning final ordered
	value to multiples of long long alignment, align to that the
	first part (ordered team ids) and if inline_ordered_team_ids
	is not on a long long alignment boundary within the structure,
	use __alignof__ (long long) - 1 pad size always.
	* loop.c (GOMP_loop_start): Fix *mem computation if
	inline_ordered_team_ids is not aligned on long long alignment boundary
	within the structure.
	* loop-ull.c (GOMP_loop_ull_start): Likewise.
	* sections.c (GOMP_sections2_start): Likewise.

--- libgomp/loop.c	(revision 271670)
+++ libgomp/loop.c	(revision 271671)
@@ -267,14 +267,17 @@ GOMP_loop_start (long start, long end, l
       if (mem)
 	{
 	  uintptr_t size = (uintptr_t) *mem;
+#define INLINE_ORDERED_TEAM_IDS_OFF \
+  ((offsetof (struct gomp_work_share, inline_ordered_team_ids)		\
+    + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
 	  if (size > (sizeof (struct gomp_work_share)
-		      - offsetof (struct gomp_work_share,
-				  inline_ordered_team_ids)))
-	    thr->ts.work_share->ordered_team_ids
-	      = gomp_malloc_cleared (size);
+		      - INLINE_ORDERED_TEAM_IDS_OFF))
+	    *mem
+	      = (void *) (thr->ts.work_share->ordered_team_ids
+			  = gomp_malloc_cleared (size));
 	  else
-	    memset (thr->ts.work_share->ordered_team_ids, '\0', size);
-	  *mem = (void *) thr->ts.work_share->ordered_team_ids;
+	    *mem = memset (((char *) thr->ts.work_share)
+			   + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
 	}
       gomp_work_share_init_done ();
     }
@@ -287,7 +290,18 @@ GOMP_loop_start (long start, long end, l
 						  first_reductions);
 	}
       if (mem)
-	*mem = (void *) thr->ts.work_share->ordered_team_ids;
+	{
+	  if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+	       & (__alignof__ (long long) - 1)) == 0)
+	    *mem = (void *) thr->ts.work_share->ordered_team_ids;
+	  else
+	    {
+	      uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
+	      p += __alignof__ (long long) - 1;
+	      p &= ~(__alignof__ (long long) - 1);
+	      *mem = (void *) p;
+	    }
+	}
     }
 
   if (!istart)
--- libgomp/loop_ull.c	(revision 271670)
+++ libgomp/loop_ull.c	(revision 271671)
@@ -266,14 +266,17 @@ GOMP_loop_ull_start (bool up, gomp_ull s
       if (mem)
 	{
 	  uintptr_t size = (uintptr_t) *mem;
+#define INLINE_ORDERED_TEAM_IDS_OFF \
+  ((offsetof (struct gomp_work_share, inline_ordered_team_ids)		\
+    + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
 	  if (size > (sizeof (struct gomp_work_share)
-		      - offsetof (struct gomp_work_share,
-				  inline_ordered_team_ids)))
-	    thr->ts.work_share->ordered_team_ids
-	      = gomp_malloc_cleared (size);
+		      - INLINE_ORDERED_TEAM_IDS_OFF))
+	    *mem
+	      = (void *) (thr->ts.work_share->ordered_team_ids
+			  = gomp_malloc_cleared (size));
 	  else
-	    memset (thr->ts.work_share->ordered_team_ids, '\0', size);
-	  *mem = (void *) thr->ts.work_share->ordered_team_ids;
+	    *mem = memset (((char *) thr->ts.work_share)
+			   + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
 	}
       gomp_work_share_init_done ();
     }
@@ -286,7 +289,18 @@ GOMP_loop_ull_start (bool up, gomp_ull s
 						  first_reductions);
 	}
       if (mem)
-	*mem = (void *) thr->ts.work_share->ordered_team_ids;
+	{
+	  if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+	       & (__alignof__ (long long) - 1)) == 0)
+	    *mem = (void *) thr->ts.work_share->ordered_team_ids;
+	  else
+	    {
+	      uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
+	      p += __alignof__ (long long) - 1;
+	      p &= ~(__alignof__ (long long) - 1);
+	      *mem = (void *) p;
+	    }
+	}
     }
 
   return ialias_call (GOMP_loop_ull_runtime_next) (istart, iend);
--- libgomp/sections.c	(revision 271670)
+++ libgomp/sections.c	(revision 271671)
@@ -118,14 +118,17 @@ GOMP_sections2_start (unsigned count, ui
       if (mem)
 	{
 	  uintptr_t size = (uintptr_t) *mem;
+#define INLINE_ORDERED_TEAM_IDS_OFF \
+  ((offsetof (struct gomp_work_share, inline_ordered_team_ids)		\
+    + __alignof__ (long long) - 1) & ~(__alignof__ (long long) - 1))
 	  if (size > (sizeof (struct gomp_work_share)
-		      - offsetof (struct gomp_work_share,
-				  inline_ordered_team_ids)))
-	    thr->ts.work_share->ordered_team_ids
-	      = gomp_malloc_cleared (size);
+		      - INLINE_ORDERED_TEAM_IDS_OFF))
+	    *mem
+	      = (void *) (thr->ts.work_share->ordered_team_ids
+			  = gomp_malloc_cleared (size));
 	  else
-	    memset (thr->ts.work_share->ordered_team_ids, '\0', size);
-	  *mem = (void *) thr->ts.work_share->ordered_team_ids;
+	    *mem = memset (((char *) thr->ts.work_share)
+			   + INLINE_ORDERED_TEAM_IDS_OFF, '\0', size);
 	}
       gomp_work_share_init_done ();
     }
@@ -138,7 +141,18 @@ GOMP_sections2_start (unsigned count, ui
 						  first_reductions);
 	}
       if (mem)
-	*mem = (void *) thr->ts.work_share->ordered_team_ids;
+	{
+	  if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+	       & (__alignof__ (long long) - 1)) == 0)
+	    *mem = (void *) thr->ts.work_share->ordered_team_ids;
+	  else
+	    {
+	      uintptr_t p = (uintptr_t) thr->ts.work_share->ordered_team_ids;
+	      p += __alignof__ (long long) - 1;
+	      p &= ~(__alignof__ (long long) - 1);
+	      *mem = (void *) p;
+	    }
+	}
     }
 
 #ifdef HAVE_SYNC_BUILTINS
--- libgomp/work.c	(revision 271670)
+++ libgomp/work.c	(revision 271671)
@@ -110,9 +110,12 @@ gomp_init_work_share (struct gomp_work_s
 
       if (__builtin_expect (ordered != 1, 0))
 	{
-	  ordered += nthreads * sizeof (*ws->ordered_team_ids) - 1;
-	  ordered = ordered + __alignof__ (long long) - 1;
-	  ordered &= ~(__alignof__ (long long) - 1);
+	  size_t o = nthreads * sizeof (*ws->ordered_team_ids);
+	  o += __alignof__ (long long) - 1;
+	  if ((offsetof (struct gomp_work_share, inline_ordered_team_ids)
+	       & (__alignof__ (long long) - 1)) == 0)
+	    o &= ~(__alignof__ (long long) - 1);
+	  ordered += o - 1;
 	}
       else
 	ordered = nthreads * sizeof (*ws->ordered_team_ids);

[-- Attachment #4: r271752 --]
[-- Type: text/plain, Size: 1865 bytes --]

2019-06-05  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-29  Jakub Jelinek  <jakub@redhat.com>

	PR c++/90598
	* tree.c (lvalue_kind): Return clk_none for expressions with
	with VOID_TYPE_P.

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

	2019-05-02  Jonathan Wakely  <jwakely@redhat.com>

	* testsuite/experimental/propagate_const/requirements2.cc: Adjust
	dg-error.

--- gcc/cp/tree.c	(revision 271751)
+++ gcc/cp/tree.c	(revision 271752)
@@ -83,6 +83,10 @@ lvalue_kind (const_tree ref)
   if (ref == current_class_ptr)
     return clk_none;
 
+  /* Expressions with cv void type are prvalues.  */
+  if (TREE_TYPE (ref) && VOID_TYPE_P (TREE_TYPE (ref)))
+    return clk_none;
+
   switch (TREE_CODE (ref))
     {
     case SAVE_EXPR:
--- gcc/testsuite/g++.dg/cpp0x/pr90598.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/pr90598.C	(revision 271752)
@@ -0,0 +1,8 @@
+// PR c++/90598
+// { dg-do compile { target c++11 } }
+
+struct A {};
+using B = decltype(A ().~A ());
+template <typename T> struct C;
+template <> struct C<void> {};
+C<B> t;
--- libstdc++-v3/testsuite/experimental/propagate_const/requirements2.cc	(revision 270808)
+++ libstdc++-v3/testsuite/experimental/propagate_const/requirements2.cc	(revision 270809)
@@ -21,9 +21,8 @@
 
 using std::experimental::propagate_const;
 
-// { dg-error "requires a class or a pointer to an object type" "" { target *-*-* } 107 }
-// { dg-error "not a pointer-to-object type" "" { target *-*-* } 66 }
-// { dg-error "forming pointer to reference type" "" { target *-*-* } 187 }
-// { dg-error "forming pointer to reference type" "" { target *-*-* } 213 }
-
 propagate_const<void*> test1;
+
+// { dg-error "requires a class or a pointer to an object type" "" { target *-*-* } 0 }
+// { dg-prune-output "forming pointer to reference type" }
+// { dg-prune-output "not a pointer-to-object type" }

[-- Attachment #5: r271952 --]
[-- Type: text/plain, Size: 1069 bytes --]

2019-06-05  Jakub Jelinek  <jakub@redhat.com>

	PR debug/90733
	* var-tracking.c (vt_expand_loc_callback): Don't create raw subregs
	with VOIDmode inner operands.

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

--- gcc/var-tracking.c	(revision 271951)
+++ gcc/var-tracking.c	(revision 271952)
@@ -8491,7 +8491,7 @@ vt_expand_loc_callback (rtx x, bitmap re
 
       /* Invalid SUBREGs are ok in debug info.  ??? We could try
 	 alternate expansions for the VALUE as well.  */
-      if (!result)
+      if (!result && GET_MODE (subreg) != VOIDmode)
 	result = gen_rtx_raw_SUBREG (GET_MODE (x), subreg, SUBREG_BYTE (x));
 
       return result;
--- gcc/testsuite/gcc.dg/pr90733.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/pr90733.c	(revision 271952)
@@ -0,0 +1,22 @@
+/* PR debug/90733 */
+/* { dg-do compile } */
+/* { dg-options "-g -O2 -w" } */
+
+struct S { unsigned a : 1; };
+union U { struct S b; _Complex unsigned c; };
+
+union U
+foo (union U d)
+{
+  union U e = d;
+  return e;
+}
+
+int
+bar (void)
+{
+  union U x, y;
+  x.c = x.b.a;
+  y = foo (x);
+  return x.c != y.c;
+}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Backports to gcc-9-branch
@ 2019-11-08 19:30 Jakub Jelinek
  0 siblings, 0 replies; 4+ messages in thread
From: Jakub Jelinek @ 2019-11-08 19:30 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 153 bytes --]

Hi!

I've backorted following 10 patches from trunk to 9 branch,
bootstrapped/regtested them on x86_64-linux and i686-linux and committed.

	Jakub

[-- Attachment #2: r277267 --]
[-- Type: text/plain, Size: 1460 bytes --]

2019-11-08  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-10-21  Jakub Jelinek  <jakub@redhat.com>

	PR c++/92015
	* constexpr.c (cxx_eval_component_reference, cxx_eval_bit_field_ref):
	Use STRIP_ANY_LOCATION_WRAPPER on CONSTRUCTOR elts.

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

--- gcc/cp/constexpr.c	(revision 277266)
+++ gcc/cp/constexpr.c	(revision 277267)
@@ -2887,7 +2887,10 @@ cxx_eval_component_reference (const cons
 	  : field == part)
 	{
 	  if (value)
-	    return value;
+	    {
+	      STRIP_ANY_LOCATION_WRAPPER (value);
+	      return value;
+	    }
 	  else
 	    /* We're in the middle of initializing it.  */
 	    break;
@@ -2977,6 +2980,7 @@ cxx_eval_bit_field_ref (const constexpr_
   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
     {
       tree bitpos = bit_position (field);
+      STRIP_ANY_LOCATION_WRAPPER (value);
       if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1))
 	return value;
       if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE
--- gcc/testsuite/g++.dg/cpp0x/constexpr-92015.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-92015.C	(revision 277267)
@@ -0,0 +1,7 @@
+// PR c++/92015
+// { dg-do compile { target c++11 } }
+
+struct S1 { char c[6] {'h', 'e', 'l', 'l', 'o', 0}; };
+struct S2 { char c[6] = "hello"; };
+static_assert (S1{}.c[0] == 'h', "");
+static_assert (S2{}.c[0] == 'h', "");

[-- Attachment #3: r277291 --]
[-- Type: text/plain, Size: 1105 bytes --]

2019-11-08  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-10-22  Tamar Christina  <tamar.christina@arm.com>

	PR sanitizer/92154
	* sanitizer_common/sanitizer_platform_limits_posix.cc:
	Cherry-pick compiler-rt revision r375220.

--- libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc	(revision 277290)
+++ libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc	(revision 277291)
@@ -1126,8 +1126,12 @@ CHECK_SIZE_AND_OFFSET(ipc_perm, uid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, gid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, cuid);
 CHECK_SIZE_AND_OFFSET(ipc_perm, cgid);
-#if !defined(__aarch64__) || !SANITIZER_LINUX || __GLIBC_PREREQ (2, 21)
+#if (!defined(__aarch64__) || !SANITIZER_LINUX || __GLIBC_PREREQ (2, 21)) && \
+    !defined(__arm__)
 /* On aarch64 glibc 2.20 and earlier provided incorrect mode field.  */
+/* On Arm glibc 2.31 and later provide a different mode field, this field is
+   never used by libsanitizer so we can simply ignore this assert for all glibc
+   versions.  */
 CHECK_SIZE_AND_OFFSET(ipc_perm, mode);
 #endif
 

[-- Attachment #4: r277293 --]
[-- Type: text/plain, Size: 1028 bytes --]

2019-11-08  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-10-22  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/85887
	* decl.c (expand_static_init): Drop ECF_LEAF from __cxa_guard_acquire
	and __cxa_guard_release.

--- gcc/cp/decl.c	(revision 277292)
+++ gcc/cp/decl.c	(revision 277293)
@@ -8589,14 +8589,14 @@ expand_static_init (tree decl, tree init
 	      (acquire_name, build_function_type_list (integer_type_node,
 						       TREE_TYPE (guard_addr),
 						       NULL_TREE),
-	       NULL_TREE, ECF_NOTHROW | ECF_LEAF);
+	       NULL_TREE, ECF_NOTHROW);
 	  if (!release_fn || !abort_fn)
 	    vfntype = build_function_type_list (void_type_node,
 						TREE_TYPE (guard_addr),
 						NULL_TREE);
 	  if (!release_fn)
 	    release_fn = push_library_fn (release_name, vfntype, NULL_TREE,
-					   ECF_NOTHROW | ECF_LEAF);
+					  ECF_NOTHROW);
 	  if (!abort_fn)
 	    abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE,
 					ECF_NOTHROW | ECF_LEAF);

[-- Attachment #5: r277492 --]
[-- Type: text/plain, Size: 540 bytes --]

2019-11-08  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-10-27  Jakub Jelinek  <jakub@redhat.com>

	* locales.c (iso_3166): Add missing comma after "United-States".

--- gcc/ada/locales.c	(revision 277491)
+++ gcc/ada/locales.c	(revision 277492)
@@ -529,7 +529,7 @@ static char* iso_3166[] =
   "UM", "United States Minor Outlying Islands",
   "US", "United States",
   "US", "United States of America",
-  "US", "United-States"
+  "US", "United-States",
   "UY", "Uruguay",
   "UZ", "Uzbekistan",
 

[-- Attachment #6: r277552 --]
[-- Type: text/plain, Size: 749 bytes --]

2019-11-08  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-10-29  Jakub Jelinek  <jakub@redhat.com>

	* doc/install.texi (--enable-offload-targets): Fix up a typo in the
	example, use actual names of supported offload targets.

--- gcc/doc/install.texi	(revision 277551)
+++ gcc/doc/install.texi	(revision 277552)
@@ -2158,7 +2158,7 @@ specifying paths @var{path1}, @dots{}, @
 
 @smallexample
 % @var{srcdir}/configure \
-    --enable-offload-target=i686-unknown-linux-gnu=/path/to/i686/compiler,x86_64-pc-linux-gnu
+    --enable-offload-targets=x86_64-intelmicemul-linux-gnu=/path/to/x86_64/compiler,nvptx-none,hsa
 @end smallexample
 
 If @samp{hsa} is specified as one of the targets, the compiler will be

[-- Attachment #7: r277656 --]
[-- Type: text/plain, Size: 7079 bytes --]

2019-11-08  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-10-31  Jakub Jelinek  <jakub@redhat.com>

	PR c++/90947
	* tree.h (type_initializer_zero_p): Remove.
	* tree.c (type_initializer_zero_p): Remove.

	* cp-tree.h (type_initializer_zero_p): Declare.
	* decl.c (reshape_init_array_1): Formatting fix.
	* tree.c (type_initializer_zero_p): New function.  Moved from
	../tree.c, use next_initializable_field, formatting fix.  Return
	false for TYPE_NON_AGGREGATE_CLASS types.

--- gcc/tree.c	(revision 277655)
+++ gcc/tree.c	(revision 277656)
@@ -11123,73 +11123,6 @@ initializer_each_zero_or_onep (const_tre
     }
 }
 
-/* Given an initializer INIT for a TYPE, return true if INIT is zero
-   so that it can be replaced by value initialization.  This function
-   distinguishes betwen empty strings as initializers for arrays and
-   for pointers (which make it return false).  */
-
-bool
-type_initializer_zero_p (tree type, tree init)
-{
-  if (type  == error_mark_node || init == error_mark_node)
-    return false;
-
-  STRIP_NOPS (init);
-
-  if (POINTER_TYPE_P (type))
-    return TREE_CODE (init) != STRING_CST && initializer_zerop (init);
-
-  if (TREE_CODE (init) != CONSTRUCTOR)
-    return initializer_zerop (init);
-
-  if (TREE_CODE (type) == ARRAY_TYPE)
-    {
-      tree elt_type = TREE_TYPE (type);
-      elt_type = TYPE_MAIN_VARIANT (elt_type);
-      if (elt_type == char_type_node)
-	return initializer_zerop (init);
-
-      tree elt_init;
-      unsigned HOST_WIDE_INT i;
-      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, elt_init)
-	if (!type_initializer_zero_p (elt_type, elt_init))
-	  return false;
-      return true;
-    }
-
-  if (TREE_CODE (type) != RECORD_TYPE)
-    return initializer_zerop (init);
-
-  tree fld = TYPE_FIELDS (type);
-
-  tree fld_init;
-  unsigned HOST_WIDE_INT i;
-  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, fld_init)
-    {
-      /* Advance to the next member, skipping over everything that
-	 canot be initialized (including unnamed bit-fields).  */
-      while (TREE_CODE (fld) != FIELD_DECL
-	     || DECL_ARTIFICIAL (fld)
-	     || (DECL_BIT_FIELD (fld) && !DECL_NAME (fld)))
-	{
-	  fld = DECL_CHAIN (fld);
-	  if (!fld)
-	    return true;
-	  continue;
-	}
-
-      tree fldtype = TREE_TYPE (fld);
-      if (!type_initializer_zero_p (fldtype, fld_init))
-	return false;
-
-      fld = DECL_CHAIN (fld);
-      if (!fld)
-	break;
-    }
-
-  return true;
-}
-
 /* Check if vector VEC consists of all the equal elements and
    that the number of elements corresponds to the type of VEC.
    The function returns first element of the vector
--- gcc/tree.h	(revision 277655)
+++ gcc/tree.h	(revision 277656)
@@ -4690,12 +4690,6 @@ extern tree first_field (const_tree);
 extern bool initializer_zerop (const_tree, bool * = NULL);
 extern bool initializer_each_zero_or_onep (const_tree);
 
-/* Analogous to initializer_zerop but also examines the type for
-   which the initializer is being used.  Unlike initializer_zerop,
-   considers empty strings to be zero initializers for arrays and
-   non-zero for pointers.  */
-extern bool type_initializer_zero_p (tree, tree);
-
 extern wide_int vector_cst_int_elt (const_tree, unsigned int);
 extern tree vector_cst_elt (const_tree, unsigned int);
 
--- gcc/cp/decl.c	(revision 277655)
+++ gcc/cp/decl.c	(revision 277656)
@@ -5973,9 +5973,8 @@ reshape_init_array_1 (tree elt_type, tre
       /* Pointers initialized to strings must be treated as non-zero
 	 even if the string is empty.  */
       tree init_type = TREE_TYPE (elt_init);
-      if ((POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)))
-	last_nonzero = index;
-      else if (!type_initializer_zero_p (elt_type, elt_init))
+      if (POINTER_TYPE_P (elt_type) != POINTER_TYPE_P (init_type)
+	  || !type_initializer_zero_p (elt_type, elt_init))
 	last_nonzero = index;
 
       /* This can happen with an invalid initializer (c++/54501).  */
--- gcc/cp/tree.c	(revision 277655)
+++ gcc/cp/tree.c	(revision 277656)
@@ -5540,6 +5540,68 @@ maybe_warn_zero_as_null_pointer_constant
   return false;
 }
 \f
+/* Given an initializer INIT for a TYPE, return true if INIT is zero
+   so that it can be replaced by value initialization.  This function
+   distinguishes betwen empty strings as initializers for arrays and
+   for pointers (which make it return false).  */
+
+bool
+type_initializer_zero_p (tree type, tree init)
+{
+  if (type == error_mark_node || init == error_mark_node)
+    return false;
+
+  STRIP_NOPS (init);
+
+  if (POINTER_TYPE_P (type))
+    return TREE_CODE (init) != STRING_CST && initializer_zerop (init);
+
+  if (TREE_CODE (init) != CONSTRUCTOR)
+    return initializer_zerop (init);
+
+  if (TREE_CODE (type) == ARRAY_TYPE)
+    {
+      tree elt_type = TREE_TYPE (type);
+      elt_type = TYPE_MAIN_VARIANT (elt_type);
+      if (elt_type == char_type_node)
+	return initializer_zerop (init);
+
+      tree elt_init;
+      unsigned HOST_WIDE_INT i;
+      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, elt_init)
+	if (!type_initializer_zero_p (elt_type, elt_init))
+	  return false;
+      return true;
+    }
+
+  if (TREE_CODE (type) != RECORD_TYPE)
+    return initializer_zerop (init);
+
+  if (TYPE_NON_AGGREGATE_CLASS (type))
+    return false;
+
+  tree fld = TYPE_FIELDS (type);
+
+  tree fld_init;
+  unsigned HOST_WIDE_INT i;
+  FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), i, fld_init)
+    {
+      fld = next_initializable_field (fld);
+      if (!fld)
+	return true;
+
+      tree fldtype = TREE_TYPE (fld);
+      if (!type_initializer_zero_p (fldtype, fld_init))
+	return false;
+
+      fld = DECL_CHAIN (fld);
+      if (!fld)
+	break;
+    }
+
+  return true;
+}
+\f
 #if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
 /* Complain that some language-specific thing hanging off a tree
    node has been accessed improperly.  */
--- gcc/cp/cp-tree.h	(revision 277655)
+++ gcc/cp/cp-tree.h	(revision 277656)
@@ -7382,6 +7382,11 @@ extern tree cxx_copy_lang_qualifiers		(c
 
 extern void cxx_print_statistics		(void);
 extern bool maybe_warn_zero_as_null_pointer_constant (tree, location_t);
+/* Analogous to initializer_zerop but also examines the type for
+   which the initializer is being used.  Unlike initializer_zerop,
+   considers empty strings to be zero initializers for arrays and
+   non-zero for pointers.  */
+extern bool type_initializer_zero_p		(tree, tree);
 
 /* in ptree.c */
 extern void cxx_print_xnode			(FILE *, tree, int);
--- gcc/testsuite/g++.dg/init/array54.C	(nonexistent)
+++ gcc/testsuite/g++.dg/init/array54.C	(revision 277656)
@@ -0,0 +1,13 @@
+// PR c++/90947
+// { dg-do run { target c++11 } }
+
+#include <atomic>
+
+static std::atomic<int> a[1] { {1} };
+
+int
+main ()
+{
+  if (a[0].load () != 1)
+    __builtin_abort ();
+}

[-- Attachment #8: r277660 --]
[-- Type: text/plain, Size: 3251 bytes --]

2019-11-08  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-10-31  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/92231
	* tree.h (fndecl_built_in_p): Use fndecl_built_in_p instead of
	DECL_BUILT_IN in comment.  Remove redundant ()s around return
	argument.
	* tree.c (free_lang_data_in_decl): Check if var is FUNCTION_DECL
	before calling fndecl_built_in_p.
	* gimple-fold.c (gimple_fold_stmt_to_constant_1): Check if
	TREE_OPERAND (fn, 0) is a FUNCTION_DECL before calling
	fndecl_built_in_p on it.

	* lto-lang.c (handle_const_attribute): Don't call fndecl_built_in_p
	on *node that is not FUNCTION_DECL.

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

--- gcc/tree.c	(revision 277659)
+++ gcc/tree.c	(revision 277660)
@@ -5805,7 +5805,8 @@ free_lang_data_in_decl (tree decl, class
       while (*nextp)
 	{
 	  tree var = *nextp;
-	  if (fndecl_built_in_p (var))
+	  if (TREE_CODE (var) == FUNCTION_DECL
+	      && fndecl_built_in_p (var))
 	    *nextp = TREE_CHAIN (var);
 	  else
 	    nextp = &TREE_CHAIN (var);
--- gcc/tree.h	(revision 277659)
+++ gcc/tree.h	(revision 277660)
@@ -6119,12 +6119,12 @@ type_has_mode_precision_p (const_tree t)
 
    Note that it is different from the DECL_IS_BUILTIN accessor.  For
    instance, user declared prototypes of C library functions are not
-   DECL_IS_BUILTIN but may be DECL_BUILT_IN.  */
+   DECL_IS_BUILTIN but may be fndecl_built_in_p.  */
 
 inline bool
 fndecl_built_in_p (const_tree node)
 {
-  return (DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN);
+  return DECL_BUILT_IN_CLASS (node) != NOT_BUILT_IN;
 }
 
 /* Return true if a FUNCTION_DECL NODE is a GCC built-in function
@@ -6133,7 +6133,7 @@ fndecl_built_in_p (const_tree node)
 inline bool
 fndecl_built_in_p (const_tree node, built_in_class klass)
 {
-  return (fndecl_built_in_p (node) && DECL_BUILT_IN_CLASS (node) == klass);
+  return fndecl_built_in_p (node) && DECL_BUILT_IN_CLASS (node) == klass;
 }
 
 /* Return true if a FUNCTION_DECL NODE is a GCC built-in function
--- gcc/gimple-fold.c	(revision 277659)
+++ gcc/gimple-fold.c	(revision 277660)
@@ -6439,6 +6439,7 @@ gimple_fold_stmt_to_constant_1 (gimple *
 
 	fn = (*valueize) (gimple_call_fn (stmt));
 	if (TREE_CODE (fn) == ADDR_EXPR
+	    && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
 	    && fndecl_built_in_p (TREE_OPERAND (fn, 0))
 	    && gimple_builtin_call_types_compatible_p (stmt,
 						       TREE_OPERAND (fn, 0)))
--- gcc/lto/lto-lang.c	(revision 277659)
+++ gcc/lto/lto-lang.c	(revision 277660)
@@ -305,7 +305,8 @@ handle_const_attribute (tree *node, tree
 			tree ARG_UNUSED (args), int ARG_UNUSED (flags),
 			bool * ARG_UNUSED (no_add_attrs))
 {
-  if (!fndecl_built_in_p (*node))
+  if (TREE_CODE (*node) != FUNCTION_DECL
+      || !fndecl_built_in_p (*node))
     inform (UNKNOWN_LOCATION, "%s:%s: %E: %E", __FILE__, __func__, *node, name);
 
   tree type = TREE_TYPE (*node);
--- gcc/testsuite/gcc.c-torture/compile/pr92231.c	(nonexistent)
+++ gcc/testsuite/gcc.c-torture/compile/pr92231.c	(revision 277660)
@@ -0,0 +1,9 @@
+/* PR middle-end/92231 */
+
+extern int bar (void);
+
+int
+foo (void)
+{
+  return (&bar + 4096) ();
+}

[-- Attachment #9: r277685 --]
[-- Type: text/plain, Size: 7124 bytes --]

2019-11-08  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-10-31  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/92296
	* internal.h (struct def_pragma_macro): Add is_builtin bitfield.
	(_cpp_restore_special_builtin): Declare.
	* init.c (_cpp_restore_special_builtin): New function.
	* directives.c (do_pragma_push_macro): For NT_BUILTIN_MACRO
	set is_builtin and don't try to grab definition.
	(cpp_pop_definition): Use _cpp_restore_special_builtin to restore
	builtin macros.

	* c-c++-common/cpp/pr92296-1.c: New test.
	* c-c++-common/cpp/pr92296-2.c: New test.

--- libcpp/directives.c	(revision 277684)
+++ libcpp/directives.c	(revision 277685)
@@ -1582,6 +1582,8 @@ do_pragma_push_macro (cpp_reader *pfile)
   node = _cpp_lex_identifier (pfile, c->name);
   if (node->type == NT_VOID)
     c->is_undef = 1;
+  else if (node->type == NT_BUILTIN_MACRO)
+    c->is_builtin = 1;
   else
     {
       defn = cpp_macro_definition (pfile, node);
@@ -2470,6 +2472,11 @@ cpp_pop_definition (cpp_reader *pfile, s
 
   if (c->is_undef)
     return;
+  if (c->is_builtin)
+    {
+      _cpp_restore_special_builtin (pfile, c);
+      return;
+    }
 
   {
     size_t namelen;
--- libcpp/init.c	(revision 277684)
+++ libcpp/init.c	(revision 277685)
@@ -497,6 +497,25 @@ cpp_init_special_builtins (cpp_reader *p
     }
 }
 
+/* Restore macro C to builtin macro definition.  */
+
+void
+_cpp_restore_special_builtin (cpp_reader *pfile, struct def_pragma_macro *c)
+{
+  size_t len = strlen (c->name);
+
+  for (const struct builtin_macro *b = builtin_array;
+       b < builtin_array + ARRAY_SIZE (builtin_array); b++)
+    if (b->len == len && memcmp (c->name, b->name, len + 1) == 0)
+      {
+	cpp_hashnode *hp = cpp_lookup (pfile, b->name, b->len);
+	hp->type = NT_BUILTIN_MACRO;
+	if (b->always_warn_if_redefined)
+	  hp->flags |= NODE_WARN;
+	hp->value.builtin = (enum cpp_builtin_type) b->value;
+      }
+}
+
 /* Read the builtins table above and enter them, and language-specific
    macros, into the hash table.  HOSTED is true if this is a hosted
    environment.  */
--- libcpp/internal.h	(revision 277684)
+++ libcpp/internal.h	(revision 277685)
@@ -391,6 +391,8 @@ struct def_pragma_macro {
 
   /* Mark if we save an undefined macro.  */
   unsigned int is_undef : 1;
+  /* Nonzero if it was a builtin macro.  */
+  unsigned int is_builtin : 1;
 };
 
 /* A cpp_reader encapsulates the "state" of a pre-processor run.
@@ -722,6 +724,8 @@ extern void *_cpp_commit_buff (cpp_reade
 /* In init.c.  */
 extern void _cpp_maybe_push_include_file (cpp_reader *);
 extern const char *cpp_named_operator2name (enum cpp_ttype type);
+extern void _cpp_restore_special_builtin (cpp_reader *pfile,
+					  struct def_pragma_macro *);
 
 /* In directives.c */
 extern int _cpp_test_assertion (cpp_reader *, unsigned int *);
--- gcc/testsuite/c-c++-common/cpp/pr92296-1.c	(nonexistent)
+++ gcc/testsuite/c-c++-common/cpp/pr92296-1.c	(revision 277685)
@@ -0,0 +1,32 @@
+/* PR preprocessor/92296 */
+/* { dg-do preprocess } */
+
+#pragma push_macro("__TIMESTAMP__")
+#pragma pop_macro("__TIMESTAMP__")
+
+#pragma push_macro("__TIME__")
+#pragma pop_macro("__TIME__")
+
+#pragma push_macro("__DATE__")
+#pragma pop_macro("__DATE__")
+
+#pragma push_macro("__FILE__")
+#pragma pop_macro("__FILE__")
+
+#pragma push_macro("__BASE_FILE__")
+#pragma pop_macro("__BASE_FILE__")
+
+#pragma push_macro("__LINE__")
+#pragma pop_macro("__LINE__")
+
+#pragma push_macro("__INCLUDE_LEVEL__")
+#pragma pop_macro("__INCLUDE_LEVEL__")
+
+#pragma push_macro("__COUNTER__")
+#pragma pop_macro("__COUNTER__")
+
+#pragma push_macro("__has_attribute")
+#pragma pop_macro("__has_attribute")
+
+#pragma push_macro("__has_cpp_attribute")
+#pragma pop_macro("__has_cpp_attribute")
--- gcc/testsuite/c-c++-common/cpp/pr92296-2.c	(nonexistent)
+++ gcc/testsuite/c-c++-common/cpp/pr92296-2.c	(revision 277685)
@@ -0,0 +1,73 @@
+/* PR preprocessor/92296 */
+/* { dg-do preprocess } */
+/* { dg-options "-Wno-builtin-macro-redefined" } */
+
+#pragma push_macro("__TIMESTAMP__")
+#undef __TIMESTAMP__
+#define __TIMESTAMP__ "Thu Oct 31 12:00:00 2019"
+timestamp1 = __TIMESTAMP__
+#pragma pop_macro("__TIMESTAMP__")
+timestamp2 = __TIMESTAMP__
+
+#pragma push_macro("__TIME__")
+#undef __TIME__
+#define __TIME__ "12:00:00"
+time1 = __TIME__
+#pragma pop_macro("__TIME__")
+time2 = __TIME__
+
+#pragma push_macro("__DATE__")
+#undef __DATE__
+#define __DATE__ "Oct 31 2019"
+date1 = __DATE__
+#pragma pop_macro("__DATE__")
+date2 = __DATE__
+
+#pragma push_macro("__FILE__")
+#undef __FILE__
+#define __FILE__ "pr92296-3.c"
+file1 = __FILE__	/* { dg-final { scan-file pr92296-2.i "file1 = \"pr92296-3.c\"" } } */
+#pragma pop_macro("__FILE__")
+file2 = __FILE__	/* { dg-final { scan-file-not pr92296-2.i "file2 = \"pr92296-3.c\"" } } */
+
+#pragma push_macro("__BASE_FILE__")
+#undef __BASE_FILE__
+#define __BASE_FILE__ "pr92296-4.c"
+filebase1 = __BASE_FILE__	/* { dg-final { scan-file pr92296-2.i "filebase1 = \"pr92296-4.c\"" } } */
+#pragma pop_macro("__BASE_FILE__")
+filebase2 = __BASE_FILE__	/* { dg-final { scan-file-not pr92296-2.i "filebase2 = \"pr92296-4.c\"" } } */
+
+#pragma push_macro("__LINE__")
+#undef __LINE__		/* { dg-warning "undefining" } */
+#define __LINE__ 142
+line1 = __LINE__	/* { dg-final { scan-file pr92296-2.i "line1 = 142" } } */
+#pragma pop_macro("__LINE__")
+line2 = __LINE__	/* { dg-final { scan-file pr92296-2.i "line2 = 45" } } */
+
+#pragma push_macro("__INCLUDE_LEVEL__")
+#undef __INCLUDE_LEVEL__	/* { dg-warning "undefining" } */
+#define __INCLUDE_LEVEL__ 42
+includelevel1 = __INCLUDE_LEVEL__	/* { dg-final { scan-file pr92296-2.i "includelevel1 = 42" } } */
+#pragma pop_macro("__INCLUDE_LEVEL__")
+includelevel2 = __INCLUDE_LEVEL__	/* { dg-final { scan-file pr92296-2.i "includelevel2 = 0" } } */
+
+#pragma push_macro("__COUNTER__")
+#undef __COUNTER__	/* { dg-warning "undefining" } */
+#define __COUNTER__ 172
+counter1 = __COUNTER__	/* { dg-final { scan-file pr92296-2.i "counter1 = 172" } } */
+#pragma pop_macro("__COUNTER__")
+counter2 = __COUNTER__	/* { dg-final { scan-file-not pr92296-2.i "counter2 = 172" } } */
+
+#pragma push_macro("__has_attribute")
+#undef __has_attribute	/* { dg-warning "undefining" } */
+#define __has_attribute(x) 0
+hasattr1 = __has_attribute(noreturn)	/* { dg-final { scan-file pr92296-2.i "hasattr1 = 0" } } */
+#pragma pop_macro("__has_attribute")
+hasattr2 = __has_attribute(noreturn)	/* { dg-final { scan-file-not pr92296-2.i "hasattr2 = 0" } } */
+
+#pragma push_macro("__has_cpp_attribute")
+#undef __has_cpp_attribute	/* { dg-warning "undefining" } */
+#define __has_cpp_attribute(x) 0
+hasattrcpp1 = __has_cpp_attribute(noreturn)	/* { dg-final { scan-file pr92296-2.i "hasattrcpp1 = 0" } } */
+#pragma pop_macro("__has_cpp_attribute")
+hasattrcpp2 = __has_cpp_attribute(noreturn)	/* { dg-final { scan-file-not pr92296-2.i "hasattrcpp2 = 0" } } */

[-- Attachment #10: r277819 --]
[-- Type: text/plain, Size: 1198 bytes --]

2019-11-08  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-11-05  Jakub Jelinek  <jakub@redhat.com>

	PR c++/92343
	* constexpr.c (potential_constant_expression_1): Return true rather
	than false for PREDICT_EXPR.

	* g++.dg/cpp2a/attr-likely6.C: New test.

--- gcc/cp/constexpr.c	(revision 277818)
+++ gcc/cp/constexpr.c	(revision 277819)
@@ -6493,6 +6493,7 @@ potential_constant_expression_1 (tree t,
     case LABEL_DECL:
     case LABEL_EXPR:
     case CASE_LABEL_EXPR:
+    case PREDICT_EXPR:
     case CONST_DECL:
     case SIZEOF_EXPR:
     case ALIGNOF_EXPR:
@@ -7354,7 +7355,6 @@ potential_constant_expression_1 (tree t,
       return true;
 
     case EMPTY_CLASS_EXPR:
-    case PREDICT_EXPR:
       return false;
 
     case GOTO_EXPR:
--- gcc/testsuite/g++.dg/cpp2a/attr-likely6.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp2a/attr-likely6.C	(revision 277819)
@@ -0,0 +1,14 @@
+// PR c++/92343
+// { dg-do compile { target c++14 } }
+
+constexpr bool
+foo (bool x)
+{
+  if (x)
+    [[unlikely]] return true;
+  else
+    [[likely]] return false;
+}
+
+static_assert (foo (true), "");
+static_assert (!foo (false), "");

[-- Attachment #11: r277962 --]
[-- Type: text/plain, Size: 2986 bytes --]

2019-11-08  Jakub Jelinek  <jakub@redhat.com>

	PR c++/92384
	* function.c (assign_parm_setup_block, assign_parm_setup_stack): Don't
	copy TYPE_EMPTY_P arguments from data->entry_parm to data->stack_parm
	slot.
	(assign_parms): For TREE_ADDRESSABLE parms with TYPE_EMPTY_P type
	force creation of a unique data.stack_parm slot.

	* g++.dg/torture/pr92384.C: New test.

--- gcc/function.c	(revision 277961)
+++ gcc/function.c	(revision 277962)
@@ -3087,7 +3087,7 @@ assign_parm_setup_block (struct assign_p
 	move_block_from_reg (REGNO (entry_parm), mem,
 			     size_stored / UNITS_PER_WORD);
     }
-  else if (data->stack_parm == 0)
+  else if (data->stack_parm == 0 && !TYPE_EMPTY_P (data->passed_type))
     {
       push_to_sequence2 (all->first_conversion_insn, all->last_conversion_insn);
       emit_block_move (stack_parm, data->entry_parm, GEN_INT (size),
@@ -3488,7 +3488,9 @@ assign_parm_setup_stack (struct assign_p
       dest = validize_mem (copy_rtx (data->stack_parm));
       src = validize_mem (copy_rtx (data->entry_parm));
 
-      if (MEM_P (src))
+      if (TYPE_EMPTY_P (data->passed_type))
+	/* Empty types don't really need to be copied.  */;
+      else if (MEM_P (src))
 	{
 	  /* Use a block move to handle potentially misaligned entry_parm.  */
 	  if (!to_conversion)
@@ -3643,6 +3645,16 @@ assign_parms (tree fndecl)
 	{
 	  assign_parm_find_stack_rtl (parm, &data);
 	  assign_parm_adjust_entry_rtl (&data);
+	  /* For arguments that occupy no space in the parameter
+	     passing area, have non-zero size and have address taken,
+	     force creation of a stack slot so that they have distinct
+	     address from other parameters.  */
+	  if (TYPE_EMPTY_P (data.passed_type)
+	      && TREE_ADDRESSABLE (parm)
+	      && data.entry_parm == data.stack_parm
+	      && MEM_P (data.entry_parm)
+	      && int_size_in_bytes (data.passed_type))
+	    data.stack_parm = NULL_RTX;
 	}
       /* Record permanently how this parm was passed.  */
       if (data.arg.pass_by_reference)
--- gcc/testsuite/g++.dg/torture/pr92384.C	(nonexistent)
+++ gcc/testsuite/g++.dg/torture/pr92384.C	(revision 277962)
@@ -0,0 +1,38 @@
+// PR c++/92384
+// { dg-do run }
+
+struct S {};
+struct T : public S { S a, b, c, d, e, f, g, h, i, j, k, l, m; };
+struct U { long long a, b, c; };
+
+U
+foo (S, S, S, T, T, T, U g)
+{
+  return g;
+}
+
+__attribute__((noipa)) bool
+bar (S a, S b, S c, T d, T e, T f, U g, void **h)
+{
+  h[0] = (void *) &a;
+  h[1] = (void *) &b;
+  h[2] = (void *) &c;
+  h[3] = (void *) &d;
+  h[4] = (void *) &e;
+  h[5] = (void *) &f;
+  h[6] = (void *) &g;
+  asm volatile ("" : : "r" (h) : "memory");
+  return (h[0] != h[1] && h[1] != h[2] && h[2] != h[3]
+	  && h[3] != h[4] && h[4] != h[5] && h[5] != h[6]);
+}
+
+int
+main ()
+{
+  S a;
+  T b;
+  U c = { 1, 2, 3 };
+  void *d[7];
+  if (!bar (a, a, a, b, b, b, c, d))
+    __builtin_abort ();
+}

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Backports to gcc-9-branch
@ 2019-08-01  6:34 Jakub Jelinek
  0 siblings, 0 replies; 4+ messages in thread
From: Jakub Jelinek @ 2019-08-01  6:34 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 150 bytes --]

Hi!

I've backported following 5 patches from trunk to 9.2,
bootstrapped/regtested on x86_64-linux and i686-linux, committed to
gcc-9-branch.

	Jakub

[-- Attachment #2: r273543 --]
[-- Type: text/plain, Size: 6416 bytes --]

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

	Backported from mainline
	2019-07-17  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/91157
	* tree-vect-generic.c (expand_vector_comparison): Handle lhs being
	a vector boolean with scalar mode.
	(expand_vector_condition): Handle first operand being a vector boolean
	with scalar mode.
	(expand_vector_operations_1): For comparisons, don't bail out early
	if the return type is vector boolean with scalar mode, but comparison
	operand type is not.

	* gcc.target/i386/avx512f-pr91157.c: New test.
	* gcc.target/i386/avx512bw-pr91157.c: New test.

--- gcc/tree-vect-generic.c	(revision 273542)
+++ gcc/tree-vect-generic.c	(revision 273545)
@@ -382,8 +382,47 @@ expand_vector_comparison (gimple_stmt_it
   tree t;
   if (!expand_vec_cmp_expr_p (TREE_TYPE (op0), type, code)
       && !expand_vec_cond_expr_p (type, TREE_TYPE (op0), code))
-    t = expand_vector_piecewise (gsi, do_compare, type,
-				 TREE_TYPE (TREE_TYPE (op0)), op0, op1, code);
+    {
+      if (VECTOR_BOOLEAN_TYPE_P (type)
+	  && SCALAR_INT_MODE_P (TYPE_MODE (type))
+	  && known_lt (GET_MODE_BITSIZE (TYPE_MODE (type)),
+		       TYPE_VECTOR_SUBPARTS (type)
+		       * GET_MODE_BITSIZE (SCALAR_TYPE_MODE
+						(TREE_TYPE (type)))))
+	{
+	  tree inner_type = TREE_TYPE (TREE_TYPE (op0));
+	  tree part_width = TYPE_SIZE (inner_type);
+	  tree index = bitsize_int (0);
+	  int nunits = nunits_for_known_piecewise_op (TREE_TYPE (op0));
+	  int prec = GET_MODE_PRECISION (SCALAR_TYPE_MODE (type));
+	  tree ret_type = build_nonstandard_integer_type (prec, 1);
+	  tree ret_inner_type = boolean_type_node;
+	  int i;
+	  location_t loc = gimple_location (gsi_stmt (*gsi));
+	  t = build_zero_cst (ret_type);
+
+	  if (TYPE_PRECISION (ret_inner_type) != 1)
+	    ret_inner_type = build_nonstandard_integer_type (1, 1);
+	  warning_at (loc, OPT_Wvector_operation_performance,
+		      "vector operation will be expanded piecewise");
+	  for (i = 0; i < nunits;
+	       i++, index = int_const_binop (PLUS_EXPR, index, part_width))
+	    {
+	      tree a = tree_vec_extract (gsi, inner_type, op0, part_width,
+					 index);
+	      tree b = tree_vec_extract (gsi, inner_type, op1, part_width,
+					 index);
+	      tree result = gimplify_build2 (gsi, code, ret_inner_type, a, b);
+	      t = gimplify_build3 (gsi, BIT_INSERT_EXPR, ret_type, t, result,
+				   bitsize_int (i));
+	    }
+	  t = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, type, t);
+	}
+      else
+	t = expand_vector_piecewise (gsi, do_compare, type,
+				     TREE_TYPE (TREE_TYPE (op0)), op0, op1,
+				     code);
+    }
   else
     t = NULL_TREE;
 
@@ -879,6 +918,7 @@ expand_vector_condition (gimple_stmt_ite
   tree a1 = a;
   tree a2 = NULL_TREE;
   bool a_is_comparison = false;
+  bool a_is_scalar_bitmask = false;
   tree b = gimple_assign_rhs2 (stmt);
   tree c = gimple_assign_rhs3 (stmt);
   vec<constructor_elt, va_gc> *v;
@@ -942,6 +982,20 @@ expand_vector_condition (gimple_stmt_ite
   warning_at (loc, OPT_Wvector_operation_performance,
 	      "vector condition will be expanded piecewise");
 
+  if (!a_is_comparison
+      && VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (a))
+      && SCALAR_INT_MODE_P (TYPE_MODE (TREE_TYPE (a)))
+      && known_lt (GET_MODE_BITSIZE (TYPE_MODE (TREE_TYPE (a))),
+		   TYPE_VECTOR_SUBPARTS (TREE_TYPE (a))
+		   * GET_MODE_BITSIZE (SCALAR_TYPE_MODE
+						(TREE_TYPE (TREE_TYPE (a))))))
+    {
+      a_is_scalar_bitmask = true;
+      int prec = GET_MODE_PRECISION (SCALAR_TYPE_MODE (TREE_TYPE (a)));
+      tree atype = build_nonstandard_integer_type (prec, 1);
+      a = gimplify_build1 (gsi, VIEW_CONVERT_EXPR, atype, a);
+    }
+
   int nunits = nunits_for_known_piecewise_op (type);
   vec_alloc (v, nunits);
   for (i = 0; i < nunits; i++)
@@ -957,6 +1011,14 @@ expand_vector_condition (gimple_stmt_ite
 				       comp_width, comp_index);
 	  aa = fold_build2 (TREE_CODE (a), cond_type, aa1, aa2);
 	}
+      else if (a_is_scalar_bitmask)
+	{
+	  wide_int w = wi::set_bit_in_zero (i, TYPE_PRECISION (TREE_TYPE (a)));
+	  result = gimplify_build2 (gsi, BIT_AND_EXPR, TREE_TYPE (a),
+				    a, wide_int_to_tree (TREE_TYPE (a), w));
+	  aa = fold_build2 (NE_EXPR, boolean_type_node, result,
+			    build_zero_cst (TREE_TYPE (a)));
+	}
       else
 	aa = tree_vec_extract (gsi, cond_type, a, width, index);
       result = gimplify_build3 (gsi, COND_EXPR, inner_type, aa, bb, cc);
@@ -1941,7 +2003,11 @@ expand_vector_operations_1 (gimple_stmt_
   /* A scalar operation pretending to be a vector one.  */
   if (VECTOR_BOOLEAN_TYPE_P (type)
       && !VECTOR_MODE_P (TYPE_MODE (type))
-      && TYPE_MODE (type) != BLKmode)
+      && TYPE_MODE (type) != BLKmode
+      && (TREE_CODE_CLASS (gimple_assign_rhs_code (stmt)) != tcc_comparison
+	  || (VECTOR_BOOLEAN_TYPE_P (TREE_TYPE (rhs1))
+	      && !VECTOR_MODE_P (TYPE_MODE (TREE_TYPE (rhs1)))
+	      && TYPE_MODE (TREE_TYPE (rhs1)) != BLKmode)))
     return;
 
   /* If the vector operation is operating on all same vector elements
--- gcc/testsuite/gcc.target/i386/avx512bw-pr91157.c	(nonexistent)
+++ gcc/testsuite/gcc.target/i386/avx512bw-pr91157.c	(revision 273543)
@@ -0,0 +1,6 @@
+/* PR tree-optimization/91157 */
+/* { dg-do run { target { avx512bw && lp64 } } } */
+/* { dg-options "-O2 -mavx512bw -fexceptions -fnon-call-exceptions -fsignaling-nans" } */
+
+#define AVX512BW
+#include "avx512f-pr91157.c"
--- gcc/testsuite/gcc.target/i386/avx512f-pr91157.c	(nonexistent)
+++ gcc/testsuite/gcc.target/i386/avx512f-pr91157.c	(revision 273543)
@@ -0,0 +1,29 @@
+/* PR tree-optimization/91157 */
+/* { dg-do run { target { avx512f && lp64 } } } */
+/* { dg-options "-O2 -mavx512f -fexceptions -fnon-call-exceptions -fsignaling-nans" } */
+
+#include "avx512f-helper.h"
+
+typedef long double V __attribute__ ((vector_size (4 * sizeof (long double))));
+typedef __int128 W __attribute__ ((vector_size (4 * sizeof (__int128))));
+
+__attribute__((noipa)) W
+foo (V x)
+{
+  return x == 0;
+}
+
+static void
+test_512 (void)
+{
+  V a = { 5.0L, 0.0L, -0.0L, -17.0L };
+  V b = { -0.0L, 16.0L, 0.0L, 18.0L };
+  V c = { 6.0L, 7.0L, 8.0L, 0.0L };
+  W ar = foo (a);
+  W br = foo (b);
+  W cr = foo (c);
+  if (ar[0] != 0 || ar[1] != -1 || ar[2] != -1 || ar[3] != 0
+      || br[0] != -1 || br[1] != 0 || br[2] != -1 || br[3] != 0
+      || cr[0] != 0 || cr[1] != 0 || cr[2] != 0 || cr[3] != -1)
+    __builtin_abort ();
+}

[-- Attachment #3: r273897 --]
[-- Type: text/plain, Size: 2176 bytes --]

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

	Backported from mainline
	2019-07-30  Jakub Jelinek  <jakub@redhat.com>

	PR target/91150
	* config/i386/i386.c (expand_vec_perm_blend): Change mask type
	from unsigned to unsigned HOST_WIDE_INT.  For E_V64QImode cast
	comparison to unsigned HOST_WIDE_INT before shifting it left.

	* gcc.target/i386/avx512bw-pr91150.c: New test.

--- gcc/config/i386/i386.c	(revision 273896)
+++ gcc/config/i386/i386.c	(revision 273897)
@@ -16385,7 +16385,8 @@ static bool
 expand_vec_perm_blend (struct expand_vec_perm_d *d)
 {
   machine_mode mmode, vmode = d->vmode;
-  unsigned i, mask, nelt = d->nelt;
+  unsigned i, nelt = d->nelt;
+  unsigned HOST_WIDE_INT mask;
   rtx target, op0, op1, maskop, x;
   rtx rperm[32], vperm;
 
@@ -16439,7 +16440,7 @@ expand_vec_perm_blend (struct expand_vec
     case E_V16SImode:
     case E_V8DImode:
       for (i = 0; i < nelt; ++i)
-	mask |= (d->perm[i] >= nelt) << i;
+	mask |= ((unsigned HOST_WIDE_INT) (d->perm[i] >= nelt)) << i;
       break;
 
     case E_V2DImode:
--- gcc/testsuite/gcc.target/i386/avx512bw-pr91150.c	(nonexistent)
+++ gcc/testsuite/gcc.target/i386/avx512bw-pr91150.c	(revision 273897)
@@ -0,0 +1,37 @@
+/* PR target/91150 */
+/* { dg-do run } */
+/* { dg-options "-O2 -mavx512bw" } */
+/* { dg-require-effective-target avx512bw } */
+
+#include "avx512bw-check.h"
+
+typedef unsigned char V __attribute__((vector_size (64)));
+
+__attribute__((noipa)) void
+foo (V *x, V *y, V *z)
+{
+  *x = __builtin_shuffle (*y, *z, (V) { 0, 1, 2, 3, 4, 5, 6, 7, 8,
+					9, 10, 11, 12, 13, 14, 15,
+					80, 81, 82, 83, 84, 85, 86, 87,
+					88, 89, 90, 91, 92, 93, 94, 95,
+					96, 97, 98, 99, 100, 101, 102, 103,
+					104, 105, 106, 107, 108, 109, 110, 111,
+				        112, 113, 114, 115, 116, 117, 118, 119,
+					120, 121, 122, 123, 124, 125, 126, 127 });
+}
+
+static void
+avx512bw_test (void)
+{
+  union U { unsigned char a[64]; V v; } a, b, c;
+  int i;
+  for (i = 0; i < 64; i++)
+    {
+      b.a[i] = i + 1;
+      c.a[i] = i + 65;
+    }
+  foo (&a.v, &b.v, &c.v);
+  for (i = 0; i < 64; i++)
+    if (a.a[i] != (i < 16 ? i + 1 : i + 65))
+      __builtin_abort ();
+}

[-- Attachment #4: r273898 --]
[-- Type: text/plain, Size: 3428 bytes --]

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

	Backported from mainline
	2019-07-30  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/91216
	* omp-low.c (global_nonaddressable_vars): New variable.
	(use_pointer_for_field): For global decls, if they are non-addressable,
	remember it in the global_nonaddressable_vars bitmap, if they are
	addressable and in the global_nonaddressable_vars bitmap, ignore their
	TREE_ADDRESSABLE bit.
	(omp_copy_decl_2): Clear TREE_ADDRESSABLE also on private copies of
	vars in global_nonaddressable_vars bitmap.
	(execute_lower_omp): Free global_nonaddressable_vars bitmap.

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

--- gcc/omp-low.c	(revision 273897)
+++ gcc/omp-low.c	(revision 273898)
@@ -162,6 +162,7 @@ static splay_tree all_contexts;
 static int taskreg_nesting_level;
 static int target_nesting_level;
 static bitmap task_shared_vars;
+static bitmap global_nonaddressable_vars;
 static vec<omp_context *> taskreg_contexts;
 
 static void scan_omp (gimple_seq *, omp_context *);
@@ -426,7 +427,26 @@ use_pointer_for_field (tree decl, omp_co
 
       /* Do not use copy-in/copy-out for variables that have their
 	 address taken.  */
-      if (TREE_ADDRESSABLE (decl))
+      if (is_global_var (decl))
+	{
+	  /* For file scope vars, track whether we've seen them as
+	     non-addressable initially and in that case, keep the same
+	     answer for the duration of the pass, even when they are made
+	     addressable later on e.g. through reduction expansion.  Global
+	     variables which weren't addressable before the pass will not
+	     have their privatized copies address taken.  See PR91216.  */
+	  if (!TREE_ADDRESSABLE (decl))
+	    {
+	      if (!global_nonaddressable_vars)
+		global_nonaddressable_vars = BITMAP_ALLOC (NULL);
+	      bitmap_set_bit (global_nonaddressable_vars, DECL_UID (decl));
+	    }
+	  else if (!global_nonaddressable_vars
+		   || !bitmap_bit_p (global_nonaddressable_vars,
+				     DECL_UID (decl)))
+	    return true;
+	}
+      else if (TREE_ADDRESSABLE (decl))
 	return true;
 
       /* lower_send_shared_vars only uses copy-in, but not copy-out
@@ -504,8 +524,10 @@ omp_copy_decl_2 (tree var, tree name, tr
      it's address.  But we don't need to take address of privatizations
      from that var.  */
   if (TREE_ADDRESSABLE (var)
-      && task_shared_vars
-      && bitmap_bit_p (task_shared_vars, DECL_UID (var)))
+      && ((task_shared_vars
+	   && bitmap_bit_p (task_shared_vars, DECL_UID (var)))
+	  || (global_nonaddressable_vars
+	      && bitmap_bit_p (global_nonaddressable_vars, DECL_UID (var)))))
     TREE_ADDRESSABLE (copy) = 0;
   ctx->block_vars = copy;
 
@@ -12730,6 +12752,7 @@ execute_lower_omp (void)
       all_contexts = NULL;
     }
   BITMAP_FREE (task_shared_vars);
+  BITMAP_FREE (global_nonaddressable_vars);
 
   /* If current function is a method, remove artificial dummy VAR_DECL created
      for non-static data member privatization, they aren't needed for
--- gcc/testsuite/gcc.dg/gomp/pr91216.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/gomp/pr91216.c	(revision 273898)
@@ -0,0 +1,20 @@
+/* PR middle-end/91216 */
+
+int r;
+
+void
+foo (int *a)
+{
+  int i;
+  #pragma omp for reduction(+:r)
+  for (i = 0; i < 64; i++)
+    a[i] = i;
+  #pragma omp for private (r)
+  for (i = 0; i < 64; i++)
+    {
+      r = 0;
+      #pragma omp parallel shared(r)
+      #pragma omp master
+      r = r + 1;
+    }
+}

[-- Attachment #5: r273922 --]
[-- Type: text/plain, Size: 7171 bytes --]

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

	Backported from mainline
	2019-07-31  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/91301
	* gimplify.c (gimplify_omp_for): If for class iterator on
	distribute parallel for there is no data sharing clause
	on inner_for_stmt, look for private clause on combined
	parallel too and if found, move it to inner_for_stmt.

	* testsuite/libgomp.c++/for-27.C: New test.

--- gcc/gimplify.c	(revision 273921)
+++ gcc/gimplify.c	(revision 273922)
@@ -10663,6 +10663,22 @@ gimplify_omp_for (tree *expr_p, gimple_s
 		  && OMP_CLAUSE_DECL (*pc) == orig_decl)
 		break;
 	    if (*pc == NULL_TREE)
+	      {
+		tree *spc;
+		for (spc = &OMP_PARALLEL_CLAUSES (*data[1]);
+		     *spc; spc = &OMP_CLAUSE_CHAIN (*spc))
+		  if (OMP_CLAUSE_CODE (*spc) == OMP_CLAUSE_PRIVATE
+		      && OMP_CLAUSE_DECL (*spc) == orig_decl)
+		    break;
+		if (*spc)
+		  {
+		    tree c = *spc;
+		    *spc = OMP_CLAUSE_CHAIN (c);
+		    OMP_CLAUSE_CHAIN (c) = NULL_TREE;
+		    *pc = c;
+		  }
+	      }
+	    if (*pc == NULL_TREE)
 	      ;
 	    else if (OMP_CLAUSE_CODE (*pc) == OMP_CLAUSE_PRIVATE)
 	      {
--- libgomp/testsuite/libgomp.c++/for-27.C	(nonexistent)
+++ libgomp/testsuite/libgomp.c++/for-27.C	(revision 273922)
@@ -0,0 +1,169 @@
+// { dg-do run }
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+extern "C" void abort ();
+
+int a[2000];
+
+template <typename T>
+class I
+{
+public:
+  typedef ptrdiff_t difference_type;
+  I ();
+  ~I ();
+  I (T *);
+  I (const I &);
+  T &operator * ();
+  T *operator -> ();
+  T &operator [] (const difference_type &) const;
+  I &operator = (const I &);
+  I &operator ++ ();
+  I operator ++ (int);
+  I &operator -- ();
+  I operator -- (int);
+  I &operator += (const difference_type &);
+  I &operator -= (const difference_type &);
+  I operator + (const difference_type &) const;
+  I operator - (const difference_type &) const;
+  template <typename S> friend bool operator == (I<S> &, I<S> &);
+  template <typename S> friend bool operator == (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator < (I<S> &, I<S> &);
+  template <typename S> friend bool operator < (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator <= (I<S> &, I<S> &);
+  template <typename S> friend bool operator <= (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator > (I<S> &, I<S> &);
+  template <typename S> friend bool operator > (const I<S> &, const I<S> &);
+  template <typename S> friend bool operator >= (I<S> &, I<S> &);
+  template <typename S> friend bool operator >= (const I<S> &, const I<S> &);
+  template <typename S> friend typename I<S>::difference_type operator - (I<S> &, I<S> &);
+  template <typename S> friend typename I<S>::difference_type operator - (const I<S> &, const I<S> &);
+  template <typename S> friend I<S> operator + (typename I<S>::difference_type , const I<S> &);
+private:
+  T *p;
+};
+template <typename T> I<T>::I () : p (0) {}
+template <typename T> I<T>::~I () {}
+template <typename T> I<T>::I (T *x) : p (x) {}
+template <typename T> I<T>::I (const I &x) : p (x.p) {}
+template <typename T> T &I<T>::operator * () { return *p; }
+template <typename T> T *I<T>::operator -> () { return p; }
+template <typename T> T &I<T>::operator [] (const difference_type &x) const { return p[x]; }
+template <typename T> I<T> &I<T>::operator = (const I &x) { p = x.p; return *this; }
+template <typename T> I<T> &I<T>::operator ++ () { ++p; return *this; }
+template <typename T> I<T> I<T>::operator ++ (int) { return I (p++); }
+template <typename T> I<T> &I<T>::operator -- () { --p; return *this; }
+template <typename T> I<T> I<T>::operator -- (int) { return I (p--); }
+template <typename T> I<T> &I<T>::operator += (const difference_type &x) { p += x; return *this; }
+template <typename T> I<T> &I<T>::operator -= (const difference_type &x) { p -= x; return *this; }
+template <typename T> I<T> I<T>::operator + (const difference_type &x) const { return I (p + x); }
+template <typename T> I<T> I<T>::operator - (const difference_type &x) const { return I (p - x); }
+template <typename T> bool operator == (I<T> &x, I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator == (const I<T> &x, const I<T> &y) { return x.p == y.p; }
+template <typename T> bool operator != (I<T> &x, I<T> &y) { return !(x == y); }
+template <typename T> bool operator != (const I<T> &x, const I<T> &y) { return !(x == y); }
+template <typename T> bool operator < (I<T> &x, I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator < (const I<T> &x, const I<T> &y) { return x.p < y.p; }
+template <typename T> bool operator <= (I<T> &x, I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator <= (const I<T> &x, const I<T> &y) { return x.p <= y.p; }
+template <typename T> bool operator > (I<T> &x, I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator > (const I<T> &x, const I<T> &y) { return x.p > y.p; }
+template <typename T> bool operator >= (I<T> &x, I<T> &y) { return x.p >= y.p; }
+template <typename T> bool operator >= (const I<T> &x, const I<T> &y) { return x.p >= y.p; }
+template <typename T> typename I<T>::difference_type operator - (I<T> &x, I<T> &y) { return x.p - y.p; }
+template <typename T> typename I<T>::difference_type operator - (const I<T> &x, const I<T> &y) { return x.p - y.p; }
+template <typename T> I<T> operator + (typename I<T>::difference_type x, const I<T> &y) { return I<T> (x + y.p); }
+
+template <typename T>
+class J
+{
+public:
+  J(const I<T> &x, const I<T> &y) : b (x), e (y) {}
+  const I<T> &begin ();
+  const I<T> &end ();
+private:
+  I<T> b, e;
+};
+
+template <typename T> const I<T> &J<T>::begin () { return b; }
+template <typename T> const I<T> &J<T>::end () { return e; }
+
+int results[2000];
+
+template <typename T> 
+void
+baz (I<T> &i)
+{
+  if (*i < 0 || *i >= 2000)
+    abort ();
+  results[*i]++;
+}
+
+static inline void
+baz (int i)
+{
+  results[i]++;
+}
+
+void
+f1 ()
+{
+#pragma omp simd
+  for (auto i : a)
+    baz (i);
+}
+
+void
+f2 (const I<int> &x, const I<int> &y)
+{
+  I<int> i;
+#pragma omp distribute parallel for
+  for (i = x; i <= y; i += 6)
+    baz (*i);
+}
+
+void
+f3 (const I<int> &x, const I<int> &y)
+{
+  I<int> i;
+#pragma omp distribute parallel for private (i)
+  for (i = x; i < y - 1; i = 1 - 6 + 7 + i)
+    baz (*i);
+}
+
+void
+f4 (const I<int> &x, const I<int> &y)
+{
+  I<int> i;
+#pragma omp teams distribute parallel for lastprivate (i)
+  for (i = x + 2000 - 64; i > y + 10; --i)
+    baz (*i);
+}
+
+#define check(expr) \
+  for (int i = 0; i < 2000; i++)			\
+    if (expr)						\
+      {							\
+	if (results[i] != 1)				\
+	  abort ();					\
+	results[i] = 0;					\
+      }							\
+    else if (results[i])				\
+      abort ()
+
+int
+main ()
+{
+  for (int i = 0; i < 2000; i++)
+    a[i] = i;
+  f1 ();
+  check (1);
+  #pragma omp teams
+  f2 (&a[10], &a[1990]);
+  check (i >= 10 && i <= 1990 && (i - 10) % 6 == 0);
+  #pragma omp teams
+  f3 (&a[0], &a[1999]);
+  check (i < 1998 && (i & 1) == 0);
+  f4 (&a[0], &a[30]);
+  check (i > 40 && i <= 2000 - 64);
+}

[-- Attachment #6: r273935 --]
[-- Type: text/plain, Size: 767 bytes --]

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

	Backported from mainline
	2019-07-31  Jakub Jelinek  <jakub@redhat.com>

	PR c/91192
	* c-parser.c (c_parser_sizeof_expression): Call set_c_expr_source_range
	even if finish is UNKNOWN_LOCATION, just use start as finish in that
	case.

--- gcc/c/c-parser.c	(revision 273934)
+++ gcc/c/c-parser.c	(revision 273935)
@@ -7477,8 +7477,9 @@ c_parser_sizeof_expression (c_parser *pa
 	error_at (expr_loc, "%<sizeof%> applied to a bit-field");
       result = c_expr_sizeof_expr (expr_loc, expr);
     }
-  if (finish != UNKNOWN_LOCATION)
-    set_c_expr_source_range (&result, start, finish);
+  if (finish == UNKNOWN_LOCATION)
+    finish = start;
+  set_c_expr_source_range (&result, start, finish);
   return result;
 }
 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Backports to gcc-9-branch
@ 2019-05-17 20:00 Jakub Jelinek
  0 siblings, 0 replies; 4+ messages in thread
From: Jakub Jelinek @ 2019-05-17 20:00 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 144 bytes --]

Hi!

I've backported following 11 patches from trunk to gcc-9-branch,
bootstrapped/regtested on x86_64-linux and i686-linux, committed.

	Jakub

[-- Attachment #2: r270606 --]
[-- Type: text/plain, Size: 9616 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-04-26  Jakub Jelinek  <jakub@redhat.com>

	PR debug/90197
	* c-tree.h (c_finish_loop): Add 2 further location_t arguments.
	* c-parser.c (c_parser_while_statement): Adjust c_finish_loop caller.
	(c_parser_do_statement): Likewise.
	(c_parser_for_statement): Likewise.  Formatting fixes.
	* c-typeck.c (c_finish_loop): Add COND_LOCUS and INCR_LOCUS arguments,
	emit DEBUG_BEGIN_STMTs if needed.

--- gcc/c/c-tree.h	(revision 270605)
+++ gcc/c/c-tree.h	(revision 270606)
@@ -694,7 +694,8 @@ extern int c_types_compatible_p (tree, t
 extern tree c_begin_compound_stmt (bool);
 extern tree c_end_compound_stmt (location_t, tree, bool);
 extern void c_finish_if_stmt (location_t, tree, tree, tree);
-extern void c_finish_loop (location_t, tree, tree, tree, tree, tree, bool);
+extern void c_finish_loop (location_t, location_t, tree, location_t, tree,
+			   tree, tree, tree, bool);
 extern tree c_begin_stmt_expr (void);
 extern tree c_finish_stmt_expr (location_t, tree);
 extern tree c_process_expr_stmt (location_t, tree);
--- gcc/c/c-parser.c	(revision 270605)
+++ gcc/c/c-parser.c	(revision 270606)
@@ -6001,7 +6001,8 @@ c_parser_while_statement (c_parser *pars
   location_t loc_after_labels;
   bool open_brace = c_parser_next_token_is (parser, CPP_OPEN_BRACE);
   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
-  c_finish_loop (loc, cond, NULL, body, c_break_label, c_cont_label, true);
+  c_finish_loop (loc, loc, cond, UNKNOWN_LOCATION, NULL, body,
+		 c_break_label, c_cont_label, true);
   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
   c_parser_maybe_reclassify_token (parser);
 
@@ -6046,6 +6047,7 @@ c_parser_do_statement (c_parser *parser,
   c_break_label = save_break;
   new_cont = c_cont_label;
   c_cont_label = save_cont;
+  location_t cond_loc = c_parser_peek_token (parser)->location;
   cond = c_parser_paren_condition (parser);
   if (ivdep && cond != error_mark_node)
     cond = build3 (ANNOTATE_EXPR, TREE_TYPE (cond), cond,
@@ -6059,7 +6061,8 @@ c_parser_do_statement (c_parser *parser,
  		   build_int_cst (integer_type_node, unroll));
   if (!c_parser_require (parser, CPP_SEMICOLON, "expected %<;%>"))
     c_parser_skip_to_end_of_block_or_statement (parser);
-  c_finish_loop (loc, cond, NULL, body, new_break, new_cont, false);
+  c_finish_loop (loc, cond_loc, cond, UNKNOWN_LOCATION, NULL, body,
+		 new_break, new_cont, false);
   add_stmt (c_end_compound_stmt (loc, block, flag_isoc99));
 }
 
@@ -6132,7 +6135,9 @@ c_parser_for_statement (c_parser *parser
   /* Silence the bogus uninitialized warning.  */
   tree collection_expression = NULL;
   location_t loc = c_parser_peek_token (parser)->location;
-  location_t for_loc = c_parser_peek_token (parser)->location;
+  location_t for_loc = loc;
+  location_t cond_loc = UNKNOWN_LOCATION;
+  location_t incr_loc = UNKNOWN_LOCATION;
   bool is_foreach_statement = false;
   gcc_assert (c_parser_next_token_is_keyword (parser, RID_FOR));
   token_indent_info for_tinfo
@@ -6166,7 +6171,8 @@ c_parser_for_statement (c_parser *parser
 	      c_parser_consume_token (parser);
 	      is_foreach_statement = true;
 	      if (check_for_loop_decls (for_loc, true) == NULL_TREE)
-		c_parser_error (parser, "multiple iterating variables in fast enumeration");
+		c_parser_error (parser, "multiple iterating variables in "
+					"fast enumeration");
 	    }
 	  else
 	    check_for_loop_decls (for_loc, flag_isoc99);
@@ -6196,7 +6202,8 @@ c_parser_for_statement (c_parser *parser
 		  c_parser_consume_token (parser);
 		  is_foreach_statement = true;
 		  if (check_for_loop_decls (for_loc, true) == NULL_TREE)
-		    c_parser_error (parser, "multiple iterating variables in fast enumeration");
+		    c_parser_error (parser, "multiple iterating variables in "
+					    "fast enumeration");
 		}
 	      else
 		check_for_loop_decls (for_loc, flag_isoc99);
@@ -6218,15 +6225,18 @@ c_parser_for_statement (c_parser *parser
 		c_parser_consume_token (parser);
 		is_foreach_statement = true;
 		if (! lvalue_p (init_expression))
-		  c_parser_error (parser, "invalid iterating variable in fast enumeration");
-		object_expression = c_fully_fold (init_expression, false, NULL);
+		  c_parser_error (parser, "invalid iterating variable in "
+					  "fast enumeration");
+		object_expression
+		  = c_fully_fold (init_expression, false, NULL);
 	      }
 	    else
 	      {
 		ce = convert_lvalue_to_rvalue (loc, ce, true, false);
 		init_expression = ce.value;
 		c_finish_expr_stmt (loc, init_expression);
-		c_parser_skip_until_found (parser, CPP_SEMICOLON, "expected %<;%>");
+		c_parser_skip_until_found (parser, CPP_SEMICOLON,
+					   "expected %<;%>");
 	      }
 	  }
 	}
@@ -6235,18 +6245,19 @@ c_parser_for_statement (c_parser *parser
       gcc_assert (!parser->objc_could_be_foreach_context);
       if (!is_foreach_statement)
 	{
+	  cond_loc = c_parser_peek_token (parser)->location;
 	  if (c_parser_next_token_is (parser, CPP_SEMICOLON))
 	    {
 	      if (ivdep)
 		{
-		  c_parser_error (parser, "missing loop condition in loop with "
-				  "%<GCC ivdep%> pragma");
+		  c_parser_error (parser, "missing loop condition in loop "
+					  "with %<GCC ivdep%> pragma");
 		  cond = error_mark_node;
 		}
 	      else if (unroll)
 		{
-		  c_parser_error (parser, "missing loop condition in loop with "
-				  "%<GCC unroll%> pragma");
+		  c_parser_error (parser, "missing loop condition in loop "
+					  "with %<GCC unroll%> pragma");
 		  cond = error_mark_node;
 		}
 	      else
@@ -6275,11 +6286,13 @@ c_parser_for_statement (c_parser *parser
       /* Parse the increment expression (the third expression in a
 	 for-statement).  In the case of a foreach-statement, this is
 	 the expression that follows the 'in'.  */
+      loc = incr_loc = c_parser_peek_token (parser)->location;
       if (c_parser_next_token_is (parser, CPP_CLOSE_PAREN))
 	{
 	  if (is_foreach_statement)
 	    {
-	      c_parser_error (parser, "missing collection in fast enumeration");
+	      c_parser_error (parser,
+			      "missing collection in fast enumeration");
 	      collection_expression = error_mark_node;
 	    }
 	  else
@@ -6288,8 +6301,8 @@ c_parser_for_statement (c_parser *parser
       else
 	{
 	  if (is_foreach_statement)
-	    collection_expression = c_fully_fold (c_parser_expression (parser).value,
-						  false, NULL);
+	    collection_expression
+	      = c_fully_fold (c_parser_expression (parser).value, false, NULL);
 	  else
 	    {
 	      struct c_expr ce = c_parser_expression (parser);
@@ -6312,10 +6325,14 @@ c_parser_for_statement (c_parser *parser
   body = c_parser_c99_block_statement (parser, if_p, &loc_after_labels);
 
   if (is_foreach_statement)
-    objc_finish_foreach_loop (loc, object_expression, collection_expression, body, c_break_label, c_cont_label);
+    objc_finish_foreach_loop (for_loc, object_expression,
+			      collection_expression, body, c_break_label,
+			      c_cont_label);
   else
-    c_finish_loop (loc, cond, incr, body, c_break_label, c_cont_label, true);
-  add_stmt (c_end_compound_stmt (loc, block, flag_isoc99 || c_dialect_objc ()));
+    c_finish_loop (for_loc, cond_loc, cond, incr_loc, incr, body,
+		   c_break_label, c_cont_label, true);
+  add_stmt (c_end_compound_stmt (for_loc, block,
+				 flag_isoc99 || c_dialect_objc ()));
   c_parser_maybe_reclassify_token (parser);
 
   token_indent_info next_tinfo
--- gcc/c/c-typeck.c	(revision 270605)
+++ gcc/c/c-typeck.c	(revision 270606)
@@ -10858,11 +10858,14 @@ c_finish_if_stmt (location_t if_locus, t
    the beginning of the loop.  COND is the loop condition.  COND_IS_FIRST
    is false for DO loops.  INCR is the FOR increment expression.  BODY is
    the statement controlled by the loop.  BLAB is the break label.  CLAB is
-   the continue label.  Everything is allowed to be NULL.  */
+   the continue label.  Everything is allowed to be NULL.
+   COND_LOCUS is the location of the loop condition, INCR_LOCUS is the
+   location of the FOR increment expression.  */
 
 void
-c_finish_loop (location_t start_locus, tree cond, tree incr, tree body,
-	       tree blab, tree clab, bool cond_is_first)
+c_finish_loop (location_t start_locus, location_t cond_locus, tree cond,
+	       location_t incr_locus, tree incr, tree body, tree blab,
+	       tree clab, bool cond_is_first)
 {
   tree entry = NULL, exit = NULL, t;
 
@@ -10904,12 +10907,8 @@ c_finish_loop (location_t start_locus, t
 	    }
 
 	  t = build_and_jump (&blab);
-	  if (cond_is_first)
-	    exit = fold_build3_loc (start_locus,
-				COND_EXPR, void_type_node, cond, exit, t);
-	  else
-	    exit = fold_build3_loc (input_location,
-				COND_EXPR, void_type_node, cond, exit, t);
+	  exit = fold_build3_loc (cond_is_first ? start_locus : input_location,
+				  COND_EXPR, void_type_node, cond, exit, t);
 	}
       else
 	{
@@ -10930,9 +10929,23 @@ c_finish_loop (location_t start_locus, t
   if (clab)
     add_stmt (build1 (LABEL_EXPR, void_type_node, clab));
   if (incr)
-    add_stmt (incr);
+    {
+      if (MAY_HAVE_DEBUG_MARKER_STMTS && incr_locus != UNKNOWN_LOCATION)
+	{
+	  t = build0 (DEBUG_BEGIN_STMT, void_type_node);
+	  SET_EXPR_LOCATION (t, incr_locus);
+	  add_stmt (t);
+	}
+      add_stmt (incr);
+    }
   if (entry)
     add_stmt (entry);
+  if (MAY_HAVE_DEBUG_MARKER_STMTS && cond_locus != UNKNOWN_LOCATION)
+    {
+      t = build0 (DEBUG_BEGIN_STMT, void_type_node);
+      SET_EXPR_LOCATION (t, cond_locus);
+      add_stmt (t);
+    }
   if (exit)
     add_stmt (exit);
   if (blab)

[-- Attachment #3: r270835 --]
[-- Type: text/plain, Size: 1397 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-03  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/90303
	* ipa-devirt.c (obj_type_ref_class, get_odr_type): Don't use
	TYPE_CANONICAL for TYPE_STRUCTURAL_EQUALITY_P types in !in_lto_p mode.

	* g++.target/i386/pr90303.C: New test.

--- gcc/ipa-devirt.c	(revision 270834)
+++ gcc/ipa-devirt.c	(revision 270835)
@@ -2020,7 +2020,7 @@ obj_type_ref_class (const_tree ref)
   ref = TREE_VALUE (TYPE_ARG_TYPES (ref));
   gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
   tree ret = TREE_TYPE (ref);
-  if (!in_lto_p)
+  if (!in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (ret))
     ret = TYPE_CANONICAL (ret);
   else
     ret = get_odr_type (ret)->type;
@@ -2042,7 +2042,7 @@ get_odr_type (tree type, bool insert)
   int base_id = -1;
 
   type = TYPE_MAIN_VARIANT (type);
-  if (!in_lto_p)
+  if (!in_lto_p && !TYPE_STRUCTURAL_EQUALITY_P (type))
     type = TYPE_CANONICAL (type);
 
   gcc_checking_assert (can_be_name_hashed_p (type)
--- gcc/testsuite/g++.target/i386/pr90303.C	(nonexistent)
+++ gcc/testsuite/g++.target/i386/pr90303.C	(revision 270835)
@@ -0,0 +1,8 @@
+// PR tree-optimization/90303
+// { dg-do compile { target ia32 } }
+// { dg-additional-options "-O2" }
+
+struct A { virtual void foo (); };
+template <class> class B : A {};
+typedef void (__attribute__((fastcall)) F) ();
+B<F> e;

[-- Attachment #4: r271055 --]
[-- Type: text/plain, Size: 3308 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-10  Jakub Jelinek  <jakub@redhat.com>

	PR pch/90326
cp/
	* config-lang.in (gtfiles): Remove c-family/c-lex.c, add
	c-family/c-cppbuiltin.c.
objc/
	* config-lang.in (gtfiles): Add c-family/c-format.c.
objcp/
	* config-lang.in (gtfiles): Don't add c-family/c-cppbuiltin.c.
testsuite/
	* g++.dg/pch/pr90326.C: New test.
	* g++.dg/pch/pr90326.Hs: New file.

--- gcc/cp/config-lang.in	(revision 271054)
+++ gcc/cp/config-lang.in	(revision 271055)
@@ -37,7 +37,7 @@ gtfiles="\
 \$(srcdir)/c-family/c-pragma.h \$(srcdir)/cp/decl.h \
 \$(srcdir)/cp/parser.h \
 \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-format.c \
-\$(srcdir)/c-family/c-lex.c \$(srcdir)/c-family/c-pragma.c \
+\$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.c \
 \$(srcdir)/cp/call.c \$(srcdir)/cp/class.c \$(srcdir)/cp/constexpr.c \
 \$(srcdir)/cp/cp-gimplify.c \
 \$(srcdir)/cp/cp-lang.c \$(srcdir)/cp/cp-objcp-common.c \
--- gcc/objc/config-lang.in	(revision 271054)
+++ gcc/objc/config-lang.in	(revision 271055)
@@ -35,4 +35,4 @@ lang_requires="c"
 # Order is important.  If you change this list, make sure you test
 # building without C++ as well; that is, remove the gcc/cp directory,
 # and build with --enable-languages=c,objc.
-gtfiles="\$(srcdir)/objc/objc-map.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/objc/objc-act.h \$(srcdir)/objc/objc-act.c \$(srcdir)/objc/objc-runtime-shared-support.c \$(srcdir)/objc/objc-gnu-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-02.c \$(srcdir)/c/c-parser.h \$(srcdir)/c/c-parser.c \$(srcdir)/c/c-tree.h \$(srcdir)/c/c-decl.c \$(srcdir)/c/c-lang.h \$(srcdir)/c/c-objc-common.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c"
+gtfiles="\$(srcdir)/objc/objc-map.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/objc/objc-act.h \$(srcdir)/objc/objc-act.c \$(srcdir)/objc/objc-runtime-shared-support.c \$(srcdir)/objc/objc-gnu-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-01.c \$(srcdir)/objc/objc-next-runtime-abi-02.c \$(srcdir)/c/c-parser.h \$(srcdir)/c/c-parser.c \$(srcdir)/c/c-tree.h \$(srcdir)/c/c-decl.c \$(srcdir)/c/c-lang.h \$(srcdir)/c/c-objc-common.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-cppbuiltin.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/c-family/c-format.c"
--- gcc/objcp/config-lang.in	(revision 271054)
+++ gcc/objcp/config-lang.in	(revision 271055)
@@ -52,7 +52,6 @@ gtfiles="$(. $srcdir/cp/config-lang.in ;
 gtfiles="$gtfiles \
 \$(srcdir)/objc/objc-act.h \
 \$(srcdir)/objc/objc-map.h \
-\$(srcdir)/c-family/c-cppbuiltin.c \
 \$(srcdir)/objc/objc-act.c \
 \$(srcdir)/objc/objc-gnu-runtime-abi-01.c \
 \$(srcdir)/objc/objc-next-runtime-abi-01.c \
--- gcc/testsuite/g++.dg/pch/pr90326.Hs	(nonexistent)
+++ gcc/testsuite/g++.dg/pch/pr90326.Hs	(revision 271055)
@@ -0,0 +1 @@
+// empty
--- gcc/testsuite/g++.dg/pch/pr90326.C	(nonexistent)
+++ gcc/testsuite/g++.dg/pch/pr90326.C	(revision 271055)
@@ -0,0 +1,9 @@
+#include "pr90326.H"
+
+int main()
+{
+  float f = __FLT_MAX__;
+  if (f == 0.0)
+    __builtin_abort ();
+  return 0;
+}

[-- Attachment #5: r271058 --]
[-- Type: text/plain, Size: 3893 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-10  Jakub Jelinek  <jakub@redhat.com>

	PR c++/90383
	* tree-inline.h (struct copy_body_data): Add do_not_fold member.
	* tree-inline.c (remap_gimple_op_r): Avoid folding expressions if
	id->do_not_fold.
	(copy_tree_body_r): Likewise.
	(copy_fn): Set id.do_not_fold to true.

	* g++.dg/cpp1y/constexpr-90383-1.C: New test.
	* g++.dg/cpp1y/constexpr-90383-2.C: New test.

--- gcc/tree-inline.h	(revision 271057)
+++ gcc/tree-inline.h	(revision 271058)
@@ -113,6 +113,9 @@ struct copy_body_data
   /* True if trees may not be unshared.  */
   bool do_not_unshare;
 
+  /* True if trees should not be folded during the copying.  */
+  bool do_not_fold;
+
   /* True if new declarations may not be created during type remapping.  */
   bool prevent_decl_creation_for_types;
 
--- gcc/tree-inline.c	(revision 271057)
+++ gcc/tree-inline.c	(revision 271058)
@@ -1101,7 +1101,7 @@ remap_gimple_op_r (tree *tp, int *walk_s
       /* Otherwise, just copy the node.  Note that copy_tree_r already
 	 knows not to copy VAR_DECLs, etc., so this is safe.  */
 
-      if (TREE_CODE (*tp) == MEM_REF)
+      if (TREE_CODE (*tp) == MEM_REF && !id->do_not_fold)
 	{
 	  /* We need to re-canonicalize MEM_REFs from inline substitutions
 	     that can happen when a pointer argument is an ADDR_EXPR.
@@ -1327,11 +1327,11 @@ copy_tree_body_r (tree *tp, int *walk_su
 	      tree type = TREE_TYPE (*tp);
 	      tree ptr = id->do_not_unshare ? *n : unshare_expr (*n);
 	      tree old = *tp;
-	      *tp = gimple_fold_indirect_ref (ptr);
+	      *tp = id->do_not_fold ? NULL : gimple_fold_indirect_ref (ptr);
 	      if (! *tp)
 	        {
 		  type = remap_type (type, id);
-		  if (TREE_CODE (ptr) == ADDR_EXPR)
+		  if (TREE_CODE (ptr) == ADDR_EXPR && !id->do_not_fold)
 		    {
 		      *tp
 		        = fold_indirect_ref_1 (EXPR_LOCATION (ptr), type, ptr);
@@ -1360,7 +1360,7 @@ copy_tree_body_r (tree *tp, int *walk_su
 	      return NULL;
 	    }
 	}
-      else if (TREE_CODE (*tp) == MEM_REF)
+      else if (TREE_CODE (*tp) == MEM_REF && !id->do_not_fold)
 	{
 	  /* We need to re-canonicalize MEM_REFs from inline substitutions
 	     that can happen when a pointer argument is an ADDR_EXPR.
@@ -1432,7 +1432,8 @@ copy_tree_body_r (tree *tp, int *walk_su
 
 	  /* Handle the case where we substituted an INDIRECT_REF
 	     into the operand of the ADDR_EXPR.  */
-	  if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF)
+	  if (TREE_CODE (TREE_OPERAND (*tp, 0)) == INDIRECT_REF
+	      && !id->do_not_fold)
 	    {
 	      tree t = TREE_OPERAND (TREE_OPERAND (*tp, 0), 0);
 	      if (TREE_TYPE (t) != TREE_TYPE (*tp))
@@ -6370,6 +6371,7 @@ copy_fn (tree fn, tree& parms, tree& res
      since front-end specific mechanisms may rely on sharing.  */
   id.regimplify = false;
   id.do_not_unshare = true;
+  id.do_not_fold = true;
 
   /* We're not inside any EH region.  */
   id.eh_lp_nr = 0;
--- gcc/testsuite/g++.dg/cpp1y/constexpr-90383-1.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-90383-1.C	(revision 271058)
@@ -0,0 +1,15 @@
+// PR c++/90383
+// { dg-do compile { target c++14 } }
+
+struct alignas(8) A { constexpr A (bool x) : a(x) {} A () = delete; bool a; };
+struct B { A b; };
+
+constexpr bool
+foo ()
+{
+  B w{A (true)};
+  w.b = A (true);
+  return w.b.a;
+}
+
+static_assert (foo (), "");
--- gcc/testsuite/g++.dg/cpp1y/constexpr-90383-2.C	(nonexistent)
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-90383-2.C	(revision 271058)
@@ -0,0 +1,22 @@
+// PR c++/90383
+// { dg-do run { target c++14 } }
+// { dg-options "-O2" }
+
+extern "C" void abort ();
+struct alignas(8) A { constexpr A (bool x) : a(x) {} A () = default; bool a; };
+struct B { A b; };
+
+constexpr bool
+foo ()
+{
+  B w{A (true)};
+  w.b = A (true);
+  return w.b.a;
+}
+
+int
+main ()
+{
+  if (!foo ())
+    abort ();
+}

[-- Attachment #6: r271059 --]
[-- Type: text/plain, Size: 1354 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-10  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/90385
	* tree-parloops.c (try_create_reduction_list): Punt on non-SSA_NAME
	arguments of the exit phis.

	* gfortran.dg/pr90385.f90: New test.

--- gcc/tree-parloops.c	(revision 271058)
+++ gcc/tree-parloops.c	(revision 271059)
@@ -2794,8 +2794,16 @@ try_create_reduction_list (loop_p loop,
       gimple *reduc_phi;
       tree val = PHI_ARG_DEF_FROM_EDGE (phi, exit);
 
-      if (TREE_CODE (val) == SSA_NAME && !virtual_operand_p (val))
+      if (!virtual_operand_p (val))
 	{
+	  if (TREE_CODE (val) != SSA_NAME)
+	    {
+	      if (dump_file && (dump_flags & TDF_DETAILS))
+		fprintf (dump_file,
+			 "  FAILED: exit PHI argument invariant.\n");
+	      return false;
+	    }
+
 	  if (dump_file && (dump_flags & TDF_DETAILS))
 	    {
 	      fprintf (dump_file, "phi is ");
--- gcc/testsuite/gfortran.dg/pr90385.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/pr90385.f90	(revision 271059)
@@ -0,0 +1,6 @@
+! PR tree-optimization/90385
+! { dg-do compile }
+! { dg-require-effective-target pthread }
+! { dg-options "-O1 -ftree-parallelize-loops=2 -fno-tree-ccp -fno-tree-ch -fno-tree-copy-prop -fno-tree-forwprop -fno-tree-sink --param parloops-min-per-thread=5" }
+
+include 'array_constructor_47.f90'

[-- Attachment #7: r271269 --]
[-- Type: text/plain, Size: 2343 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-15  Jakub Jelinek  <jakub@redhat.com>

	PR debug/90197
	* cp-gimplify.c (genericize_cp_loop): Emit a DEBUG_BEGIN_STMT
	before the condition (or if missing or constant non-zero at the end
	of the loop.  Emit a DEBUG_BEGIN_STMT before the increment expression
	if any.  Don't call protected_set_expr_location on incr if it already
	has a location.

--- gcc/cp/cp-gimplify.c	(revision 271268)
+++ gcc/cp/cp-gimplify.c	(revision 271269)
@@ -241,8 +241,10 @@ genericize_cp_loop (tree *stmt_p, locati
   tree blab, clab;
   tree exit = NULL;
   tree stmt_list = NULL;
+  tree debug_begin = NULL;
 
-  protected_set_expr_location (incr, start_locus);
+  if (EXPR_LOCATION (incr) == UNKNOWN_LOCATION)
+    protected_set_expr_location (incr, start_locus);
 
   cp_walk_tree (&cond, cp_genericize_r, data, NULL);
   cp_walk_tree (&incr, cp_genericize_r, data, NULL);
@@ -253,6 +255,13 @@ genericize_cp_loop (tree *stmt_p, locati
   cp_walk_tree (&body, cp_genericize_r, data, NULL);
   *walk_subtrees = 0;
 
+  if (MAY_HAVE_DEBUG_MARKER_STMTS
+      && (!cond || !integer_zerop (cond)))
+    {
+      debug_begin = build0 (DEBUG_BEGIN_STMT, void_type_node);
+      SET_EXPR_LOCATION (debug_begin, cp_expr_loc_or_loc (cond, start_locus));
+    }
+
   if (cond && TREE_CODE (cond) != INTEGER_CST)
     {
       /* If COND is constant, don't bother building an exit.  If it's false,
@@ -265,10 +274,24 @@ genericize_cp_loop (tree *stmt_p, locati
     }
 
   if (exit && cond_is_first)
-    append_to_statement_list (exit, &stmt_list);
+    {
+      append_to_statement_list (debug_begin, &stmt_list);
+      debug_begin = NULL_TREE;
+      append_to_statement_list (exit, &stmt_list);
+    }
   append_to_statement_list (body, &stmt_list);
   finish_bc_block (&stmt_list, bc_continue, clab);
-  append_to_statement_list (incr, &stmt_list);
+  if (incr)
+    {
+      if (MAY_HAVE_DEBUG_MARKER_STMTS)
+	{
+	  tree d = build0 (DEBUG_BEGIN_STMT, void_type_node);
+	  SET_EXPR_LOCATION (d, cp_expr_loc_or_loc (incr, start_locus));
+	  append_to_statement_list (d, &stmt_list);
+	}
+      append_to_statement_list (incr, &stmt_list);
+    }
+  append_to_statement_list (debug_begin, &stmt_list);
   if (exit && !cond_is_first)
     append_to_statement_list (exit, &stmt_list);
 

[-- Attachment #8: r271270 --]
[-- Type: text/plain, Size: 3006 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-15  Jakub Jelinek  <jakub@redhat.com>

	* omp-low.c (lower_rec_input_clauses): For if (0) or simdlen (1) set
	max_vf to 1.
	* omp-expand.c (expand_omp_simd): For if (0) or simdlen (1) clear
	safelen_int and set loop->dont_vectorize.

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

--- gcc/omp-low.c	(revision 271269)
+++ gcc/omp-low.c	(revision 271270)
@@ -3811,6 +3811,14 @@ lower_rec_input_clauses (tree clauses, g
 	      || is_variable_sized (OMP_CLAUSE_DECL (c)))
 	    sctx.max_vf = 1;
 	  break;
+	case OMP_CLAUSE_IF:
+	  if (integer_zerop (OMP_CLAUSE_IF_EXPR (c)))
+	    sctx.max_vf = 1;
+	  break;
+        case OMP_CLAUSE_SIMDLEN:
+	  if (integer_onep (OMP_CLAUSE_SIMDLEN_EXPR (c)))
+	    sctx.max_vf = 1;
+	  break;
 	default:
 	  continue;
 	}
--- gcc/omp-expand.c	(revision 271269)
+++ gcc/omp-expand.c	(revision 271270)
@@ -4664,10 +4664,15 @@ expand_omp_simd (struct omp_region *regi
   tree *counts = NULL;
   int i;
   int safelen_int = INT_MAX;
+  bool dont_vectorize = false;
   tree safelen = omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
 				  OMP_CLAUSE_SAFELEN);
   tree simduid = omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
 				  OMP_CLAUSE__SIMDUID_);
+  tree ifc = omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
+			      OMP_CLAUSE_IF);
+  tree simdlen = omp_find_clause (gimple_omp_for_clauses (fd->for_stmt),
+				  OMP_CLAUSE_SIMDLEN);
   tree n1, n2;
 
   if (safelen)
@@ -4681,6 +4686,12 @@ expand_omp_simd (struct omp_region *regi
       if (safelen_int == 1)
 	safelen_int = 0;
     }
+  if ((ifc && integer_zerop (OMP_CLAUSE_IF_EXPR (ifc)))
+      || (simdlen && integer_onep (OMP_CLAUSE_SIMDLEN_EXPR (simdlen))))
+    {
+      safelen_int = 0;
+      dont_vectorize = true;
+    }
   type = TREE_TYPE (fd->loop.v);
   entry_bb = region->entry;
   cont_bb = region->cont;
@@ -4965,6 +4976,8 @@ expand_omp_simd (struct omp_region *regi
 	  loop->force_vectorize = true;
 	  cfun->has_force_vectorize_loops = true;
 	}
+      else if (dont_vectorize)
+	loop->dont_vectorize = true;
     }
   else if (simduid)
     cfun->has_simduid_loops = true;
--- gcc/testsuite/c-c++-common/gomp/simd8.c	(nonexistent)
+++ gcc/testsuite/c-c++-common/gomp/simd8.c	(revision 271270)
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -O3 -fdump-tree-vect-details" } */
+/* { dg-final { scan-tree-dump-times "vectorized 0 loops in function" 4 "vect" } } */
+
+int a[1024];
+
+void
+foo (void)
+{
+  #pragma omp simd if (0)
+  for (int i = 0; i < 1024; ++i)
+    a[i] = a[i] + 1;
+}
+
+void
+bar (void)
+{
+  #pragma omp simd if (0) safelen (256) simdlen (8)
+  for (int i = 0; i < 512; ++i)
+    a[i] = a[i] + 1;
+}
+
+void
+baz (void)
+{
+  #pragma omp simd safelen (256) simdlen (1)
+  for (int i = 0; i < 512; ++i)
+    a[i] = a[i] + 1;
+}
+
+void
+qux (void)
+{
+  #pragma omp simd simdlen (1) if (1)
+  for (int i = 0; i < 512; ++i)
+    a[i] = a[i] + 1;
+}

[-- Attachment #9: r271298 --]
[-- Type: text/plain, Size: 11857 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-16  Jakub Jelinek  <jakub@redhat.com>

	* omp-low.c (lower_rec_input_clauses): If OMP_CLAUSE_IF
	has non-constant expression, force sctx.lane and use two
	argument IFN_GOMP_SIMD_LANE instead of single argument.
	* tree-ssa-dce.c (eliminate_unnecessary_stmts): Don't DCE
	two argument IFN_GOMP_SIMD_LANE without lhs.
	* tree-vectorizer.h (struct _loop_vec_info): Add simd_if_cond
	member.
	(LOOP_VINFO_SIMD_IF_COND, LOOP_REQUIRES_VERSIONING_FOR_SIMD_IF_COND):
	Define.
	(LOOP_REQUIRES_VERSIONING): Or in
	LOOP_REQUIRES_VERSIONING_FOR_SIMD_IF_COND.
	* tree-vect-loop.c (_loop_vec_info::_loop_vec_info): Initialize
	simd_if_cond.
	(vect_analyze_loop_2): Punt if LOOP_VINFO_SIMD_IF_COND is constant 0.
	* tree-vect-loop-manip.c (vect_loop_versioning): Add runtime check
	from simd if clause if needed.

	* gcc.dg/vect/vect-simd-1.c: New test.
	* gcc.dg/vect/vect-simd-2.c: New test.
	* gcc.dg/vect/vect-simd-3.c: New test.
	* gcc.dg/vect/vect-simd-4.c: New test.

--- gcc/omp-low.c	(revision 271297)
+++ gcc/omp-low.c	(revision 271298)
@@ -3783,6 +3783,7 @@ lower_rec_input_clauses (tree clauses, g
   tree simt_lane = NULL_TREE, simtrec = NULL_TREE;
   tree ivar = NULL_TREE, lvar = NULL_TREE, uid = NULL_TREE;
   gimple_seq llist[3] = { };
+  tree nonconst_simd_if = NULL_TREE;
 
   copyin_seq = NULL;
   sctx.is_simt = is_simd && omp_find_clause (clauses, OMP_CLAUSE__SIMT_);
@@ -3814,6 +3815,8 @@ lower_rec_input_clauses (tree clauses, g
 	case OMP_CLAUSE_IF:
 	  if (integer_zerop (OMP_CLAUSE_IF_EXPR (c)))
 	    sctx.max_vf = 1;
+	  else if (TREE_CODE (OMP_CLAUSE_IF_EXPR (c)) != INTEGER_CST)
+	    nonconst_simd_if = OMP_CLAUSE_IF_EXPR (c);
 	  break;
         case OMP_CLAUSE_SIMDLEN:
 	  if (integer_onep (OMP_CLAUSE_SIMDLEN_EXPR (c)))
@@ -5190,6 +5193,17 @@ lower_rec_input_clauses (tree clauses, g
   if (known_eq (sctx.max_vf, 1U))
     sctx.is_simt = false;
 
+  if (nonconst_simd_if)
+    {
+      if (sctx.lane == NULL_TREE)
+	{
+	  sctx.idx = create_tmp_var (unsigned_type_node);
+	  sctx.lane = create_tmp_var (unsigned_type_node);
+	}
+      /* FIXME: For now.  */
+      sctx.is_simt = false;
+    }
+
   if (sctx.lane || sctx.is_simt)
     {
       uid = create_tmp_var (ptr_type_node, "simduid");
@@ -5219,8 +5233,9 @@ lower_rec_input_clauses (tree clauses, g
     }
   if (sctx.lane)
     {
-      gimple *g
-	= gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid);
+      gimple *g = gimple_build_call_internal (IFN_GOMP_SIMD_LANE,
+					      1 + (nonconst_simd_if != NULL),
+					      uid, nonconst_simd_if);
       gimple_call_set_lhs (g, sctx.lane);
       gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
       gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
--- gcc/tree-vect-loop-manip.c	(revision 271297)
+++ gcc/tree-vect-loop-manip.c	(revision 271298)
@@ -3009,6 +3009,8 @@ vect_loop_versioning (loop_vec_info loop
   bool version_align = LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo);
   bool version_alias = LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo);
   bool version_niter = LOOP_REQUIRES_VERSIONING_FOR_NITERS (loop_vinfo);
+  tree version_simd_if_cond
+    = LOOP_REQUIRES_VERSIONING_FOR_SIMD_IF_COND (loop_vinfo);
 
   if (check_profitability)
     cond_expr = fold_build2 (GE_EXPR, boolean_type_node, scalar_loop_iters,
@@ -3044,6 +3046,31 @@ vect_loop_versioning (loop_vec_info loop
       vect_create_cond_for_alias_checks (loop_vinfo, &cond_expr);
     }
 
+  if (version_simd_if_cond)
+    {
+      gcc_assert (dom_info_available_p (CDI_DOMINATORS));
+      if (flag_checking)
+	if (basic_block bb
+	    = gimple_bb (SSA_NAME_DEF_STMT (version_simd_if_cond)))
+	  gcc_assert (bb != loop->header
+		      && dominated_by_p (CDI_DOMINATORS, loop->header, bb)
+		      && (scalar_loop == NULL
+			  || (bb != scalar_loop->header
+			      && dominated_by_p (CDI_DOMINATORS,
+						 scalar_loop->header, bb))));
+      tree zero = build_zero_cst (TREE_TYPE (version_simd_if_cond));
+      tree c = fold_build2 (NE_EXPR, boolean_type_node,
+			    version_simd_if_cond, zero);
+      if (cond_expr)
+        cond_expr = fold_build2 (TRUTH_AND_EXPR, boolean_type_node,
+				 c, cond_expr);
+      else
+        cond_expr = c;
+      if (dump_enabled_p ())
+	dump_printf_loc (MSG_NOTE, vect_location,
+			 "created versioning for simd if condition check.\n");
+    }
+
   cond_expr = force_gimple_operand_1 (unshare_expr (cond_expr),
 				      &gimplify_stmt_list,
 				      is_gimple_condexpr, NULL_TREE);
--- gcc/tree-vectorizer.h	(revision 271297)
+++ gcc/tree-vectorizer.h	(revision 271298)
@@ -428,6 +428,13 @@ typedef struct _loop_vec_info : public v
      loops.  */
   tree mask_compare_type;
 
+  /* For #pragma omp simd if (x) loops the x expression.  If constant 0,
+     the loop should not be vectorized, if constant non-zero, simd_if_cond
+     shouldn't be set and loop vectorized normally, if SSA_NAME, the loop
+     should be versioned on that condition, using scalar loop if the condition
+     is false and vectorized loop otherwise.  */
+  tree simd_if_cond;
+
   /* Unknown DRs according to which loop was peeled.  */
   struct dr_vec_info *unaligned_dr;
 
@@ -591,6 +598,7 @@ typedef struct _loop_vec_info : public v
 #define LOOP_VINFO_SCALAR_ITERATION_COST(L) (L)->scalar_cost_vec
 #define LOOP_VINFO_SINGLE_SCALAR_ITERATION_COST(L) (L)->single_scalar_iteration_cost
 #define LOOP_VINFO_ORIG_LOOP_INFO(L)       (L)->orig_loop_info
+#define LOOP_VINFO_SIMD_IF_COND(L)         (L)->simd_if_cond
 
 #define LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT(L)	\
   ((L)->may_misalign_stmts.length () > 0)
@@ -600,10 +608,13 @@ typedef struct _loop_vec_info : public v
    || (L)->lower_bounds.length () > 0)
 #define LOOP_REQUIRES_VERSIONING_FOR_NITERS(L)		\
   (LOOP_VINFO_NITERS_ASSUMPTIONS (L))
+#define LOOP_REQUIRES_VERSIONING_FOR_SIMD_IF_COND(L)	\
+  (LOOP_VINFO_SIMD_IF_COND (L))
 #define LOOP_REQUIRES_VERSIONING(L)			\
   (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (L)		\
    || LOOP_REQUIRES_VERSIONING_FOR_ALIAS (L)		\
-   || LOOP_REQUIRES_VERSIONING_FOR_NITERS (L))
+   || LOOP_REQUIRES_VERSIONING_FOR_NITERS (L)		\
+   || LOOP_REQUIRES_VERSIONING_FOR_SIMD_IF_COND (L))
 
 #define LOOP_VINFO_NITERS_KNOWN_P(L)          \
   (tree_fits_shwi_p ((L)->num_iters) && tree_to_shwi ((L)->num_iters) > 0)
--- gcc/tree-vect-loop.c	(revision 271297)
+++ gcc/tree-vect-loop.c	(revision 271298)
@@ -819,6 +819,7 @@ _loop_vec_info::_loop_vec_info (struct l
     max_vectorization_factor (0),
     mask_skip_niters (NULL_TREE),
     mask_compare_type (NULL_TREE),
+    simd_if_cond (NULL_TREE),
     unaligned_dr (NULL),
     peeling_for_alignment (0),
     ptr_mask (0),
@@ -862,6 +863,26 @@ _loop_vec_info::_loop_vec_info (struct l
 	  gimple *stmt = gsi_stmt (si);
 	  gimple_set_uid (stmt, 0);
 	  add_stmt (stmt);
+	  /* If .GOMP_SIMD_LANE call for the current loop has 2 arguments, the
+	     second argument is the #pragma omp simd if (x) condition, when 0,
+	     loop shouldn't be vectorized, when non-zero constant, it should
+	     be vectorized normally, otherwise versioned with vectorized loop
+	     done if the condition is non-zero at runtime.  */
+	  if (loop_in->simduid
+	      && is_gimple_call (stmt)
+	      && gimple_call_internal_p (stmt)
+	      && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE
+	      && gimple_call_num_args (stmt) >= 2
+	      && TREE_CODE (gimple_call_arg (stmt, 0)) == SSA_NAME
+	      && (loop_in->simduid
+		  == SSA_NAME_VAR (gimple_call_arg (stmt, 0))))
+	    {
+	      tree arg = gimple_call_arg (stmt, 1);
+	      if (integer_zerop (arg) || TREE_CODE (arg) == SSA_NAME)
+		simd_if_cond = arg;
+	      else
+		gcc_assert (integer_nonzerop (arg));
+	    }
 	}
     }
 }
@@ -1769,6 +1790,11 @@ vect_analyze_loop_2 (loop_vec_info loop_
   /* The first group of checks is independent of the vector size.  */
   fatal = true;
 
+  if (LOOP_VINFO_SIMD_IF_COND (loop_vinfo)
+      && integer_zerop (LOOP_VINFO_SIMD_IF_COND (loop_vinfo)))
+    return opt_result::failure_at (vect_location,
+				   "not vectorized: simd if(0)\n");
+
   /* Find all data references in the loop (which correspond to vdefs/vuses)
      and analyze their evolution in the loop.  */
 
--- gcc/tree-ssa-dce.c	(revision 271297)
+++ gcc/tree-ssa-dce.c	(revision 271298)
@@ -1328,12 +1328,16 @@ eliminate_unnecessary_stmts (void)
 		  update_stmt (stmt);
 		  release_ssa_name (name);
 
-		  /* GOMP_SIMD_LANE or ASAN_POISON without lhs is not
-		     needed.  */
+		  /* GOMP_SIMD_LANE (unless two argument) or ASAN_POISON
+		     without lhs is not needed.  */
 		  if (gimple_call_internal_p (stmt))
 		    switch (gimple_call_internal_fn (stmt))
 		      {
 		      case IFN_GOMP_SIMD_LANE:
+			if (gimple_call_num_args (stmt) >= 2
+			    && !integer_nonzerop (gimple_call_arg (stmt, 1)))
+			  break;
+			/* FALLTHRU */
 		      case IFN_ASAN_POISON:
 			remove_dead_stmt (&gsi, bb, to_remove_edges);
 			break;
--- gcc/testsuite/gcc.dg/vect/vect-simd-1.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/vect/vect-simd-1.c	(revision 271298)
@@ -0,0 +1,64 @@
+/* { dg-additional-options "-fopenmp-simd" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+#include "tree-vect.h"
+
+#define N 1024
+int a[N];
+int x;
+
+__attribute__((noipa)) int
+bar (void)
+{
+  return x;
+}
+
+__attribute__((noipa)) void
+foo (void)
+{
+  #pragma omp simd if (bar ())
+  for (int i = 0; i < N; ++i)
+    a[i] = a[i] + 1;
+}
+
+__attribute__((noipa)) void
+baz (void)
+{
+  int c = 0;
+  #pragma omp simd if (c)
+  for (int i = 0; i < N; ++i)
+    a[i] = a[i] + 1;
+}
+
+__attribute__((noipa)) void
+qux (void)
+{
+  int c = 1;
+  #pragma omp simd if (c)
+  for (int i = 0; i < N; ++i)
+    a[i] = a[i] + 1;
+}
+
+int
+main ()
+{
+  check_vect ();
+  foo ();
+  for (int i = 0; i < N; ++i)
+    if (a[i] != 1)
+      abort ();
+  x = 1;
+  foo ();
+  for (int i = 0; i < N; ++i)
+    if (a[i] != 2)
+      abort ();
+  baz ();
+  for (int i = 0; i < N; ++i)
+    if (a[i] != 3)
+      abort ();
+  qux ();
+  for (int i = 0; i < N; ++i)
+    if (a[i] != 4)
+      abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.dg/vect/vect-simd-2.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/vect/vect-simd-2.c	(revision 271298)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-fopenmp-simd" } */
+
+#define N 1024
+int a[N];
+int bar (void);
+
+void
+foo (void)
+{
+  #pragma omp simd if (bar ())
+  for (int i = 0; i < N; ++i)
+    a[i] = a[i] + 1;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-times "created versioning for simd if condition check" 1 "vect" } } */
--- gcc/testsuite/gcc.dg/vect/vect-simd-3.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/vect/vect-simd-3.c	(revision 271298)
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-fopenmp-simd" } */
+
+#define N 1024
+int a[N];
+
+void
+foo (void)
+{
+  int c = 0;
+  #pragma omp simd if (c)
+  for (int i = 0; i < N; ++i)
+    a[i] = a[i] + 1;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 1 "vect" } } */
--- gcc/testsuite/gcc.dg/vect/vect-simd-4.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/vect/vect-simd-4.c	(revision 271298)
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-fopenmp-simd" } */
+
+#define N 1024
+int a[N];
+
+void
+foo (void)
+{
+  int c = 1;
+  #pragma omp simd if (c)
+  for (int i = 0; i < N; ++i)
+    a[i] = a[i] + 1;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
+/* { dg-final { scan-tree-dump-not "created versioning for simd if condition check" "vect" } } */

[-- Attachment #10: r271299 --]
[-- Type: text/plain, Size: 877 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2019-05-16  Jakub Jelinek  <jakub@redhat.com>

	PR c++/90484
	* tree-ssa-scopedtables.c (equal_mem_array_ref_p): Don't assert that
	sz0 is equal to sz1, instead return false in that case.

--- gcc/tree-ssa-scopedtables.c	(revision 271298)
+++ gcc/tree-ssa-scopedtables.c	(revision 271299)
@@ -537,13 +537,10 @@ equal_mem_array_ref_p (tree t0, tree t1)
       || maybe_ne (sz1, max1))
     return false;
 
-  if (rev0 != rev1)
+  if (rev0 != rev1 || maybe_ne (sz0, sz1) || maybe_ne (off0, off1))
     return false;
 
-  /* Types were compatible, so this is a sanity check.  */
-  gcc_assert (known_eq (sz0, sz1));
-
-  return known_eq (off0, off1) && operand_equal_p (base0, base1, 0);
+  return operand_equal_p (base0, base1, 0);
 }
 
 /* Compare two hashable_expr structures for equivalence.  They are

[-- Attachment #11: r271334 --]
[-- Type: text/plain, Size: 524 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/54613
	* gfortran.map (GFORTRAN_9.2): New symbol version, export
	_gfortran_{,m,s}findloc0_i2 in it.

--- libgfortran/gfortran.map	(revision 271333)
+++ libgfortran/gfortran.map	(revision 271334)
@@ -1590,3 +1590,9 @@ GFORTRAN_9 {
   __ieee_arithmetic_MOD_ieee_support_subnormal_8;
   __ieee_arithmetic_MOD_ieee_support_subnormal_noarg;
 } GFORTRAN_8;
+
+GFORTRAN_9.2 {
+  _gfortran_findloc0_i2;
+  _gfortran_mfindloc0_i2;
+  _gfortran_sfindloc0_i2;
+} GFORTRAN_9;

[-- Attachment #12: r271335 --]
[-- Type: text/plain, Size: 32031 bytes --]

2019-05-17  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/54613
	* gfortran.map (GFORTRAN_9.2): Export _gfortran_{,m,s}findloc{0,1}_r10.
	* Makefile.am (i_findloc0_c): Add $(srcdir)/generated/findloc0_r10.c.
	(i_findloc1_c): Add $(srcdir)/generated/findloc1_r10.c.
	* Makefile.in: Regenerated.
	* generated/findloc0_r10.c: Generated.
	* generated/findloc1_r10.c: Generated.

--- libgfortran/gfortran.map	(revision 271334)
+++ libgfortran/gfortran.map	(revision 271335)
@@ -1593,6 +1593,12 @@ GFORTRAN_9 {
 
 GFORTRAN_9.2 {
   _gfortran_findloc0_i2;
+  _gfortran_findloc0_r10;
   _gfortran_mfindloc0_i2;
+  _gfortran_mfindloc0_r10;
   _gfortran_sfindloc0_i2;
+  _gfortran_sfindloc0_r10;
+  _gfortran_findloc1_r10;
+  _gfortran_mfindloc1_r10;
+  _gfortran_sfindloc1_r10;
 } GFORTRAN_9;
--- libgfortran/Makefile.am	(revision 271334)
+++ libgfortran/Makefile.am	(revision 271335)
@@ -278,6 +278,7 @@ $(srcdir)/generated/findloc0_i8.c \
 $(srcdir)/generated/findloc0_i16.c \
 $(srcdir)/generated/findloc0_r4.c \
 $(srcdir)/generated/findloc0_r8.c \
+$(srcdir)/generated/findloc0_r10.c \
 $(srcdir)/generated/findloc0_r16.c \
 $(srcdir)/generated/findloc0_c4.c \
 $(srcdir)/generated/findloc0_c8.c \
@@ -295,6 +296,7 @@ $(srcdir)/generated/findloc1_i8.c \
 $(srcdir)/generated/findloc1_i16.c \
 $(srcdir)/generated/findloc1_r4.c \
 $(srcdir)/generated/findloc1_r8.c \
+$(srcdir)/generated/findloc1_r10.c \
 $(srcdir)/generated/findloc1_r16.c \
 $(srcdir)/generated/findloc1_c4.c \
 $(srcdir)/generated/findloc1_c8.c \
--- libgfortran/Makefile.in	(revision 271334)
+++ libgfortran/Makefile.in	(revision 271335)
@@ -371,11 +371,13 @@ am__objects_45 = maxval1_s1.lo maxval1_s
 am__objects_46 = minval1_s1.lo minval1_s4.lo
 am__objects_47 = findloc0_i1.lo findloc0_i2.lo findloc0_i4.lo \
 	findloc0_i8.lo findloc0_i16.lo findloc0_r4.lo findloc0_r8.lo \
-	findloc0_r16.lo findloc0_c4.lo findloc0_c8.lo findloc0_c16.lo
+	findloc0_r10.lo findloc0_r16.lo findloc0_c4.lo findloc0_c8.lo \
+	findloc0_c16.lo
 am__objects_48 = findloc0_s1.lo findloc0_s4.lo
 am__objects_49 = findloc1_i1.lo findloc1_i2.lo findloc1_i4.lo \
 	findloc1_i8.lo findloc1_i16.lo findloc1_r4.lo findloc1_r8.lo \
-	findloc1_r16.lo findloc1_c4.lo findloc1_c8.lo findloc1_c16.lo
+	findloc1_r10.lo findloc1_r16.lo findloc1_c4.lo findloc1_c8.lo \
+	findloc1_c16.lo
 am__objects_50 = findloc1_s1.lo findloc1_s4.lo
 am__objects_51 = findloc2_s1.lo findloc2_s4.lo
 am__objects_52 = ISO_Fortran_binding.lo
@@ -836,6 +838,7 @@ $(srcdir)/generated/findloc0_i8.c \
 $(srcdir)/generated/findloc0_i16.c \
 $(srcdir)/generated/findloc0_r4.c \
 $(srcdir)/generated/findloc0_r8.c \
+$(srcdir)/generated/findloc0_r10.c \
 $(srcdir)/generated/findloc0_r16.c \
 $(srcdir)/generated/findloc0_c4.c \
 $(srcdir)/generated/findloc0_c8.c \
@@ -853,6 +856,7 @@ $(srcdir)/generated/findloc1_i8.c \
 $(srcdir)/generated/findloc1_i16.c \
 $(srcdir)/generated/findloc1_r4.c \
 $(srcdir)/generated/findloc1_r8.c \
+$(srcdir)/generated/findloc1_r10.c \
 $(srcdir)/generated/findloc1_r16.c \
 $(srcdir)/generated/findloc1_c4.c \
 $(srcdir)/generated/findloc1_c8.c \
@@ -1824,6 +1828,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_i2.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_i4.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_r10.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_r16.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_r4.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc0_r8.Plo@am__quote@
@@ -1837,6 +1842,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_i2.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_i4.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_i8.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_r10.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_r16.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_r4.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/findloc1_r8.Plo@am__quote@
@@ -5949,6 +5955,13 @@ findloc0_r8.lo: $(srcdir)/generated/find
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o findloc0_r8.lo `test -f '$(srcdir)/generated/findloc0_r8.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc0_r8.c
 
+findloc0_r10.lo: $(srcdir)/generated/findloc0_r10.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT findloc0_r10.lo -MD -MP -MF $(DEPDIR)/findloc0_r10.Tpo -c -o findloc0_r10.lo `test -f '$(srcdir)/generated/findloc0_r10.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc0_r10.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/findloc0_r10.Tpo $(DEPDIR)/findloc0_r10.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$(srcdir)/generated/findloc0_r10.c' object='findloc0_r10.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o findloc0_r10.lo `test -f '$(srcdir)/generated/findloc0_r10.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc0_r10.c
+
 findloc0_r16.lo: $(srcdir)/generated/findloc0_r16.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT findloc0_r16.lo -MD -MP -MF $(DEPDIR)/findloc0_r16.Tpo -c -o findloc0_r16.lo `test -f '$(srcdir)/generated/findloc0_r16.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc0_r16.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/findloc0_r16.Tpo $(DEPDIR)/findloc0_r16.Plo
@@ -6040,6 +6053,13 @@ findloc1_r8.lo: $(srcdir)/generated/find
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o findloc1_r8.lo `test -f '$(srcdir)/generated/findloc1_r8.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc1_r8.c
 
+findloc1_r10.lo: $(srcdir)/generated/findloc1_r10.c
+@am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT findloc1_r10.lo -MD -MP -MF $(DEPDIR)/findloc1_r10.Tpo -c -o findloc1_r10.lo `test -f '$(srcdir)/generated/findloc1_r10.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc1_r10.c
+@am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/findloc1_r10.Tpo $(DEPDIR)/findloc1_r10.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	$(AM_V_CC)source='$(srcdir)/generated/findloc1_r10.c' object='findloc1_r10.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@	$(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o findloc1_r10.lo `test -f '$(srcdir)/generated/findloc1_r10.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc1_r10.c
+
 findloc1_r16.lo: $(srcdir)/generated/findloc1_r16.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT findloc1_r16.lo -MD -MP -MF $(DEPDIR)/findloc1_r16.Tpo -c -o findloc1_r16.lo `test -f '$(srcdir)/generated/findloc1_r16.c' || echo '$(srcdir)/'`$(srcdir)/generated/findloc1_r16.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/findloc1_r16.Tpo $(DEPDIR)/findloc1_r16.Plo
--- libgfortran/generated/findloc0_r10.c	(nonexistent)
+++ libgfortran/generated/findloc0_r10.c	(revision 271336)
@@ -0,0 +1,375 @@
+
+/* Implementation of the FINDLOC intrinsic
+   Copyright (C) 2018-2019 Free Software Foundation, Inc.
+   Contributed by Thomas König <tk@tkoenig.net>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later version.
+
+Libgfortran is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "libgfortran.h"
+#include <assert.h>
+
+#if defined (HAVE_GFC_REAL_10)
+extern void findloc0_r10 (gfc_array_index_type * const restrict retarray,
+       	    		gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+			 GFC_LOGICAL_4);
+export_proto(findloc0_r10);
+
+void
+findloc0_r10 (gfc_array_index_type * const restrict retarray,
+    	    gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+	    GFC_LOGICAL_4 back)
+{
+  index_type count[GFC_MAX_DIMENSIONS];
+  index_type extent[GFC_MAX_DIMENSIONS];
+  index_type sstride[GFC_MAX_DIMENSIONS];
+  index_type dstride;
+  const GFC_REAL_10 *base;
+  index_type * restrict dest;
+  index_type rank;
+  index_type n;
+  index_type sz;
+
+  rank = GFC_DESCRIPTOR_RANK (array);
+  if (rank <= 0)
+    runtime_error ("Rank of array needs to be > 0");
+
+  if (retarray->base_addr == NULL)
+    {
+      GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
+      retarray->dtype.rank = 1;
+      retarray->offset = 0;
+      retarray->base_addr = xmallocarray (rank, sizeof (index_type));
+    }
+  else
+    {
+      if (unlikely (compile_options.bounds_check))
+	bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
+				"FINDLOC");
+    }
+
+  dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
+  dest = retarray->base_addr;
+
+  /* Set the return value.  */
+  for (n = 0; n < rank; n++)
+    dest[n * dstride] = 0;
+
+  sz = 1;
+  for (n = 0; n < rank; n++)
+    {
+      sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
+      extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
+      sz *= extent[n];
+      if (extent[n] <= 0)
+	return;
+    }
+
+    for (n = 0; n < rank; n++)
+      count[n] = 0;
+
+  if (back)
+    {
+      base = array->base_addr + (sz - 1) * 1;
+
+      while (1)
+        {
+	  do
+	    {
+	      if (unlikely(*base == value))
+	        {
+		  for (n = 0; n < rank; n++)
+		    dest[n * dstride] = extent[n] - count[n];
+
+		  return;
+		}
+	      base -= sstride[0] * 1;
+	    } while(++count[0] != extent[0]);
+
+	  n = 0;
+	  do
+	    {
+	      /* When we get to the end of a dimension, reset it and increment
+		 the next dimension.  */
+	      count[n] = 0;
+	      /* We could precalculate these products, but this is a less
+		 frequently used path so probably not worth it.  */
+	      base += sstride[n] * extent[n] * 1;
+	      n++;
+	      if (n >= rank)
+	        return;
+	      else
+		{
+		  count[n]++;
+		  base -= sstride[n] * 1;
+		}
+	    } while (count[n] == extent[n]);      
+	}
+    }
+  else
+    {
+      base = array->base_addr;
+      while (1)
+        {
+	  do
+	    {
+	      if (unlikely(*base == value))
+	        {
+		  for (n = 0; n < rank; n++)
+		    dest[n * dstride] = count[n] + 1;
+
+		  return;
+		}
+	      base += sstride[0] * 1;
+	    } while(++count[0] != extent[0]);
+
+	  n = 0;
+	  do
+	    {
+	      /* When we get to the end of a dimension, reset it and increment
+		 the next dimension.  */
+	      count[n] = 0;
+	      /* We could precalculate these products, but this is a less
+		 frequently used path so probably not worth it.  */
+	      base -= sstride[n] * extent[n] * 1;
+	      n++;
+	      if (n >= rank)
+	        return;
+	      else
+		{
+		  count[n]++;
+		  base += sstride[n] * 1;
+		}
+	    } while (count[n] == extent[n]);
+	}
+    }
+  return;
+}
+
+extern void mfindloc0_r10 (gfc_array_index_type * const restrict retarray,
+       	    		gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+			 gfc_array_l1 *const restrict, GFC_LOGICAL_4);
+export_proto(mfindloc0_r10);
+
+void
+mfindloc0_r10 (gfc_array_index_type * const restrict retarray,
+    	    gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+	    gfc_array_l1 *const restrict mask, GFC_LOGICAL_4 back)
+{
+  index_type count[GFC_MAX_DIMENSIONS];
+  index_type extent[GFC_MAX_DIMENSIONS];
+  index_type sstride[GFC_MAX_DIMENSIONS];
+  index_type mstride[GFC_MAX_DIMENSIONS];
+  index_type dstride;
+  const GFC_REAL_10 *base;
+  index_type * restrict dest;
+  GFC_LOGICAL_1 *mbase;
+  index_type rank;
+  index_type n;
+  int mask_kind;
+  index_type sz;
+
+  rank = GFC_DESCRIPTOR_RANK (array);
+  if (rank <= 0)
+    runtime_error ("Rank of array needs to be > 0");
+
+  if (retarray->base_addr == NULL)
+    {
+      GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
+      retarray->dtype.rank = 1;
+      retarray->offset = 0;
+      retarray->base_addr = xmallocarray (rank, sizeof (index_type));
+    }
+  else
+    {
+      if (unlikely (compile_options.bounds_check))
+	{
+	  bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
+				  "FINDLOC");
+	  bounds_equal_extents ((array_t *) mask, (array_t *) array,
+				"MASK argument", "FINDLOC");
+	}
+    }
+
+  mask_kind = GFC_DESCRIPTOR_SIZE (mask);
+
+  mbase = mask->base_addr;
+
+  if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
+#ifdef HAVE_GFC_LOGICAL_16
+      || mask_kind == 16
+#endif
+      )
+    mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
+  else
+    internal_error (NULL, "Funny sized logical array");
+
+  dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
+  dest = retarray->base_addr;
+
+  /* Set the return value.  */
+  for (n = 0; n < rank; n++)
+    dest[n * dstride] = 0;
+
+  sz = 1;
+  for (n = 0; n < rank; n++)
+    {
+      sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
+      mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
+      extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
+      sz *= extent[n];
+      if (extent[n] <= 0)
+	return;
+    }
+
+    for (n = 0; n < rank; n++)
+      count[n] = 0;
+
+  if (back)
+    {
+      base = array->base_addr + (sz - 1) * 1;
+      mbase = mbase + (sz - 1) * mask_kind;
+      while (1)
+        {
+	  do
+	    {
+	      if (unlikely(*mbase && *base == value))
+	        {
+		  for (n = 0; n < rank; n++)
+		    dest[n * dstride] = extent[n] - count[n];
+
+		  return;
+		}
+	      base -= sstride[0] * 1;
+	      mbase -= mstride[0];
+	    } while(++count[0] != extent[0]);
+
+	  n = 0;
+	  do
+	    {
+	      /* When we get to the end of a dimension, reset it and increment
+		 the next dimension.  */
+	      count[n] = 0;
+	      /* We could precalculate these products, but this is a less
+		 frequently used path so probably not worth it.  */
+	      base += sstride[n] * extent[n] * 1;
+	      mbase -= mstride[n] * extent[n];
+	      n++;
+	      if (n >= rank)
+		return;
+	      else
+		{
+		  count[n]++;
+		  base -= sstride[n] * 1;
+		  mbase += mstride[n];
+		}
+	    } while (count[n] == extent[n]);      
+	}
+    }
+  else
+    {
+      base = array->base_addr;
+      while (1)
+        {
+	  do
+	    {
+	      if (unlikely(*mbase && *base == value))
+	        {
+		  for (n = 0; n < rank; n++)
+		    dest[n * dstride] = count[n] + 1;
+
+		  return;
+		}
+	      base += sstride[0] * 1;
+	      mbase += mstride[0];
+	    } while(++count[0] != extent[0]);
+
+	  n = 0;
+	  do
+	    {
+	      /* When we get to the end of a dimension, reset it and increment
+		 the next dimension.  */
+	      count[n] = 0;
+	      /* We could precalculate these products, but this is a less
+		 frequently used path so probably not worth it.  */
+	      base -= sstride[n] * extent[n] * 1;
+	      mbase -= mstride[n] * extent[n];
+	      n++;
+	      if (n >= rank)
+		return;
+	      else
+		{
+		  count[n]++;
+		  base += sstride[n]* 1;
+		  mbase += mstride[n];
+		}
+	    } while (count[n] == extent[n]);
+	}
+    }
+  return;
+}
+
+extern void sfindloc0_r10 (gfc_array_index_type * const restrict retarray,
+       	    		gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+			 GFC_LOGICAL_4 *, GFC_LOGICAL_4);
+export_proto(sfindloc0_r10);
+
+void
+sfindloc0_r10 (gfc_array_index_type * const restrict retarray,
+    	    gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+	    GFC_LOGICAL_4 * mask, GFC_LOGICAL_4 back)
+{
+  index_type rank;
+  index_type dstride;
+  index_type * restrict dest;
+  index_type n;
+
+  if (mask == NULL || *mask)
+    {
+      findloc0_r10 (retarray, array, value, back);
+      return;
+    }
+
+  rank = GFC_DESCRIPTOR_RANK (array);
+
+  if (rank <= 0)
+    internal_error (NULL, "Rank of array needs to be > 0");
+
+  if (retarray->base_addr == NULL)
+    {
+      GFC_DIMENSION_SET(retarray->dim[0], 0, rank-1, 1);
+      retarray->dtype.rank = 1;
+      retarray->offset = 0;
+      retarray->base_addr = xmallocarray (rank, sizeof (index_type));
+    }
+  else if (unlikely (compile_options.bounds_check))
+    {
+       bounds_iforeach_return ((array_t *) retarray, (array_t *) array,
+			       "FINDLOC");
+    }
+
+  dstride = GFC_DESCRIPTOR_STRIDE(retarray,0);
+  dest = retarray->base_addr;
+  for (n = 0; n<rank; n++)
+    dest[n * dstride] = 0 ;
+}
+
+#endif
--- libgfortran/generated/findloc1_r10.c	(nonexistent)
+++ libgfortran/generated/findloc1_r10.c	(revision 271336)
@@ -0,0 +1,523 @@
+/* Implementation of the FINDLOC intrinsic
+   Copyright (C) 2018-2019 Free Software Foundation, Inc.
+   Contributed by Thomas König <tk@tkoenig.net>
+
+This file is part of the GNU Fortran 95 runtime library (libgfortran).
+
+Libgfortran is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public
+License as published by the Free Software Foundation; either
+version 3 of the License, or (at your option) any later version.
+
+Libgfortran is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+<http://www.gnu.org/licenses/>.  */
+
+#include "libgfortran.h"
+#include <assert.h>
+
+#if defined (HAVE_GFC_REAL_10)
+extern void findloc1_r10 (gfc_array_index_type * const restrict retarray,
+		         gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+			 const index_type * restrict pdim, GFC_LOGICAL_4 back);
+export_proto(findloc1_r10);
+
+extern void
+findloc1_r10 (gfc_array_index_type * const restrict retarray,
+	    gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+	    const index_type * restrict pdim, GFC_LOGICAL_4 back)
+{
+  index_type count[GFC_MAX_DIMENSIONS];
+  index_type extent[GFC_MAX_DIMENSIONS];
+  index_type sstride[GFC_MAX_DIMENSIONS];
+  index_type dstride[GFC_MAX_DIMENSIONS];
+  const GFC_REAL_10 * restrict base;
+  index_type * restrict dest;
+  index_type rank;
+  index_type n;
+  index_type len;
+  index_type delta;
+  index_type dim;
+  int continue_loop;
+
+  /* Make dim zero based to avoid confusion.  */
+  rank = GFC_DESCRIPTOR_RANK (array) - 1;
+  dim = (*pdim) - 1;
+
+  if (unlikely (dim < 0 || dim > rank))
+    {
+      runtime_error ("Dim argument incorrect in FINDLOC intrinsic: "
+ 		     "is %ld, should be between 1 and %ld",
+		     (long int) dim + 1, (long int) rank + 1);
+    }
+
+  len = GFC_DESCRIPTOR_EXTENT(array,dim);
+  if (len < 0)
+    len = 0;
+  delta = GFC_DESCRIPTOR_STRIDE(array,dim);
+
+  for (n = 0; n < dim; n++)
+    {
+      sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
+      extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
+
+      if (extent[n] < 0)
+	extent[n] = 0;
+    }
+  for (n = dim; n < rank; n++)
+    {
+      sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1);
+      extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
+
+      if (extent[n] < 0)
+	extent[n] = 0;
+    }
+
+  if (retarray->base_addr == NULL)
+    {
+      size_t alloc_size, str;
+
+      for (n = 0; n < rank; n++)
+	{
+	  if (n == 0)
+	    str = 1;
+	  else
+	    str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
+
+	  GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
+
+	}
+
+      retarray->offset = 0;
+      retarray->dtype.rank = rank;
+
+      alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
+
+      retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type));
+      if (alloc_size == 0)
+	{
+	  /* Make sure we have a zero-sized array.  */
+	  GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
+	  return;
+	}
+    }
+  else
+    {
+      if (rank != GFC_DESCRIPTOR_RANK (retarray))
+	runtime_error ("rank of return array incorrect in"
+		       " FINDLOC intrinsic: is %ld, should be %ld",
+		       (long int) (GFC_DESCRIPTOR_RANK (retarray)),
+		       (long int) rank);
+
+      if (unlikely (compile_options.bounds_check))
+	bounds_ifunction_return ((array_t *) retarray, extent,
+				 "return value", "FINDLOC");
+    }
+
+  for (n = 0; n < rank; n++)
+    {
+      count[n] = 0;
+      dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
+      if (extent[n] <= 0)
+	return;
+    }
+
+  dest = retarray->base_addr;
+  continue_loop = 1;
+
+  base = array->base_addr;
+  while (continue_loop)
+    {
+      const GFC_REAL_10 * restrict src;
+      index_type result;
+
+      result = 0;
+      if (back)
+	{
+	  src = base + (len - 1) * delta * 1;
+	  for (n = len; n > 0; n--, src -= delta * 1)
+	    {
+	      if (*src == value)
+		{
+		  result = n;
+		  break;
+		}
+	    }
+	}
+      else
+	{
+	  src = base;
+	  for (n = 1; n <= len; n++, src += delta * 1)
+	    {
+	      if (*src == value)
+		{
+		  result = n;
+		  break;
+		}
+	    }
+	}
+      *dest = result;
+
+      count[0]++;
+      base += sstride[0] * 1;
+      dest += dstride[0];
+      n = 0;
+      while (count[n] == extent[n])
+	{
+	  count[n] = 0;
+	  base -= sstride[n] * extent[n] * 1;
+	  dest -= dstride[n] * extent[n];
+	  n++;
+	  if (n >= rank)
+	    {
+	      continue_loop = 0;
+	      break;
+	    }
+	  else
+	    {
+	      count[n]++;
+	      base += sstride[n] * 1;
+	      dest += dstride[n];
+	    }
+	}
+    }
+}
+extern void mfindloc1_r10 (gfc_array_index_type * const restrict retarray,
+		         gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+			 const index_type * restrict pdim, gfc_array_l1 *const restrict mask,
+			 GFC_LOGICAL_4 back);
+export_proto(mfindloc1_r10);
+
+extern void
+mfindloc1_r10 (gfc_array_index_type * const restrict retarray,
+	    gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+	    const index_type * restrict pdim, gfc_array_l1 *const restrict mask,
+	    GFC_LOGICAL_4 back)
+{
+  index_type count[GFC_MAX_DIMENSIONS];
+  index_type extent[GFC_MAX_DIMENSIONS];
+  index_type sstride[GFC_MAX_DIMENSIONS];
+  index_type mstride[GFC_MAX_DIMENSIONS];
+  index_type dstride[GFC_MAX_DIMENSIONS];
+  const GFC_REAL_10 * restrict base;
+  const GFC_LOGICAL_1 * restrict mbase;
+  index_type * restrict dest;
+  index_type rank;
+  index_type n;
+  index_type len;
+  index_type delta;
+  index_type mdelta;
+  index_type dim;
+  int mask_kind;
+  int continue_loop;
+
+  /* Make dim zero based to avoid confusion.  */
+  rank = GFC_DESCRIPTOR_RANK (array) - 1;
+  dim = (*pdim) - 1;
+
+  if (unlikely (dim < 0 || dim > rank))
+    {
+      runtime_error ("Dim argument incorrect in FINDLOC intrinsic: "
+ 		     "is %ld, should be between 1 and %ld",
+		     (long int) dim + 1, (long int) rank + 1);
+    }
+
+  len = GFC_DESCRIPTOR_EXTENT(array,dim);
+  if (len < 0)
+    len = 0;
+
+  delta = GFC_DESCRIPTOR_STRIDE(array,dim);
+  mdelta = GFC_DESCRIPTOR_STRIDE_BYTES(mask,dim);
+
+  mbase = mask->base_addr;
+
+  mask_kind = GFC_DESCRIPTOR_SIZE (mask);
+
+  if (mask_kind == 1 || mask_kind == 2 || mask_kind == 4 || mask_kind == 8
+#ifdef HAVE_GFC_LOGICAL_16
+      || mask_kind == 16
+#endif
+      )
+    mbase = GFOR_POINTER_TO_L1 (mbase, mask_kind);
+  else
+    internal_error (NULL, "Funny sized logical array");
+
+  for (n = 0; n < dim; n++)
+    {
+      sstride[n] = GFC_DESCRIPTOR_STRIDE(array,n);
+      mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask,n);
+      extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
+
+      if (extent[n] < 0)
+	extent[n] = 0;
+    }
+  for (n = dim; n < rank; n++)
+    {
+      sstride[n] = GFC_DESCRIPTOR_STRIDE(array, n + 1);
+      mstride[n] = GFC_DESCRIPTOR_STRIDE_BYTES(mask, n + 1);
+      extent[n] = GFC_DESCRIPTOR_EXTENT(array, n + 1);
+
+      if (extent[n] < 0)
+	extent[n] = 0;
+    }
+
+  if (retarray->base_addr == NULL)
+    {
+      size_t alloc_size, str;
+
+      for (n = 0; n < rank; n++)
+	{
+	  if (n == 0)
+	    str = 1;
+	  else
+	    str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
+
+	  GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
+
+	}
+
+      retarray->offset = 0;
+      retarray->dtype.rank = rank;
+
+      alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
+
+      retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type));
+      if (alloc_size == 0)
+	{
+	  /* Make sure we have a zero-sized array.  */
+	  GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
+	  return;
+	}
+    }
+  else
+    {
+      if (rank != GFC_DESCRIPTOR_RANK (retarray))
+	runtime_error ("rank of return array incorrect in"
+		       " FINDLOC intrinsic: is %ld, should be %ld",
+		       (long int) (GFC_DESCRIPTOR_RANK (retarray)),
+		       (long int) rank);
+
+      if (unlikely (compile_options.bounds_check))
+	bounds_ifunction_return ((array_t *) retarray, extent,
+				 "return value", "FINDLOC");
+    }
+
+  for (n = 0; n < rank; n++)
+    {
+      count[n] = 0;
+      dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
+      if (extent[n] <= 0)
+	return;
+    }
+
+  dest = retarray->base_addr;
+  continue_loop = 1;
+
+  base = array->base_addr;
+  while (continue_loop)
+    {
+      const GFC_REAL_10 * restrict src;
+      const GFC_LOGICAL_1 * restrict msrc;
+      index_type result;
+
+      result = 0;
+      if (back)
+	{
+	  src = base + (len - 1) * delta * 1;
+	  msrc = mbase + (len - 1) * mdelta; 
+	  for (n = len; n > 0; n--, src -= delta * 1, msrc -= mdelta)
+	    {
+	      if (*msrc && *src == value)
+		{
+		  result = n;
+		  break;
+		}
+	    }
+	}
+      else
+	{
+	  src = base;
+	  msrc = mbase;
+	  for (n = 1; n <= len; n++, src += delta * 1, msrc += mdelta)
+	    {
+	      if (*msrc && *src == value)
+		{
+		  result = n;
+		  break;
+		}
+	    }
+	}
+      *dest = result;
+
+      count[0]++;
+      base += sstride[0] * 1;
+      mbase += mstride[0];
+      dest += dstride[0];
+      n = 0;
+      while (count[n] == extent[n])
+	{
+	  count[n] = 0;
+	  base -= sstride[n] * extent[n] * 1;
+	  mbase -= mstride[n] * extent[n];
+	  dest -= dstride[n] * extent[n];
+	  n++;
+	  if (n >= rank)
+	    {
+	      continue_loop = 0;
+	      break;
+	    }
+	  else
+	    {
+	      count[n]++;
+	      base += sstride[n] * 1;
+	      dest += dstride[n];
+	    }
+	}
+    }
+}
+extern void sfindloc1_r10 (gfc_array_index_type * const restrict retarray,
+		         gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+			 const index_type * restrict pdim, GFC_LOGICAL_4 *const restrict mask,
+			 GFC_LOGICAL_4 back);
+export_proto(sfindloc1_r10);
+
+extern void
+sfindloc1_r10 (gfc_array_index_type * const restrict retarray,
+	    gfc_array_r10 * const restrict array, GFC_REAL_10 value,
+	    const index_type * restrict pdim, GFC_LOGICAL_4 *const restrict  mask,
+	    GFC_LOGICAL_4 back)
+{
+  index_type count[GFC_MAX_DIMENSIONS];
+  index_type extent[GFC_MAX_DIMENSIONS];
+  index_type dstride[GFC_MAX_DIMENSIONS];
+  index_type * restrict dest;
+  index_type rank;
+  index_type n;
+  index_type len;
+  index_type dim;
+  bool continue_loop;
+
+  if (mask == NULL || *mask)
+    {
+      findloc1_r10 (retarray, array, value, pdim, back);
+      return;
+    }
+    /* Make dim zero based to avoid confusion.  */
+  rank = GFC_DESCRIPTOR_RANK (array) - 1;
+  dim = (*pdim) - 1;
+
+  if (unlikely (dim < 0 || dim > rank))
+    {
+      runtime_error ("Dim argument incorrect in FINDLOC intrinsic: "
+ 		     "is %ld, should be between 1 and %ld",
+		     (long int) dim + 1, (long int) rank + 1);
+    }
+
+  len = GFC_DESCRIPTOR_EXTENT(array,dim);
+  if (len < 0)
+    len = 0;
+
+  for (n = 0; n < dim; n++)
+    {
+      extent[n] = GFC_DESCRIPTOR_EXTENT(array,n);
+
+      if (extent[n] <= 0)
+	extent[n] = 0;
+    }
+
+  for (n = dim; n < rank; n++)
+    {
+      extent[n] =
+	GFC_DESCRIPTOR_EXTENT(array,n + 1);
+
+      if (extent[n] <= 0)
+	extent[n] = 0;
+    }
+
+
+  if (retarray->base_addr == NULL)
+    {
+      size_t alloc_size, str;
+
+      for (n = 0; n < rank; n++)
+	{
+	  if (n == 0)
+	    str = 1;
+	  else
+	    str = GFC_DESCRIPTOR_STRIDE(retarray,n-1) * extent[n-1];
+
+	  GFC_DIMENSION_SET(retarray->dim[n], 0, extent[n] - 1, str);
+	}
+
+      retarray->offset = 0;
+      retarray->dtype.rank = rank;
+
+      alloc_size = GFC_DESCRIPTOR_STRIDE(retarray,rank-1) * extent[rank-1];
+
+      retarray->base_addr = xmallocarray (alloc_size, sizeof (index_type));
+      if (alloc_size == 0)
+	{
+	  /* Make sure we have a zero-sized array.  */
+	  GFC_DIMENSION_SET(retarray->dim[0], 0, -1, 1);
+	  return;
+	}
+    }
+  else
+    {
+      if (rank != GFC_DESCRIPTOR_RANK (retarray))
+	runtime_error ("rank of return array incorrect in"
+		       " FINDLOC intrinsic: is %ld, should be %ld",
+		       (long int) (GFC_DESCRIPTOR_RANK (retarray)),
+		       (long int) rank);
+
+      if (unlikely (compile_options.bounds_check))
+	bounds_ifunction_return ((array_t *) retarray, extent,
+				 "return value", "FINDLOC");
+    }
+
+  for (n = 0; n < rank; n++)
+    {
+      count[n] = 0;
+      dstride[n] = GFC_DESCRIPTOR_STRIDE(retarray,n);
+      if (extent[n] <= 0)
+	return;
+    }
+  dest = retarray->base_addr;
+  continue_loop = 1;
+
+  while (continue_loop)
+    {
+      *dest = 0;
+
+      count[0]++;
+      dest += dstride[0];
+      n = 0;
+      while (count[n] == extent[n])
+	{
+	  count[n] = 0;
+	  dest -= dstride[n] * extent[n];
+	  n++;
+	  if (n >= rank)
+	    {
+	      continue_loop = 0;
+	      break;
+	    }
+	  else
+	    {
+	      count[n]++;
+	      dest += dstride[n];
+	    }
+	}
+    }
+}
+#endif

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-11-08 19:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-05 12:24 Backports to gcc-9-branch Jakub Jelinek
  -- strict thread matches above, loose matches on Subject: below --
2019-11-08 19:30 Jakub Jelinek
2019-08-01  6:34 Jakub Jelinek
2019-05-17 20:00 Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).