diff mbox series

Backports to 8.3

Message ID 20180726164126.GE17988@tucnak
State New
Headers show
Series Backports to 8.3 | expand

Commit Message

Jakub Jelinek July 26, 2018, 4:41 p.m. UTC
Hi!

I've backported 4 commits of mine to gcc-8-branch, after
bootstrapping/regtesting them on x86_64-linux and i686-linux.

	Jakub
2018-07-26  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-07-10  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/86421
	* module.c (omp_declare_simd_clauses): Add LINEAR with _REF, _VAL and
	_UVAL suffixes.
	(mio_omp_declare_simd): Save and restore ref, val and uval modifiers
	on linear clauses.  Initialize n->where to gfc_current_locus.

	* gfortran.dg/vect/pr86421.f90: New test.
2018-07-26  Jakub Jelinek  <jakub@redhat.com>

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

	PR middle-end/86539
	* gimplify.c (gimplify_omp_for): Ensure taskloop firstprivatized init
	and cond temporaries don't have reference type if iterator has
	pointer type.  For init use &for_pre_body instead of pre_p if
	for_pre_body is non-empty.

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

--- gcc/gimplify.c	(revision 262775)
+++ gcc/gimplify.c	(revision 262776)
@@ -9811,9 +9811,26 @@ gimplify_omp_for (tree *expr_p, gimple_s
 	  t = TREE_VEC_ELT (OMP_FOR_INIT (for_stmt), i);
 	  if (!is_gimple_constant (TREE_OPERAND (t, 1)))
 	    {
+	      tree type = TREE_TYPE (TREE_OPERAND (t, 0));
 	      TREE_OPERAND (t, 1)
 		= get_initialized_tmp_var (TREE_OPERAND (t, 1),
-					   pre_p, NULL, false);
+					   gimple_seq_empty_p (for_pre_body)
+					   ? pre_p : &for_pre_body, NULL,
+					   false);
+	      /* Reference to pointer conversion is considered useless,
+		 but is significant for firstprivate clause.  Force it
+		 here.  */
+	      if (TREE_CODE (type) == POINTER_TYPE
+		  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
+		      == REFERENCE_TYPE))
+		{
+		  tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
+		  tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
+				   TREE_OPERAND (t, 1));
+		  gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
+				       ? pre_p : &for_pre_body);
+		  TREE_OPERAND (t, 1) = v;
+		}
 	      tree c = build_omp_clause (input_location,
 					 OMP_CLAUSE_FIRSTPRIVATE);
 	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
@@ -9825,11 +9842,26 @@ gimplify_omp_for (tree *expr_p, gimple_s
 	  t = TREE_VEC_ELT (OMP_FOR_COND (for_stmt), i);
 	  if (!is_gimple_constant (TREE_OPERAND (t, 1)))
 	    {
+	      tree type = TREE_TYPE (TREE_OPERAND (t, 0));
 	      TREE_OPERAND (t, 1)
 		= get_initialized_tmp_var (TREE_OPERAND (t, 1),
 					   gimple_seq_empty_p (for_pre_body)
 					   ? pre_p : &for_pre_body, NULL,
 					   false);
+	      /* Reference to pointer conversion is considered useless,
+		 but is significant for firstprivate clause.  Force it
+		 here.  */
+	      if (TREE_CODE (type) == POINTER_TYPE
+		  && (TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 1)))
+		      == REFERENCE_TYPE))
+		{
+		  tree v = create_tmp_var (TYPE_MAIN_VARIANT (type));
+		  tree m = build2 (INIT_EXPR, TREE_TYPE (v), v,
+				   TREE_OPERAND (t, 1));
+		  gimplify_and_add (m, gimple_seq_empty_p (for_pre_body)
+				       ? pre_p : &for_pre_body);
+		  TREE_OPERAND (t, 1) = v;
+		}
 	      tree c = build_omp_clause (input_location,
 					 OMP_CLAUSE_FIRSTPRIVATE);
 	      OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
--- libgomp/testsuite/libgomp.c++/pr86539.C	(nonexistent)
+++ libgomp/testsuite/libgomp.c++/pr86539.C	(revision 262776)
@@ -0,0 +1,28 @@
+// PR middle-end/86539
+
+int a[384];
+
+__attribute__((noipa)) void
+foo (int &b, int &c)
+{
+  #pragma omp taskloop shared (a) collapse(3)
+  for (int i = 0; i < 1; i++)
+    for (int *p = &b; p < &c; p++)
+      for (int j = 0; j < 1; j++)
+	if (p < &a[128] || p >= &a[256])
+	  __builtin_abort ();
+	else
+	  p[0]++;
+}
+
+int
+main ()
+{
+  #pragma omp parallel
+  #pragma omp single
+    foo (a[128], a[256]);
+  for (int i = 0; i < 384; i++)
+    if (a[i] != (i >= 128 && i < 256))
+      __builtin_abort ();
+  return 0;
+}
2018-07-26  Jakub Jelinek  <jakub@redhat.com>

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

	PR middle-end/86542
	* omp-low.c (create_task_copyfn): Copy over also fields corresponding
	to _looptemp_ clauses, other than the first two.

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

--- gcc/omp-low.c	(revision 262814)
+++ gcc/omp-low.c	(revision 262815)
@@ -7026,6 +7026,7 @@ create_task_copyfn (gomp_task *task_stmt
   splay_tree_node n;
   struct omp_taskcopy_context tcctx;
   location_t loc = gimple_location (task_stmt);
+  size_t looptempno = 0;
 
   child_fn = gimple_omp_task_copy_fn (task_stmt);
   child_cfun = DECL_STRUCT_FUNCTION (child_fn);
@@ -7139,6 +7140,15 @@ create_task_copyfn (gomp_task *task_stmt
 	t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
 	append_to_statement_list (t, &list);
 	break;
+      case OMP_CLAUSE__LOOPTEMP_:
+	/* Fields for first two _looptemp_ clauses are initialized by
+	   GOMP_taskloop*, the rest are handled like firstprivate.  */
+        if (looptempno < 2)
+	  {
+	    looptempno++;
+	    break;
+	  }
+	/* FALLTHRU */
       case OMP_CLAUSE_FIRSTPRIVATE:
 	decl = OMP_CLAUSE_DECL (c);
 	if (is_variable_sized (decl))
@@ -7164,7 +7174,10 @@ create_task_copyfn (gomp_task *task_stmt
 	  src = decl;
 	dst = build_simple_mem_ref_loc (loc, arg);
 	dst = omp_build_component_ref (dst, f);
-	t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
+	if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE__LOOPTEMP_)
+	  t = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
+	else
+	  t = lang_hooks.decls.omp_clause_copy_ctor (c, dst, src);
 	append_to_statement_list (t, &list);
 	break;
       case OMP_CLAUSE_PRIVATE:
--- libgomp/testsuite/libgomp.c++/pr86542.C	(nonexistent)
+++ libgomp/testsuite/libgomp.c++/pr86542.C	(revision 262815)
@@ -0,0 +1,37 @@
+// PR middle-end/86542
+
+struct S { int s; S (); ~S (); S (const S &); };
+S s;
+
+S::S ()
+{
+}
+
+S::~S ()
+{
+}
+
+S::S (const S &x)
+{
+  s = x.s;
+}
+
+__attribute__((noipa)) void
+foo (int i, int j, int k, S s)
+{
+  if (i != 0 || j != 0 || k != 0 || s.s != 12)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  volatile int inc = 16, jnc = 16, knc = 16;
+  s.s = 12;
+  #pragma omp taskloop collapse (3) firstprivate (s)
+  for (int i = 0; i < 16; i += inc)
+    for (int j = 0; j < 16; j += jnc)
+      for (int k = 0; k < 16; k += knc)
+	foo (i, j, k, s);
+  return 0;
+}
2018-07-26  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2018-07-24  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/86627
	* expmed.c (expand_divmod): Punt if d == HOST_WIDE_INT_MIN
	and size > HOST_BITS_PER_WIDE_INT.  For size > HOST_BITS_PER_WIDE_INT
	and abs_d == d, do the power of two handling if profitable.

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

--- gcc/expmed.c	(revision 262947)
+++ gcc/expmed.c	(revision 262948)
@@ -4480,6 +4480,11 @@ expand_divmod (int rem_flag, enum tree_c
 		HOST_WIDE_INT d = INTVAL (op1);
 		unsigned HOST_WIDE_INT abs_d;
 
+		/* Not prepared to handle division/remainder by
+		   0xffffffffffffffff8000000000000000 etc.  */
+		if (d == HOST_WIDE_INT_MIN && size > HOST_BITS_PER_WIDE_INT)
+		  break;
+
 		/* Since d might be INT_MIN, we have to cast to
 		   unsigned HOST_WIDE_INT before negating to avoid
 		   undefined signed overflow.  */
@@ -4522,9 +4527,7 @@ expand_divmod (int rem_flag, enum tree_c
 			     || (optab_handler (sdivmod_optab, int_mode)
 				 != CODE_FOR_nothing)))
 		  ;
-		else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d)
-			 && (size <= HOST_BITS_PER_WIDE_INT
-			     || abs_d != (unsigned HOST_WIDE_INT) d))
+		else if (EXACT_POWER_OF_2_OR_ZERO_P (abs_d))
 		  {
 		    if (rem_flag)
 		      {
--- gcc/testsuite/gcc.target/i386/pr86627.c	(nonexistent)
+++ gcc/testsuite/gcc.target/i386/pr86627.c	(revision 262948)
@@ -0,0 +1,28 @@
+/* PR middle-end/86627 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler-not "call\[^\n\r]*__divti3" } } */
+
+__int128_t
+f1 (__int128_t a)
+{
+  return a / 2;
+}
+
+__int128_t
+f2 (__int128_t a)
+{
+  return a / -2;
+}
+
+__int128_t
+f3 (__int128_t a)
+{
+  return a / 0x4000000000000000LL;
+}
+
+__int128_t
+f4 (__int128_t a)
+{
+  return a / -0x4000000000000000LL;
+}
diff mbox series

Patch

--- gcc/fortran/module.c	(revision 262534)
+++ gcc/fortran/module.c	(revision 262535)
@@ -4098,6 +4098,9 @@  static const mstring omp_declare_simd_cl
     minit ("UNIFORM", 3),
     minit ("LINEAR", 4),
     minit ("ALIGNED", 5),
+    minit ("LINEAR_REF", 33),
+    minit ("LINEAR_VAL", 34),
+    minit ("LINEAR_UVAL", 35),
     minit (NULL, -1)
 };
 
@@ -4140,7 +4143,10 @@  mio_omp_declare_simd (gfc_namespace *ns,
 	    }
 	  for (n = ods->clauses->lists[OMP_LIST_LINEAR]; n; n = n->next)
 	    {
-	      mio_name (4, omp_declare_simd_clauses);
+	      if (n->u.linear_op == OMP_LINEAR_DEFAULT)
+		mio_name (4, omp_declare_simd_clauses);
+	      else
+		mio_name (32 + n->u.linear_op, omp_declare_simd_clauses);
 	      mio_symbol_ref (&n->sym);
 	      mio_expr (&n->expr);
 	    }
@@ -4181,11 +4187,20 @@  mio_omp_declare_simd (gfc_namespace *ns,
 	    case 4:
 	    case 5:
 	      *ptrs[t - 3] = n = gfc_get_omp_namelist ();
+	    finish_namelist:
+	      n->where = gfc_current_locus;
 	      ptrs[t - 3] = &n->next;
 	      mio_symbol_ref (&n->sym);
 	      if (t != 3)
 		mio_expr (&n->expr);
 	      break;
+	    case 33:
+	    case 34:
+	    case 35:
+	      *ptrs[1] = n = gfc_get_omp_namelist ();
+	      n->u.linear_op = (enum gfc_omp_linear_op) (t - 32);
+	      t = 4;
+	      goto finish_namelist;
 	    }
 	}
     }
--- gcc/testsuite/gfortran.dg/vect/pr86421.f90	(nonexistent)
+++ gcc/testsuite/gfortran.dg/vect/pr86421.f90	(revision 262535)
@@ -0,0 +1,35 @@ 
+! PR fortran/86421
+! { dg-require-effective-target vect_simd_clones }
+! { dg-additional-options "-fopenmp-simd" }
+! { dg-additional-options "-mavx" { target avx_runtime } }
+
+module mod86421
+  implicit none
+contains
+  subroutine foo(x, y, z)
+    real :: x
+    integer :: y, z
+    !$omp declare simd linear(ref(x)) linear(val(y)) linear(uval(z))
+    x = x + y
+    z = z + 1
+  end subroutine
+end module mod86421
+
+program pr86421
+  use mod86421
+  implicit none
+  integer :: i, j
+  real :: a(64)
+  j = 0
+  do i = 1, 64
+    a(i) = i
+  end do
+  !$omp simd
+  do i = 1, 64
+    call foo (a(i), i, j)
+  end do
+  do i = 1, 64
+    if (a(i) .ne. (2 * i)) stop 1
+  end do
+  if (j .ne. 64) stop 2
+end program pr86421