Hi! I've bootstrapped/regtested and committed following 5 backports from mainline to 7.x.
Jakub
2017-07-17 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-06-30 Jakub Jelinek <ja...@redhat.com> PR target/81225 * config/i386/sse.md (vec_extract_lo_<mode><mask_name>): For V8FI, V16FI and VI8F_256 iterators, use <store_mask_predicate> instead of nonimmediate_operand and <store_mask_constraint> instead of m for the input operand. For V8FI iterator, always split if input is a MEM. For V16FI and V8SF_256 iterators, don't test if both operands are MEM if <mask_applied>. For VI4F_256 iterator, use <store_mask_predicate> instead of register_operand and <store_mask_constraint> instead of v for the input operand. Make sure both operands aren't MEMs for if not <mask_applied>. * gcc.target/i386/pr81225.c: New test. --- gcc/config/i386/sse.md (revision 249843) +++ gcc/config/i386/sse.md (revision 249844) @@ -7359,13 +7359,13 @@ (define_insn "vec_extract_lo_<mode>_mask (define_insn "vec_extract_lo_<mode><mask_name>" [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=<store_mask_constraint>,v") (vec_select:<ssehalfvecmode> - (match_operand:V8FI 1 "nonimmediate_operand" "v,m") + (match_operand:V8FI 1 "<store_mask_predicate>" "v,<store_mask_constraint>") (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)])))] "TARGET_AVX512F && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))" { - if (<mask_applied> || !TARGET_AVX512VL) + if (<mask_applied> || (!TARGET_AVX512VL && !MEM_P (operands[1]))) return "vextract<shuffletype>64x4\t{$0x0, %1, %0<mask_operand2>|%0<mask_operand2>, %1, 0x0}"; else return "#"; @@ -7515,14 +7515,15 @@ (define_expand "avx_vextractf128<mode>" (define_insn "vec_extract_lo_<mode><mask_name>" [(set (match_operand:<ssehalfvecmode> 0 "nonimmediate_operand" "=v,m") (vec_select:<ssehalfvecmode> - (match_operand:V16FI 1 "nonimmediate_operand" "vm,v") + (match_operand:V16FI 1 "<store_mask_predicate>" + "<store_mask_constraint>,v") (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3) (const_int 4) (const_int 5) (const_int 6) (const_int 7)])))] "TARGET_AVX512F && <mask_mode512bit_condition> - && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))" { if (<mask_applied>) return "vextract<shuffletype>32x8\t{$0x0, %1, %0<mask_operand2>|%0<mask_operand2>, %1, 0x0}"; @@ -7546,11 +7547,12 @@ (define_split (define_insn "vec_extract_lo_<mode><mask_name>" [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=v,m") (vec_select:<ssehalfvecmode> - (match_operand:VI8F_256 1 "nonimmediate_operand" "vm,v") + (match_operand:VI8F_256 1 "<store_mask_predicate>" + "<store_mask_constraint>,v") (parallel [(const_int 0) (const_int 1)])))] "TARGET_AVX && <mask_avx512vl_condition> && <mask_avx512dq_condition> - && !(MEM_P (operands[0]) && MEM_P (operands[1]))" + && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))" { if (<mask_applied>) return "vextract<shuffletype>64x2\t{$0x0, %1, %0%{%3%}|%0%{%3%}, %1, 0x0}"; @@ -7610,12 +7612,16 @@ (define_split "operands[1] = gen_lowpart (<ssehalfvecmode>mode, operands[1]);") (define_insn "vec_extract_lo_<mode><mask_name>" - [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" "=<store_mask_constraint>") + [(set (match_operand:<ssehalfvecmode> 0 "<store_mask_predicate>" + "=<store_mask_constraint>,v") (vec_select:<ssehalfvecmode> - (match_operand:VI4F_256 1 "register_operand" "v") + (match_operand:VI4F_256 1 "<store_mask_predicate>" + "v,<store_mask_constraint>") (parallel [(const_int 0) (const_int 1) (const_int 2) (const_int 3)])))] - "TARGET_AVX && <mask_avx512vl_condition> && <mask_avx512dq_condition>" + "TARGET_AVX + && <mask_avx512vl_condition> && <mask_avx512dq_condition> + && (<mask_applied> || !(MEM_P (operands[0]) && MEM_P (operands[1])))" { if (<mask_applied>) return "vextract<shuffletype>32x4\t{$0x0, %1, %0<mask_operand2>|%0<mask_operand2>, %1, 0x0}"; --- gcc/testsuite/gcc.target/i386/pr81225.c (nonexistent) +++ gcc/testsuite/gcc.target/i386/pr81225.c (revision 249844) @@ -0,0 +1,14 @@ +/* PR target/81225 */ +/* { dg-do compile } */ +/* { dg-options "-mavx512ifma -O3 -ffloat-store" } */ + +long a[24]; +float b[4], c[24]; +int d; + +void +foo () +{ + for (d = 0; d < 24; d++) + c[d] = (float) d ? : b[a[d]]; +}
2017-07-17 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-07-04 Jakub Jelinek <ja...@redhat.com> PR c++/81258 * parser.c (cp_parser_decomposition_declaration): Diagnose invalid forms of structured binding initializers. * g++.dg/cpp1z/decomp21.C (foo): Adjust expected diagnostics. * g++.dg/cpp1z/decomp30.C: New test. --- gcc/cp/parser.c (revision 249946) +++ gcc/cp/parser.c (revision 249947) @@ -13210,6 +13210,16 @@ cp_parser_decomposition_declaration (cp_ *init_loc = cp_lexer_peek_token (parser->lexer)->location; tree initializer = cp_parser_initializer (parser, &is_direct_init, &non_constant_p); + if (initializer == NULL_TREE + || (TREE_CODE (initializer) == TREE_LIST + && TREE_CHAIN (initializer)) + || (TREE_CODE (initializer) == CONSTRUCTOR + && CONSTRUCTOR_NELTS (initializer) != 1)) + { + error_at (loc, "invalid initializer for structured binding " + "declaration"); + initializer = error_mark_node; + } if (decl != error_mark_node) { --- gcc/testsuite/g++.dg/cpp1z/decomp21.C (revision 249946) +++ gcc/testsuite/g++.dg/cpp1z/decomp21.C (revision 249947) @@ -12,5 +12,6 @@ foo () auto [ n, o, p ] { a }; auto [ q, r, t ] ( s ); auto [ u, v, w ] ( s, ); // { dg-error "expected primary-expression before '.' token" } - auto [ x, y, z ] ( a ); // { dg-error "expression list treated as compound expression in initializer" "" { target *-*-* } .-1 } + // { dg-error "invalid initializer for structured binding declaration" "" { target *-*-* } .-1 } + auto [ x, y, z ] ( a ); } --- gcc/testsuite/g++.dg/cpp1z/decomp30.C (nonexistent) +++ gcc/testsuite/g++.dg/cpp1z/decomp30.C (revision 249947) @@ -0,0 +1,12 @@ +// PR c++/81258 +// { dg-options -std=c++1z } + +int a[2]; +auto [b, c] (a); +auto [d, e] { a }; +auto [f, g] = a; +auto [h, i] ( a, a ); // { dg-error "invalid initializer for structured binding declaration" } +auto [j, k] { a, a }; // { dg-error "invalid initializer for structured binding declaration" } +auto [l, m] = { a }; // { dg-error "deducing from brace-enclosed initializer list requires" } +auto [n, o] {}; // { dg-error "invalid initializer for structured binding declaration" } +auto [p, q] (); // { dg-error "invalid initializer for structured binding declaration" }
2017-07-17 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2017-07-14 Jakub Jelinek <ja...@redhat.com> PR sanitizer/81066 * sanitizer_common/sanitizer_linux.h: Cherry-pick upstream r307969. * sanitizer_common/sanitizer_linux.cc: Likewise. * sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc: Likewise. * tsan/tsan_platform_linux.cc: Likewise. --- libsanitizer/sanitizer_common/sanitizer_linux.cc (revision 250199) +++ libsanitizer/sanitizer_common/sanitizer_linux.cc (revision 250200) @@ -605,8 +605,7 @@ uptr internal_prctl(int option, uptr arg } #endif -uptr internal_sigaltstack(const struct sigaltstack *ss, - struct sigaltstack *oss) { +uptr internal_sigaltstack(const void *ss, void *oss) { return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss); } --- libsanitizer/sanitizer_common/sanitizer_linux.h (revision 250199) +++ libsanitizer/sanitizer_common/sanitizer_linux.h (revision 250200) @@ -19,7 +19,6 @@ #include "sanitizer_platform_limits_posix.h" struct link_map; // Opaque type returned by dlopen(). -struct sigaltstack; namespace __sanitizer { // Dirent structure for getdents(). Note that this structure is different from @@ -28,8 +27,7 @@ struct linux_dirent; // Syscall wrappers. uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count); -uptr internal_sigaltstack(const struct sigaltstack* ss, - struct sigaltstack* oss); +uptr internal_sigaltstack(const void* ss, void* oss); uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset); --- libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc (revision 250199) +++ libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc (revision 250200) @@ -273,7 +273,7 @@ static int TracerThread(void* argument) // Alternate stack for signal handling. InternalScopedBuffer<char> handler_stack_memory(kHandlerStackSize); - struct sigaltstack handler_stack; + stack_t handler_stack; internal_memset(&handler_stack, 0, sizeof(handler_stack)); handler_stack.ss_sp = handler_stack_memory.data(); handler_stack.ss_size = kHandlerStackSize; --- libsanitizer/tsan/tsan_platform_linux.cc (revision 250199) +++ libsanitizer/tsan/tsan_platform_linux.cc (revision 250200) @@ -287,7 +287,7 @@ void InitializePlatform() { int ExtractResolvFDs(void *state, int *fds, int nfd) { #if SANITIZER_LINUX && !SANITIZER_ANDROID int cnt = 0; - __res_state *statp = (__res_state*)state; + struct __res_state *statp = (struct __res_state*)state; for (int i = 0; i < MAXNS && cnt < nfd; i++) { if (statp->_u._ext.nsaddrs[i] && statp->_u._ext.nssocks[i] != -1) fds[cnt++] = statp->_u._ext.nssocks[i];
2017-07-17 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/81365 * tree-ssa-phiprop.c (propagate_with_phi): When considering hoisting aggregate moves onto bb predecessor edges, make sure there are no loads that could alias the lhs in between the start of bb and the loads from *phi. * g++.dg/torture/pr81365.C: New test. --- gcc/tree-ssa-phiprop.c (revision 250260) +++ gcc/tree-ssa-phiprop.c (revision 250261) @@ -327,7 +327,7 @@ propagate_with_phi (basic_block bb, gphi if (!dominated_by_p (CDI_POST_DOMINATORS, bb, gimple_bb (use_stmt))) continue; - + /* Check whether this is a load of *ptr. */ if (!(is_gimple_assign (use_stmt) && gimple_assign_rhs_code (use_stmt) == MEM_REF @@ -356,6 +356,9 @@ propagate_with_phi (basic_block bb, gphi insert aggregate copies on the edges instead. */ if (!is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr)))) { + if (!gimple_vdef (use_stmt)) + goto next; + /* As we replicate the lhs on each incoming edge all used SSA names have to be available there. */ if (! for_each_index (gimple_assign_lhs_ptr (use_stmt), @@ -363,6 +366,28 @@ propagate_with_phi (basic_block bb, gphi get_immediate_dominator (CDI_DOMINATORS, gimple_bb (phi)))) goto next; + + gimple *vuse_stmt; + imm_use_iterator vui; + use_operand_p vuse_p; + /* In order to move the aggregate copies earlier, make sure + there are no statements that could read from memory + aliasing the lhs in between the start of bb and use_stmt. + As we require use_stmt to have a VDEF above, loads after + use_stmt will use a different virtual SSA_NAME. */ + FOR_EACH_IMM_USE_FAST (vuse_p, vui, vuse) + { + vuse_stmt = USE_STMT (vuse_p); + if (vuse_stmt == use_stmt) + continue; + if (!dominated_by_p (CDI_DOMINATORS, + gimple_bb (vuse_stmt), bb)) + continue; + if (ref_maybe_used_by_stmt_p (vuse_stmt, + gimple_assign_lhs (use_stmt))) + goto next; + } + phiprop_insert_phi (bb, phi, use_stmt, phivn, n); /* Remove old stmt. The phi is taken care of by DCE. */ --- gcc/testsuite/g++.dg/torture/pr81365.C (nonexistent) +++ gcc/testsuite/g++.dg/torture/pr81365.C (revision 250261) @@ -0,0 +1,39 @@ +// PR tree-optimization/81365 +// { dg-do run } + +struct A { unsigned a; }; + +struct B { + B (const A *x) + { + __builtin_memcpy (b, x, 3 * sizeof (A)); + __builtin_memcpy (c, x + 3, sizeof (A)); + __builtin_memset (c + 1, 0, sizeof (A)); + } + bool + foo (unsigned x) + { + A *it = c; + if (it->a == x || (++it)->a == x) + { + A t(b[0]); + b[0] = *it; + *it = t; + return true; + } + return false; + } + A b[3]; + A c[2]; +}; + +int +main () +{ + A x[] = { 4, 8, 12, 18 }; + B y(x); + if (!y.foo (18)) + __builtin_abort (); + if (!y.foo (4)) + __builtin_abort (); +}
2017-07-17 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/81428 * match.pd (X / X -> one): Don't optimize _Fract divisions, as 1 can't be built for those types. * gcc.dg/fixed-point/pr81428.c: New test. --- gcc/match.pd (revision 250264) +++ gcc/match.pd (revision 250265) @@ -243,8 +243,9 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) /* X / X is one. */ (simplify (div @0 @0) - /* But not for 0 / 0 so that we can get the proper warnings and errors. */ - (if (!integer_zerop (@0)) + /* But not for 0 / 0 so that we can get the proper warnings and errors. + And not for _Fract types where we can't build 1. */ + (if (!integer_zerop (@0) && !ALL_FRACT_MODE_P (TYPE_MODE (type))) { build_one_cst (type); })) /* X / abs (X) is X < 0 ? -1 : 1. */ (simplify --- gcc/testsuite/gcc.dg/fixed-point/pr81428.c (nonexistent) +++ gcc/testsuite/gcc.dg/fixed-point/pr81428.c (revision 250265) @@ -0,0 +1,9 @@ +/* PR tree-optimization/81428 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void +foo (long _Fract *a, long _Fract *b) +{ + *b = *a / *a; +}