[4.9] 3 backports to 4.9 branch from the trunk

Jakub Jelinek jakub@redhat.com
Wed Feb 11 14:56:00 GMT 2015


Hi!

I've bootstrapped/regtested these 3 backports from trunk to 4.9 branch
on x86_64-linux and i686-linux and installed.

	Jakub
-------------- next part --------------
2015-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-02-04  Jakub Jelinek  <jakub@redhat.com>

	PR c/64824
	PR c/64868
	* c-omp.c (c_finish_omp_atomic): Use TRUNC_DIV_EXPR
	instead of RDIV_EXPR.  Use build_binary_op instead of
	build2_loc.

	* c-parser.c (c_parser_omp_atomic): Handle RDIV_EXPR.

	* parser.c (cp_parser_omp_atomic): Handle RDIV_EXPR.

	* testsuite/libgomp.c/pr64824.c: New test.
	* testsuite/libgomp.c/pr64868.c: New test.
	* testsuite/libgomp.c++/pr64824.C: New test.
	* testsuite/libgomp.c++/pr64868.C: New test.

--- gcc/c-family/c-omp.c	(revision 220419)
+++ gcc/c-family/c-omp.c	(revision 220420)
@@ -206,6 +206,9 @@ c_finish_omp_atomic (location_t loc, enu
       return error_mark_node;
     }
 
+  if (opcode == RDIV_EXPR)
+    opcode = TRUNC_DIV_EXPR;
+
   /* ??? Validate that rhs does not overlap lhs.  */
 
   /* Take and save the address of the lhs.  From then on we'll reference it
@@ -240,7 +243,7 @@ c_finish_omp_atomic (location_t loc, enu
      to do this, and then take it apart again.  */
   if (swapped)
     {
-      rhs = build2_loc (loc, opcode, TREE_TYPE (lhs), rhs, lhs);
+      rhs = build_binary_op (loc, opcode, rhs, lhs, 1);
       opcode = NOP_EXPR;
     }
   bool save = in_late_binary_op;
--- gcc/c/c-parser.c	(revision 220419)
+++ gcc/c/c-parser.c	(revision 220420)
@@ -12611,6 +12611,7 @@ restart:
 	    {
 	    case MULT_EXPR:
 	    case TRUNC_DIV_EXPR:
+	    case RDIV_EXPR:
 	    case PLUS_EXPR:
 	    case MINUS_EXPR:
 	    case LSHIFT_EXPR:
--- gcc/cp/parser.c	(revision 220419)
+++ gcc/cp/parser.c	(revision 220420)
@@ -29835,6 +29835,7 @@ restart:
 		{
 		case MULT_EXPR:
 		case TRUNC_DIV_EXPR:
+		case RDIV_EXPR:
 		case PLUS_EXPR:
 		case MINUS_EXPR:
 		case LSHIFT_EXPR:
--- libgomp/testsuite/libgomp.c++/pr64868.C	(revision 0)
+++ libgomp/testsuite/libgomp.c++/pr64868.C	(revision 220420)
@@ -0,0 +1,5 @@
+// PR c/64868
+// { dg-do run }
+// { dg-options "-O2 -fopenmp" }
+
+#include "../libgomp.c/pr64868.c"
--- libgomp/testsuite/libgomp.c++/pr64824.C	(revision 0)
+++ libgomp/testsuite/libgomp.c++/pr64824.C	(revision 220420)
@@ -0,0 +1,5 @@
+// PR c/64824
+// { dg-do run }
+// { dg-options "-O2 -fopenmp" }
+
+#include "../libgomp.c/pr64824.c"
--- libgomp/testsuite/libgomp.c/pr64868.c	(revision 0)
+++ libgomp/testsuite/libgomp.c/pr64868.c	(revision 220420)
@@ -0,0 +1,87 @@
+/* PR c/64868 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fopenmp" } */
+
+float f = 2.0f;
+double d = 4.0;
+long double ld = 8.0L;
+
+void
+foo ()
+{
+#pragma omp atomic
+  f = 1.0f / f;
+#pragma omp atomic
+  f = 1 / f;
+#pragma omp atomic
+  f = f / 2.0f;
+#pragma omp atomic
+  f = f / 2;
+#pragma omp atomic
+  f /= 2.0f;
+#pragma omp atomic
+  f /= 2;
+#pragma omp atomic
+  d = 1.0 / d;
+#pragma omp atomic
+  d = 1 / d;
+#pragma omp atomic
+  d = d / 2.0;
+#pragma omp atomic
+  d = d / 2;
+#pragma omp atomic
+  d /= 2.0;
+#pragma omp atomic
+  d /= 2;
+#pragma omp atomic
+  ld = 1.0L / ld;
+#pragma omp atomic
+  ld = 1 / ld;
+#pragma omp atomic
+  ld = ld / 2.0L;
+#pragma omp atomic
+  ld = ld / 2;
+#pragma omp atomic
+  ld /= 2.0L;
+#pragma omp atomic
+  ld /= 2;
+  if (f != 0.125f || d != 0.25 || ld != 0.5L)
+    __builtin_abort ();
+}
+
+#ifdef __cplusplus
+template <typename T, int N1, int N2>
+void
+bar ()
+{
+  T v = ::d;
+#pragma omp atomic
+  v *= 16;
+#pragma omp atomic
+  v = 1.0 / v;
+#pragma omp atomic
+  v = N1 / v;
+#pragma omp atomic
+  v = v / 2.0;
+#pragma omp atomic
+  v = v / N2;
+#pragma omp atomic
+  v /= 2.0;
+#pragma omp atomic
+  v /= N2;
+  if (v != 0.25)
+    __builtin_abort ();
+}
+#endif
+
+int
+main ()
+{
+  foo ();
+#ifdef __cplusplus
+  bar<float, 1, 2> ();
+  bar<double, 1, 2> ();
+  bar<long double, 1, 2> ();
+#endif
+  return 0;
+}
--- libgomp/testsuite/libgomp.c/pr64824.c	(revision 0)
+++ libgomp/testsuite/libgomp.c/pr64824.c	(revision 220420)
@@ -0,0 +1,16 @@
+/* PR c/64824 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fopenmp" } */
+
+int
+main ()
+{
+  long long a;
+  long long b = 1LL;
+  int c = 3;
+#pragma omp atomic capture
+  a = b = c << b;
+  if (b != 6LL || a != 6LL)
+    __builtin_abort ();
+  return 0;
+}
-------------- next part --------------
2015-02-11  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-02-09  Jakub Jelinek  <jakub@redhat.com>

	PR target/64979
	* tree-stdarg.c (pass_stdarg::execute): Scan phi node args for
	va_list escapes.

	* gcc.dg/tree-ssa/stdarg-7.c: New test.
	* gcc.c-torture/execute/pr64979.c: New test.

--- gcc/tree-stdarg.c	(revision 220542)
+++ gcc/tree-stdarg.c	(revision 220543)
@@ -823,21 +823,22 @@ execute_optimize_stdarg (void)
       /* For va_list_simple_ptr, we have to check PHI nodes too.  We treat
 	 them as assignments for the purpose of escape analysis.  This is
 	 not needed for non-simple va_list because virtual phis don't perform
-	 any real data movement.  */
-      if (va_list_simple_ptr)
-	{
-	  tree lhs, rhs;
-	  use_operand_p uop;
-	  ssa_op_iter soi;
+	 any real data movement.  Also, check PHI nodes for taking address of
+	 the va_list vars.  */
+      tree lhs, rhs;
+      use_operand_p uop;
+      ssa_op_iter soi;
 
-	  for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
-	    {
-	      gimple phi = gsi_stmt (i);
-	      lhs = PHI_RESULT (phi);
+      for (i = gsi_start_phis (bb); !gsi_end_p (i); gsi_next (&i))
+	{
+	  gimple phi = gsi_stmt (i);
+	  lhs = PHI_RESULT (phi);
 
-	      if (virtual_operand_p (lhs))
-		continue;
+	  if (virtual_operand_p (lhs))
+	    continue;
 
+	  if (va_list_simple_ptr)
+	    {
 	      FOR_EACH_PHI_ARG (uop, phi, soi, SSA_OP_USE)
 		{
 		  rhs = USE_FROM_PTR (uop);
@@ -860,6 +861,22 @@ execute_optimize_stdarg (void)
 		    }
 		}
 	    }
+
+	  for (unsigned j = 0; !va_list_escapes
+			       && j < gimple_phi_num_args (phi); ++j)
+	    if ((!va_list_simple_ptr
+		 || TREE_CODE (gimple_phi_arg_def (phi, j)) != SSA_NAME)
+		&& walk_tree (gimple_phi_arg_def_ptr (phi, j),
+			      find_va_list_reference, &wi, NULL))
+	      {
+		if (dump_file && (dump_flags & TDF_DETAILS))
+		  {
+		    fputs ("va_list escapes in ", dump_file);
+		    print_gimple_stmt (dump_file, phi, 0, dump_flags);
+		    fputc ('\n', dump_file);
+		  }
+		va_list_escapes = true;
+	      }
 	}
 
       for (i = gsi_start_bb (bb);
@@ -882,8 +899,8 @@ execute_optimize_stdarg (void)
 
 	  if (is_gimple_assign (stmt))
 	    {
-	      tree lhs = gimple_assign_lhs (stmt);
-	      tree rhs = gimple_assign_rhs1 (stmt);
+	      lhs = gimple_assign_lhs (stmt);
+	      rhs = gimple_assign_rhs1 (stmt);
 
 	      if (va_list_simple_ptr)
 		{
--- gcc/testsuite/gcc.c-torture/execute/pr64979.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/execute/pr64979.c	(revision 220543)
@@ -0,0 +1,36 @@
+/* PR target/64979 */
+
+#include <stdarg.h>
+
+void __attribute__((noinline, noclone))
+bar (int x, va_list *ap)
+{
+  if (ap)
+    {
+      int i;
+      for (i = 0; i < 10; i++)
+	if (i != va_arg (*ap, int))
+	  __builtin_abort ();
+      if (va_arg (*ap, double) != 0.5)
+	__builtin_abort ();
+    }
+}
+
+void __attribute__((noinline, noclone))
+foo (int x, ...)
+{
+  va_list ap;
+  int n;
+
+  va_start (ap, x);
+  n = va_arg (ap, int);
+  bar (x, (va_list *) ((n == 0) ? ((void *) 0) : &ap));
+  va_end (ap);
+}
+
+int
+main ()
+{
+  foo (100, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0.5);
+  return 0;
+}
--- gcc/testsuite/gcc.dg/tree-ssa/stdarg-7.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/stdarg-7.c	(revision 220543)
@@ -0,0 +1,22 @@
+/* PR target/64979 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-stdarg" } */
+
+#include <stdarg.h>
+
+void bar (int x, va_list *ap);
+
+void
+foo (int x, ...)
+{
+  va_list ap;
+  int n;
+
+  va_start (ap, x);
+  n = va_arg (ap, int);
+  bar (x, (va_list *) ((n == 0) ? ((void *) 0) : &ap));
+  va_end (ap);
+}
+
+/* { dg-final { scan-tree-dump "foo: va_list escapes 1, needs to save all GPR units and all FPR units" "stdarg" } } */
+/* { dg-final { cleanup-tree-dump "stdarg" } } */
-------------- next part --------------
2015-02-11  Jakub Jelinek  <jakub@redhat.com>

	PR c/64824
	* c-parser.c (c_parser_binary_expression): Fix OpenMP stack[sp].prec
	check in the POP macro.

	* testsuite/libgomp.c/atomic-18.c: New test.
	* testsuite/libgomp.c++/atomic-16.C: New test.

--- gcc/c/c-parser.c	(revision 220616)
+++ gcc/c/c-parser.c	(revision 220617)
@@ -6233,8 +6233,8 @@ c_parser_binary_expression (c_parser *pa
     if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1	      \
 	&& c_parser_peek_token (parser)->type == CPP_SEMICOLON		      \
 	&& ((1 << stack[sp].prec)					      \
-	    & (1 << (PREC_BITOR | PREC_BITXOR | PREC_BITAND | PREC_SHIFT      \
-		     | PREC_ADD | PREC_MULT)))				      \
+	    & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND)    \
+	       | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT)))     \
 	&& stack[sp].op != TRUNC_MOD_EXPR				      \
 	&& stack[0].expr.value != error_mark_node			      \
 	&& stack[1].expr.value != error_mark_node			      \
--- libgomp/testsuite/libgomp.c/atomic-18.c	(revision 0)
+++ libgomp/testsuite/libgomp.c/atomic-18.c	(revision 220617)
@@ -0,0 +1,61 @@
+/* PR c/64824 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fopenmp" } */
+
+void
+f1 (void)
+{
+  short a;
+  short b = 1;
+  int c = 3;
+#pragma omp atomic capture
+  a = b = c << b;
+  if (b != 6 || a != 6)
+    __builtin_abort ();
+}
+
+void
+f2 (void)
+{
+  short a;
+  short b = 1;
+  int c = 3;
+#pragma omp atomic capture
+  a = b = c + b;
+  if (b != 4 || a != 4)
+    __builtin_abort ();
+}
+
+void
+f3 (void)
+{
+  short a;
+  short b = 1;
+  long long int c = 3;
+#pragma omp atomic capture
+  a = b = c + b;
+  if (b != 4 || a != 4)
+    __builtin_abort ();
+}
+
+void
+f4 (void)
+{
+  char a;
+  char b = 1;
+  long long int c = 3LL;
+#pragma omp atomic capture
+  a = b = c << b;
+  if (b != 6 || a != 6)
+    __builtin_abort ();
+}
+
+int
+main ()
+{
+  f1 ();
+  f2 ();
+  f3 ();
+  f4 ();
+  return 0;
+}
--- libgomp/testsuite/libgomp.c++/atomic-16.C	(revision 0)
+++ libgomp/testsuite/libgomp.c++/atomic-16.C	(revision 220617)
@@ -0,0 +1,5 @@
+// PR c/64824
+// { dg-do run }
+// { dg-options "-O2 -fopenmp" }
+
+#include "../libgomp.c/atomic-18.c"


More information about the Gcc-patches mailing list