Hi! I've backported a few patches of mine to 4.9 branch, bootstrapped/regtested on x86_64-linux and i686-linux, committed to 4.9 branch.
Jakub
2014-11-28 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2014-10-31 Jakub Jelinek <ja...@redhat.com> PR rtl-optimization/63659 * ree.c (update_reg_equal_equiv_notes): New function. (combine_set_extension, transform_ifelse): Use it. * gcc.c-torture/execute/pr63659.c: New test. --- gcc/ree.c (revision 216984) +++ gcc/ree.c (revision 216985) @@ -261,6 +261,50 @@ typedef struct ext_cand static int max_insn_uid; +/* Update or remove REG_EQUAL or REG_EQUIV notes for INSN. */ + +static bool +update_reg_equal_equiv_notes (rtx insn, enum machine_mode new_mode, + enum machine_mode old_mode, enum rtx_code code) +{ + rtx *loc = ®_NOTES (insn); + while (*loc) + { + enum reg_note kind = REG_NOTE_KIND (*loc); + if (kind == REG_EQUAL || kind == REG_EQUIV) + { + rtx orig_src = XEXP (*loc, 0); + /* Update equivalency constants. Recall that RTL constants are + sign-extended. */ + if (GET_CODE (orig_src) == CONST_INT + && HOST_BITS_PER_WIDE_INT >= GET_MODE_BITSIZE (new_mode)) + { + if (INTVAL (orig_src) >= 0 || code == SIGN_EXTEND) + /* Nothing needed. */; + else + { + /* Zero-extend the negative constant by masking out the + bits outside the source mode. */ + rtx new_const_int + = gen_int_mode (INTVAL (orig_src) + & GET_MODE_MASK (old_mode), + new_mode); + if (!validate_change (insn, &XEXP (*loc, 0), + new_const_int, true)) + return false; + } + loc = &XEXP (*loc, 1); + } + /* Drop all other notes, they assume a wrong mode. */ + else if (!validate_change (insn, loc, XEXP (*loc, 1), true)) + return false; + } + else + loc = &XEXP (*loc, 1); + } + return true; +} + /* Given a insn (CURR_INSN), an extension candidate for removal (CAND) and a pointer to the SET rtx (ORIG_SET) that needs to be modified, this code modifies the SET rtx to a new SET rtx that extends the @@ -282,6 +326,7 @@ static bool combine_set_extension (ext_cand *cand, rtx curr_insn, rtx *orig_set) { rtx orig_src = SET_SRC (*orig_set); + enum machine_mode orig_mode = GET_MODE (SET_DEST (*orig_set)); rtx new_set; rtx cand_pat = PATTERN (cand->insn); @@ -318,9 +363,8 @@ combine_set_extension (ext_cand *cand, r { /* Zero-extend the negative constant by masking out the bits outside the source mode. */ - enum machine_mode src_mode = GET_MODE (SET_DEST (*orig_set)); rtx new_const_int - = gen_int_mode (INTVAL (orig_src) & GET_MODE_MASK (src_mode), + = gen_int_mode (INTVAL (orig_src) & GET_MODE_MASK (orig_mode), GET_MODE (new_reg)); new_set = gen_rtx_SET (VOIDmode, new_reg, new_const_int); } @@ -359,7 +403,9 @@ combine_set_extension (ext_cand *cand, r /* This change is a part of a group of changes. Hence, validate_change will not try to commit the change. */ - if (validate_change (curr_insn, orig_set, new_set, true)) + if (validate_change (curr_insn, orig_set, new_set, true) + && update_reg_equal_equiv_notes (curr_insn, cand->mode, orig_mode, + cand->code)) { if (dump_file) { @@ -409,7 +455,9 @@ transform_ifelse (ext_cand *cand, rtx de ifexpr = gen_rtx_IF_THEN_ELSE (cand->mode, cond, map_srcreg, map_srcreg2); new_set = gen_rtx_SET (VOIDmode, map_dstreg, ifexpr); - if (validate_change (def_insn, &PATTERN (def_insn), new_set, true)) + if (validate_change (def_insn, &PATTERN (def_insn), new_set, true) + && update_reg_equal_equiv_notes (def_insn, cand->mode, GET_MODE (dstreg), + cand->code)) { if (dump_file) { --- gcc/testsuite/gcc.c-torture/execute/pr63659.c (revision 0) +++ gcc/testsuite/gcc.c-torture/execute/pr63659.c (revision 216985) @@ -0,0 +1,29 @@ +/* PR rtl-optimization/63659 */ + +int a, b, c, *d = &b, g, h, i; +unsigned char e; +char f; + +int +main () +{ + while (a) + { + for (a = 0; a; a++) + for (; c; c++) + ; + if (i) + break; + } + + char j = c, k = -1, l; + l = g = j >> h; + f = l == 0 ? k : k % l; + e = 0 ? 0 : f; + *d = e; + + if (b != 255) + __builtin_abort (); + + return 0; +}
2014-11-28 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2014-11-19 Jakub Jelinek <ja...@redhat.com> PR sanitizer/63913 * ubsan.c: Include tree-eh.h. (instrument_bool_enum_load): Handle loads that can throw. * g++.dg/ubsan/pr63913.C: New test. --- gcc/ubsan.c (revision 217754) +++ gcc/ubsan.c (revision 217755) @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. #include "asan.h" #include "gimplify-me.h" #include "intl.h" +#include "tree-eh.h" /* Map from a tree to a VAR_DECL tree. */ @@ -807,7 +808,9 @@ instrument_bool_enum_load (gimple_stmt_i || TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME) return; + bool can_throw = stmt_could_throw_p (stmt); location_t loc = gimple_location (stmt); + tree lhs = gimple_assign_lhs (stmt); tree ptype = build_pointer_type (TREE_TYPE (rhs)); tree atype = reference_alias_ptr_type (rhs); gimple g = gimple_build_assign (make_ssa_name (ptype, NULL), @@ -817,9 +820,24 @@ instrument_bool_enum_load (gimple_stmt_i tree mem = build2 (MEM_REF, utype, gimple_assign_lhs (g), build_int_cst (atype, 0)); tree urhs = make_ssa_name (utype, NULL); - g = gimple_build_assign (urhs, mem); - gimple_set_location (g, loc); - gsi_insert_before (gsi, g, GSI_SAME_STMT); + if (can_throw) + { + gimple_assign_set_lhs (stmt, urhs); + g = gimple_build_assign_with_ops (NOP_EXPR, lhs, urhs, NULL_TREE); + gimple_set_location (g, loc); + edge e = find_fallthru_edge (gimple_bb (stmt)->succs); + gsi_insert_on_edge_immediate (e, g); + gimple_assign_set_rhs_from_tree (gsi, mem); + update_stmt (stmt); + *gsi = gsi_for_stmt (g); + g = stmt; + } + else + { + g = gimple_build_assign (urhs, mem); + gimple_set_location (g, loc); + gsi_insert_before (gsi, g, GSI_SAME_STMT); + } minv = fold_convert (utype, minv); maxv = fold_convert (utype, maxv); if (!integer_zerop (minv)) @@ -841,8 +859,11 @@ instrument_bool_enum_load (gimple_stmt_i gimple_set_location (g, loc); gsi_insert_after (gsi, g, GSI_NEW_STMT); - gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE); - update_stmt (stmt); + if (!can_throw) + { + gimple_assign_set_rhs_with_ops (&gsi2, NOP_EXPR, urhs, NULL_TREE); + update_stmt (stmt); + } tree data = ubsan_create_data ("__ubsan_invalid_value_data", &loc, NULL, --- gcc/testsuite/g++.dg/ubsan/pr63913.C (revision 0) +++ gcc/testsuite/g++.dg/ubsan/pr63913.C (revision 217755) @@ -0,0 +1,12 @@ +// PR sanitizer/63913 +// { dg-do compile } +// { dg-options "-fsanitize=bool -fnon-call-exceptions" } + +struct B { B (); ~B (); }; + +double +foo (bool *x) +{ + B b; + return *x; +}
2014-11-28 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2014-11-19 Jakub Jelinek <ja...@redhat.com> PR tree-optimization/63915 * tree-vect-stmts.c (vectorizable_simd_clone_call): Pass true instead of false as last argument to gsi_replace. * c-c++-common/gomp/pr60823-4.c: New test. --- gcc/tree-vect-stmts.c (revision 217758) +++ gcc/tree-vect-stmts.c (revision 217759) @@ -3195,7 +3195,7 @@ vectorizable_simd_clone_call (gimple stm set_vinfo_for_stmt (new_stmt, stmt_info); set_vinfo_for_stmt (stmt, NULL); STMT_VINFO_STMT (stmt_info) = new_stmt; - gsi_replace (gsi, new_stmt, false); + gsi_replace (gsi, new_stmt, true); unlink_stmt_vdef (stmt); return true; --- gcc/testsuite/c-c++-common/gomp/pr60823-4.c (revision 0) +++ gcc/testsuite/c-c++-common/gomp/pr60823-4.c (revision 217759) @@ -0,0 +1,7 @@ +/* PR tree-optimization/63915 */ +/* { dg-do run } */ +/* { dg-require-effective-target vect_simd_clones } */ +/* { dg-options "-O2 -fopenmp-simd" } */ +/* { dg-additional-options "-fpic" { target fpic } } */ + +#include "pr60823-2.c"
2014-11-28 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2014-11-24 Jakub Jelinek <ja...@redhat.com> PR fortran/63938 * trans-openmp.c (gfc_trans_omp_atomic): Make sure lhsaddr is simple enough for goa_lhs_expr_p. * libgomp.fortran/pr63938-1.f90: New test. * libgomp.fortran/pr63938-2.f90: New test. --- gcc/fortran/trans-openmp.c (revision 218030) +++ gcc/fortran/trans-openmp.c (revision 218031) @@ -2683,6 +2683,18 @@ gfc_trans_omp_atomic (gfc_code *code) } lhsaddr = save_expr (lhsaddr); + if (TREE_CODE (lhsaddr) != SAVE_EXPR + && (TREE_CODE (lhsaddr) != ADDR_EXPR + || TREE_CODE (TREE_OPERAND (lhsaddr, 0)) != VAR_DECL)) + { + /* Make sure LHS is simple enough so that goa_lhs_expr_p can recognize + it even after unsharing function body. */ + tree var = create_tmp_var_raw (TREE_TYPE (lhsaddr), NULL); + DECL_CONTEXT (var) = current_function_decl; + lhsaddr = build4 (TARGET_EXPR, TREE_TYPE (lhsaddr), var, lhsaddr, + NULL_TREE, NULL_TREE); + } + rhs = gfc_evaluate_now (rse.expr, &block); if (((atomic_code->ext.omp_atomic & GFC_OMP_ATOMIC_MASK) --- libgomp/testsuite/libgomp.fortran/pr63938-1.f90 (revision 0) +++ libgomp/testsuite/libgomp.fortran/pr63938-1.f90 (revision 218031) @@ -0,0 +1,14 @@ +! PR fortran/63938 +! { dg-do run } + +program pr63938_1 + integer :: i, x(1) + x(1) = 0 +!$omp parallel do + do i = 1, 1000 + !$omp atomic + x(1) = x(1) + 1 + end do +!$omp end parallel do + if (x(1) .ne. 1000) call abort +end program pr63938_1 --- libgomp/testsuite/libgomp.fortran/pr63938-2.f90 (revision 0) +++ libgomp/testsuite/libgomp.fortran/pr63938-2.f90 (revision 218031) @@ -0,0 +1,18 @@ +! PR fortran/63938 +! { dg-do run } + +program pr63938_2 + type t + integer :: x + end type + integer :: i + type(t) :: x + x%x = 0 +!$omp parallel do + do i = 1, 1000 + !$omp atomic + x%x = x%x + 1 + end do +!$omp end parallel do + if (x%x .ne. 1000) call abort +end program pr63938_2
2014-11-28 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2014-11-25 Jakub Jelinek <ja...@redhat.com> PR preprocessor/60436 * line-map.c (linemap_line_start): If highest is above 0x60000000 and we are still tracking columns or highest is above 0x70000000, force add_map. --- libcpp/line-map.c (revision 218041) +++ libcpp/line-map.c (revision 218042) @@ -529,10 +529,10 @@ linemap_line_start (struct line_maps *se && line_delta * ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) > 1000) || (max_column_hint >= (1U << ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map))) || (max_column_hint <= 80 - && ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) >= 10)) - { - add_map = true; - } + && ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (map) >= 10) + || (highest > 0x60000000 + && (set->max_column_hint || highest > 0x70000000))) + add_map = true; else max_column_hint = set->max_column_hint; if (add_map) @@ -543,7 +543,7 @@ linemap_line_start (struct line_maps *se /* If the column number is ridiculous or we've allocated a huge number of source_locations, give up on column numbers. */ max_column_hint = 0; - if (highest >0x70000000) + if (highest > 0x70000000) return 0; column_bits = 0; }
2014-11-28 Jakub Jelinek <ja...@redhat.com> Backported from mainline 2014-11-27 Jakub Jelinek <ja...@redhat.com> PR middle-end/64067 * expr.c (expand_expr_addr_expr_1) <case COMPOUND_LITERAL_EXPR>: Handle it by returning address of COMPOUND_LITERAL_EXPR_DECL not only if modifier is EXPAND_INITIALIZER, but whenever COMPOUND_LITERAL_EXPR_DECL is non-NULL and TREE_STATIC. * gcc.c-torture/compile/pr64067.c: New test. --- gcc/expr.c (revision 218120) +++ gcc/expr.c (revision 218121) @@ -7677,11 +7677,13 @@ expand_expr_addr_expr_1 (tree exp, rtx t break; case COMPOUND_LITERAL_EXPR: - /* Allow COMPOUND_LITERAL_EXPR in initializers, if e.g. - rtl_for_decl_init is called on DECL_INITIAL with - COMPOUNT_LITERAL_EXPRs in it, they aren't gimplified. */ - if (modifier == EXPAND_INITIALIZER - && COMPOUND_LITERAL_EXPR_DECL (exp)) + /* Allow COMPOUND_LITERAL_EXPR in initializers or coming from + initializers, if e.g. rtl_for_decl_init is called on DECL_INITIAL + with COMPOUND_LITERAL_EXPRs in it, or ARRAY_REF on a const static + array with address of COMPOUND_LITERAL_EXPR in DECL_INITIAL; + the initializers aren't gimplified. */ + if (COMPOUND_LITERAL_EXPR_DECL (exp) + && TREE_STATIC (COMPOUND_LITERAL_EXPR_DECL (exp))) return expand_expr_addr_expr_1 (COMPOUND_LITERAL_EXPR_DECL (exp), target, tmode, modifier, as); /* FALLTHRU */ --- gcc/testsuite/gcc.c-torture/compile/pr64067.c (revision 0) +++ gcc/testsuite/gcc.c-torture/compile/pr64067.c (revision 218121) @@ -0,0 +1,10 @@ +/* PR middle-end/64067 */ + +struct S { int s; }; +int *const v[1] = { &((struct S) { .s = 42 }).s }; + +int * +foo (void) +{ + return v[0]; +}