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"