Hi!

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

        Jakub
2015-02-11  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2015-02-04  Jakub Jelinek  <ja...@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;
+}
2015-02-11  Jakub Jelinek  <ja...@redhat.com>

        Backported from mainline
        2015-02-09  Jakub Jelinek  <ja...@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" } } */
2015-02-11  Jakub Jelinek  <ja...@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"

Reply via email to