Hi! I've bootstrapped/regtested on x86_64-linux and i686-linux the following backports from trunk to 6.2 and committed to 6.2.
Jakub
2016-07-02 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2016-06-20 Jakub Jelinek <ja...@redhat.com> PR target/71559 * config/i386/i386.c (ix86_fp_cmp_code_to_pcmp_immediate): Fix up returned values and add UN*/LTGT/*ORDERED cases with values matching D operand modifier on vcmp for AVX. * gcc.target/i386/sse2-pr71559.c: New test. * gcc.target/i386/avx-pr71559.c: New test. * gcc.target/i386/avx512f-pr71559.c: New test. --- gcc/config/i386/i386.c (revision 237613) +++ gcc/config/i386/i386.c (revision 237614) @@ -23622,17 +23622,33 @@ ix86_fp_cmp_code_to_pcmp_immediate (enum switch (code) { case EQ: - return 0x08; + return 0x00; case NE: return 0x04; case GT: - return 0x16; + return 0x0e; case LE: - return 0x1a; + return 0x02; case GE: - return 0x15; + return 0x0d; case LT: - return 0x19; + return 0x01; + case UNLE: + return 0x0a; + case UNLT: + return 0x09; + case UNGE: + return 0x05; + case UNGT: + return 0x06; + case UNEQ: + return 0x18; + case LTGT: + return 0x0c; + case ORDERED: + return 0x07; + case UNORDERED: + return 0x03; default: gcc_unreachable (); } --- gcc/testsuite/gcc.target/i386/avx-pr71559.c (revision 0) +++ gcc/testsuite/gcc.target/i386/avx-pr71559.c (revision 237614) @@ -0,0 +1,8 @@ +/* PR target/71559 */ +/* { dg-do run { target avx } } */ +/* { dg-options "-O2 -ftree-vectorize -mavx" } */ + +#include "avx-check.h" +#define PR71559_TEST avx_test + +#include "sse2-pr71559.c" --- gcc/testsuite/gcc.target/i386/avx512f-pr71559.c (revision 0) +++ gcc/testsuite/gcc.target/i386/avx512f-pr71559.c (revision 237614) @@ -0,0 +1,8 @@ +/* PR target/71559 */ +/* { dg-do run { target avx512f } } */ +/* { dg-options "-O2 -ftree-vectorize -mavx512f" } */ + +#include "avx512f-check.h" +#define PR71559_TEST avx512f_test + +#include "sse2-pr71559.c" --- gcc/testsuite/gcc.target/i386/sse2-pr71559.c (revision 0) +++ gcc/testsuite/gcc.target/i386/sse2-pr71559.c (revision 237614) @@ -0,0 +1,73 @@ +/* PR target/71559 */ +/* { dg-do run { target sse2 } } */ +/* { dg-options "-O2 -ftree-vectorize -msse2" } */ + +#ifndef PR71559_TEST +#include "sse2-check.h" +#define PR71559_TEST sse2_test +#endif + +#define N 16 +float a[N] = { 5.0f, -3.0f, 1.0f, __builtin_nanf (""), 9.0f, 7.0f, -3.0f, -9.0f, + -3.0f, -5.0f, -9.0f, __builtin_nanf (""), 0.5f, -0.5f, 0.0f, 0.0f }; +float b[N] = { -5.0f, 3.0f, 1.0f, 7.0f, 8.0f, 8.0f, -3.0f, __builtin_nanf (""), + -4.0f, -4.0f, -9.0f, __builtin_nanf (""), 0.0f, 0.0f, 0.0f, __builtin_nanf ("") }; +int c[N], d[N]; + +#define FN(name, op) \ +void \ +name (void) \ +{ \ + int i; \ + for (i = 0; i < N; i++) \ + c[i] = (op || d[i] > 37) ? 5 : 32; \ +} +FN (eq, a[i] == b[i]) +FN (ne, a[i] != b[i]) +FN (gt, a[i] > b[i]) +FN (ge, a[i] >= b[i]) +FN (lt, a[i] < b[i]) +FN (le, a[i] <= b[i]) +FN (unle, !__builtin_isgreater (a[i], b[i])) +FN (unlt, !__builtin_isgreaterequal (a[i], b[i])) +FN (unge, !__builtin_isless (a[i], b[i])) +FN (ungt, !__builtin_islessequal (a[i], b[i])) +FN (uneq, !__builtin_islessgreater (a[i], b[i])) +FN (ordered, !__builtin_isunordered (a[i], b[i])) +FN (unordered, __builtin_isunordered (a[i], b[i])) + +#define TEST(name, GT, LT, EQ, UO) \ + name (); \ + for (i = 0; i < N; i++) \ + { \ + int v; \ + switch (i % 4) \ + { \ + case 0: v = GT ? 5 : 32; break; \ + case 1: v = LT ? 5 : 32; break; \ + case 2: v = EQ ? 5 : 32; break; \ + case 3: v = UO ? 5 : 32; break; \ + } \ + if (c[i] != v) \ + __builtin_abort (); \ + } + +void +PR71559_TEST (void) +{ + int i; + asm volatile ("" : : "g" (a), "g" (b), "g" (c), "g" (d) : "memory"); + TEST (eq, 0, 0, 1, 0) + TEST (ne, 1, 1, 0, 1) + TEST (gt, 1, 0, 0, 0) + TEST (ge, 1, 0, 1, 0) + TEST (lt, 0, 1, 0, 0) + TEST (le, 0, 1, 1, 0) + TEST (unle, 0, 1, 1, 1) + TEST (unlt, 0, 1, 0, 1) + TEST (unge, 1, 0, 1, 1) + TEST (ungt, 1, 0, 0, 1) + TEST (uneq, 0, 0, 1, 1) + TEST (ordered, 1, 1, 1, 0) + TEST (unordered, 0, 0, 0, 1) +}
2016-07-02 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2016-06-28 Jakub Jelinek <ja...@redhat.com> PR middle-end/71626 * config/i386/i386.c (ix86_expand_vector_move): For SUBREG of a constant, force its SUBREG_REG into memory or register instead of whole op1. * gcc.c-torture/execute/pr71626-1.c: New test. * gcc.c-torture/execute/pr71626-2.c: New test. --- gcc/config/i386/i386.c (revision 237825) +++ gcc/config/i386/i386.c (revision 237826) @@ -18787,12 +18787,29 @@ ix86_expand_vector_move (machine_mode mo of the register, once we have that information we may be able to handle some of them more efficiently. */ if (can_create_pseudo_p () - && register_operand (op0, mode) && (CONSTANT_P (op1) || (SUBREG_P (op1) && CONSTANT_P (SUBREG_REG (op1)))) - && !standard_sse_constant_p (op1)) - op1 = validize_mem (force_const_mem (mode, op1)); + && ((register_operand (op0, mode) + && !standard_sse_constant_p (op1)) + /* ix86_expand_vector_move_misalign() does not like constants. */ + || (SSE_REG_MODE_P (mode) + && MEM_P (op0) + && MEM_ALIGN (op0) < align))) + { + if (SUBREG_P (op1)) + { + machine_mode imode = GET_MODE (SUBREG_REG (op1)); + rtx r = force_const_mem (imode, SUBREG_REG (op1)); + if (r) + r = validize_mem (r); + else + r = force_reg (imode, SUBREG_REG (op1)); + op1 = simplify_gen_subreg (mode, r, imode, SUBREG_BYTE (op1)); + } + else + op1 = validize_mem (force_const_mem (mode, op1)); + } /* We need to check memory alignment for SSE mode since attribute can make operands unaligned. */ @@ -18803,13 +18820,8 @@ ix86_expand_vector_move (machine_mode mo { rtx tmp[2]; - /* ix86_expand_vector_move_misalign() does not like constants ... */ - if (CONSTANT_P (op1) - || (SUBREG_P (op1) - && CONSTANT_P (SUBREG_REG (op1)))) - op1 = validize_mem (force_const_mem (mode, op1)); - - /* ... nor both arguments in memory. */ + /* ix86_expand_vector_move_misalign() does not like both + arguments in memory. */ if (!register_operand (op0, mode) && !register_operand (op1, mode)) op1 = force_reg (mode, op1); --- gcc/testsuite/gcc.c-torture/execute/pr71626-1.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/pr71626-1.c (revision 237826) @@ -0,0 +1,19 @@ +/* PR middle-end/71626 */ + +typedef __INTPTR_TYPE__ V __attribute__((__vector_size__(sizeof (__INTPTR_TYPE__)))); + +__attribute__((noinline, noclone)) V +foo () +{ + V v = { (__INTPTR_TYPE__) foo }; + return v; +} + +int +main () +{ + V v = foo (); + if (v[0] != (__INTPTR_TYPE__) foo) + __builtin_abort (); + return 0; +} --- gcc/testsuite/gcc.c-torture/execute/pr71626-2.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/pr71626-2.c (revision 237826) @@ -0,0 +1,4 @@ +/* PR middle-end/71626 */ +/* { dg-additional-options "-fpic" { target fpic } } */ + +#include "pr71626-1.c"
2016-07-02 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2016-06-29 Jakub Jelinek <ja...@redhat.com> PR c/71685 * c-typeck.c (c_build_qualified_type): Don't clear C_TYPE_INCOMPLETE_VARS for the main variant. * gcc.dg/pr71685.c: New test. --- gcc/c/c-typeck.c (revision 237829) +++ gcc/c/c-typeck.c (revision 237830) @@ -13676,7 +13676,8 @@ c_build_qualified_type (tree type, int t : build_qualified_type (type, type_quals)); /* A variant type does not inherit the list of incomplete vars from the type main variant. */ - if (RECORD_OR_UNION_TYPE_P (var_type)) + if (RECORD_OR_UNION_TYPE_P (var_type) + && TYPE_MAIN_VARIANT (var_type) != var_type) C_TYPE_INCOMPLETE_VARS (var_type) = 0; return var_type; } --- gcc/testsuite/gcc.dg/pr71685.c (revision 0) +++ gcc/testsuite/gcc.dg/pr71685.c (revision 237830) @@ -0,0 +1,6 @@ +/* PR c/71685 */ +/* { dg-do compile } */ +/* { dg-options "-std=gnu11" } */ + +extern struct S v, s; +struct S { int t; int p[]; } v = { 4, 0 };
2016-07-02 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2016-06-30 Jakub Jelinek <ja...@redhat.com> PR fortran/71705 * trans-openmp.c (gfc_trans_omp_clauses): Set TREE_ADDRESSABLE on decls in to/from clauses. * gfortran.dg/gomp/pr71705.f90: New test. --- gcc/fortran/trans-openmp.c (revision 237886) +++ gcc/fortran/trans-openmp.c (revision 237887) @@ -2182,6 +2182,8 @@ gfc_trans_omp_clauses (stmtblock_t *bloc tree decl = gfc_get_symbol_decl (n->sym); if (gfc_omp_privatize_by_reference (decl)) decl = build_fold_indirect_ref (decl); + else if (DECL_P (decl)) + TREE_ADDRESSABLE (decl) = 1; if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (decl))) { tree type = TREE_TYPE (decl); --- gcc/testsuite/gfortran.dg/gomp/pr71705.f90 (revision 0) +++ gcc/testsuite/gfortran.dg/gomp/pr71705.f90 (revision 237887) @@ -0,0 +1,7 @@ +! PR fortran/71705 +! { dg-do compile } + + real :: x + x = 0.0 + !$omp target update to(x) +end
2016-07-02 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2016-06-30 Jakub Jelinek <ja...@redhat.com> PR fortran/71704 * parse.c (matchs, matcho): Move right before decode_omp_directive. If spec_only, only gfc_match the keyword and if successful, goto do_spec_only. (matchds, matchdo): Define. (decode_omp_directive): Add spec_only local var and set it. Use matchds or matchdo macros instead of matchs or matcho for declare target, declare simd, declare reduction and threadprivate directives. Return ST_GET_FCN_CHARACTERISTICS if a non-declarative directive could be matched. (next_statement): For ST_GET_FCN_CHARACTERISTICS restore gfc_current_locus from old_locus even if there is no label. * gfortran.dg/gomp/pr71704.f90: New test. --- gcc/fortran/parse.c (revision 237887) +++ gcc/fortran/parse.c (revision 237888) @@ -589,28 +589,6 @@ decode_statement (void) return ST_NONE; } -/* Like match, but set a flag simd_matched if keyword matched. */ -#define matchs(keyword, subr, st) \ - do { \ - if (match_word_omp_simd (keyword, subr, &old_locus, \ - &simd_matched) == MATCH_YES) \ - return st; \ - else \ - undo_new_statement (); \ - } while (0); - -/* Like match, but don't match anything if not -fopenmp. */ -#define matcho(keyword, subr, st) \ - do { \ - if (!flag_openmp) \ - ; \ - else if (match_word (keyword, subr, &old_locus) \ - == MATCH_YES) \ - return st; \ - else \ - undo_new_statement (); \ - } while (0); - static gfc_statement decode_oacc_directive (void) { @@ -702,12 +680,63 @@ decode_oacc_directive (void) return ST_NONE; } +/* Like match, but set a flag simd_matched if keyword matched + and if spec_only, goto do_spec_only without actually matching. */ +#define matchs(keyword, subr, st) \ + do { \ + if (spec_only && gfc_match (keyword) == MATCH_YES) \ + goto do_spec_only; \ + if (match_word_omp_simd (keyword, subr, &old_locus, \ + &simd_matched) == MATCH_YES) \ + return st; \ + else \ + undo_new_statement (); \ + } while (0); + +/* Like match, but don't match anything if not -fopenmp + and if spec_only, goto do_spec_only without actually matching. */ +#define matcho(keyword, subr, st) \ + do { \ + if (!flag_openmp) \ + ; \ + else if (spec_only && gfc_match (keyword) == MATCH_YES) \ + goto do_spec_only; \ + else if (match_word (keyword, subr, &old_locus) \ + == MATCH_YES) \ + return st; \ + else \ + undo_new_statement (); \ + } while (0); + +/* Like match, but set a flag simd_matched if keyword matched. */ +#define matchds(keyword, subr, st) \ + do { \ + if (match_word_omp_simd (keyword, subr, &old_locus, \ + &simd_matched) == MATCH_YES) \ + return st; \ + else \ + undo_new_statement (); \ + } while (0); + +/* Like match, but don't match anything if not -fopenmp. */ +#define matchdo(keyword, subr, st) \ + do { \ + if (!flag_openmp) \ + ; \ + else if (match_word (keyword, subr, &old_locus) \ + == MATCH_YES) \ + return st; \ + else \ + undo_new_statement (); \ + } while (0); + static gfc_statement decode_omp_directive (void) { locus old_locus; char c; bool simd_matched = false; + bool spec_only = false; gfc_enforce_clean_symbol_state (); @@ -722,6 +751,10 @@ decode_omp_directive (void) return ST_NONE; } + if (gfc_current_state () == COMP_FUNCTION + && gfc_current_block ()->result->ts.kind == -1) + spec_only = true; + gfc_unset_implicit_pure (NULL); old_locus = gfc_current_locus; @@ -750,12 +783,12 @@ decode_omp_directive (void) matcho ("critical", gfc_match_omp_critical, ST_OMP_CRITICAL); break; case 'd': - matchs ("declare reduction", gfc_match_omp_declare_reduction, - ST_OMP_DECLARE_REDUCTION); - matchs ("declare simd", gfc_match_omp_declare_simd, - ST_OMP_DECLARE_SIMD); - matcho ("declare target", gfc_match_omp_declare_target, - ST_OMP_DECLARE_TARGET); + matchds ("declare reduction", gfc_match_omp_declare_reduction, + ST_OMP_DECLARE_REDUCTION); + matchds ("declare simd", gfc_match_omp_declare_simd, + ST_OMP_DECLARE_SIMD); + matchdo ("declare target", gfc_match_omp_declare_target, + ST_OMP_DECLARE_TARGET); matchs ("distribute parallel do simd", gfc_match_omp_distribute_parallel_do_simd, ST_OMP_DISTRIBUTE_PARALLEL_DO_SIMD); @@ -875,8 +908,8 @@ decode_omp_directive (void) matcho ("teams distribute", gfc_match_omp_teams_distribute, ST_OMP_TEAMS_DISTRIBUTE); matcho ("teams", gfc_match_omp_teams, ST_OMP_TEAMS); - matcho ("threadprivate", gfc_match_omp_threadprivate, - ST_OMP_THREADPRIVATE); + matchdo ("threadprivate", gfc_match_omp_threadprivate, + ST_OMP_THREADPRIVATE); break; case 'w': matcho ("workshare", gfc_match_omp_workshare, ST_OMP_WORKSHARE); @@ -899,6 +932,13 @@ decode_omp_directive (void) gfc_error_recovery (); return ST_NONE; + + do_spec_only: + reject_statement (); + gfc_clear_error (); + gfc_buffer_error (false); + gfc_current_locus = old_locus; + return ST_GET_FCN_CHARACTERISTICS; } static gfc_statement @@ -1319,10 +1359,13 @@ next_statement (void) gfc_buffer_error (false); - if (st == ST_GET_FCN_CHARACTERISTICS && gfc_statement_label != NULL) + if (st == ST_GET_FCN_CHARACTERISTICS) { - gfc_free_st_label (gfc_statement_label); - gfc_statement_label = NULL; + if (gfc_statement_label != NULL) + { + gfc_free_st_label (gfc_statement_label); + gfc_statement_label = NULL; + } gfc_current_locus = old_locus; } --- gcc/testsuite/gfortran.dg/gomp/pr71704.f90 (revision 0) +++ gcc/testsuite/gfortran.dg/gomp/pr71704.f90 (revision 237888) @@ -0,0 +1,58 @@ +! PR fortran/71704 +! { dg-do compile } + +real function f0 () +!$omp declare simd (f0) + f0 = 1 +end + +real function f1 () +!$omp declare target (f1) + f1 = 1 +end + +real function f2 () +!$omp declare reduction (foo : integer : omp_out = omp_out + omp_in) & +!$omp & initializer (omp_priv = 0) + f2 = 1 +end + +real function f3 () + real, save :: t +!$omp threadprivate (t) + f3 = 1 +end + +real function f4 () +!$omp taskwait + f4 = 1 +end + +real function f5 () +!$omp barrier + f5 = 1 +end + +real function f6 () +!$omp parallel +!$omp end parallel + f6 = 1 +end + +real function f7 () +!$omp single +!$omp end single + f7 = 1 +end + +real function f8 () +!$omp critical +!$omp end critical + f8 = 1 +end + +real function f9 () +!$omp critical +!$omp end critical + f9 = 1 +end
2016-07-02 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2016-07-01 Jakub Jelinek <ja...@redhat.com> PR fortran/71717 * trans-openmp.c (gfc_omp_privatize_by_reference): Return false for GFC_DECL_ASSOCIATE_VAR_P with POINTER_TYPE. * testsuite/libgomp.fortran/associate3.f90: New test. --- gcc/fortran/trans-openmp.c (revision 237915) +++ gcc/fortran/trans-openmp.c (revision 237916) @@ -61,6 +61,7 @@ gfc_omp_privatize_by_reference (const_tr if (GFC_DECL_GET_SCALAR_POINTER (decl) || GFC_DECL_GET_SCALAR_ALLOCATABLE (decl) || GFC_DECL_CRAY_POINTEE (decl) + || GFC_DECL_ASSOCIATE_VAR_P (decl) || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (decl)))) return false; --- libgomp/testsuite/libgomp.fortran/associate3.f90 (revision 0) +++ libgomp/testsuite/libgomp.fortran/associate3.f90 (revision 237916) @@ -0,0 +1,20 @@ +! PR fortran/71717 +! { dg-do run } + + type t + real, allocatable :: f(:) + end type + type (t) :: v + integer :: i, j + allocate (v%f(4)) + v%f = 19. + i = 5 + associate (u => v, k => i) + !$omp parallel do + do j = 1, 4 + u%f(j) = 21. + if (j.eq.1) k = 7 + end do + end associate + if (any (v%f(:).ne.21.) .or. i.ne.7) call abort +end
2016-07-02 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2016-07-01 Jakub Jelinek <ja...@redhat.com> PR fortran/71687 * f95-lang.c (struct binding_level): Add reversed field. (clear_binding_level): Adjust initializer. (getdecls): If reversed is clear, set it and nreverse the names chain before returning it. (poplevel): Use getdecls. * trans-decl.c (gfc_generate_function_code, gfc_process_block_locals): Use nreverse to pushdecl decls in the declaration order. * gfortran.dg/gomp/pr71687.f90: New test. --- gcc/fortran/f95-lang.c (revision 237925) +++ gcc/fortran/f95-lang.c (revision 237926) @@ -286,6 +286,9 @@ binding_level { tree blocks; /* The binding level containing this one (the enclosing binding level). */ struct binding_level *level_chain; + /* True if nreverse has been already called on names; if false, names + are ordered from newest declaration to oldest one. */ + bool reversed; }; /* The binding level currently in effect. */ @@ -296,7 +299,7 @@ static GTY(()) struct binding_level *cur static GTY(()) struct binding_level *global_binding_level; /* Binding level structures are initialized by copying this one. */ -static struct binding_level clear_binding_level = { NULL, NULL, NULL }; +static struct binding_level clear_binding_level = { NULL, NULL, NULL, false }; /* Return true if we are in the global binding level. */ @@ -310,6 +313,11 @@ global_bindings_p (void) tree getdecls (void) { + if (!current_binding_level->reversed) + { + current_binding_level->reversed = true; + current_binding_level->names = nreverse (current_binding_level->names); + } return current_binding_level->names; } @@ -347,7 +355,7 @@ poplevel (int keep, int functionbody) binding level that we are about to exit and which is returned by this routine. */ tree block_node = NULL_TREE; - tree decl_chain = current_binding_level->names; + tree decl_chain = getdecls (); tree subblock_chain = current_binding_level->blocks; tree subblock_node; --- gcc/fortran/trans-decl.c (revision 237925) +++ gcc/fortran/trans-decl.c (revision 237926) @@ -6277,7 +6277,7 @@ gfc_generate_function_code (gfc_namespac gfc_finish_block (&cleanup)); /* Add all the decls we created during processing. */ - decl = saved_function_decls; + decl = nreverse (saved_function_decls); while (decl) { tree next; @@ -6469,7 +6469,7 @@ gfc_process_block_locals (gfc_namespace* if (flag_coarray == GFC_FCOARRAY_LIB && has_coarray_vars) generate_coarray_init (ns); - decl = saved_local_decls; + decl = nreverse (saved_local_decls); while (decl) { tree next; --- gcc/testsuite/gfortran.dg/gomp/pr71687.f90 (revision 0) +++ gcc/testsuite/gfortran.dg/gomp/pr71687.f90 (revision 237926) @@ -0,0 +1,11 @@ +! PR fortran/71687 +! { dg-do compile } +! { dg-additional-options "-fstack-arrays -O2" } + +subroutine s (n, x) + integer :: n + real :: x(n) +!$omp parallel + x(1:n) = x(n:1:-1) +!$omp end parallel +end