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 <[email protected]>
Backported from mainline
2014-10-31 Jakub Jelinek <[email protected]>
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 <[email protected]>
Backported from mainline
2014-11-19 Jakub Jelinek <[email protected]>
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 <[email protected]>
Backported from mainline
2014-11-19 Jakub Jelinek <[email protected]>
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 <[email protected]>
Backported from mainline
2014-11-24 Jakub Jelinek <[email protected]>
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 <[email protected]>
Backported from mainline
2014-11-25 Jakub Jelinek <[email protected]>
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 <[email protected]>
Backported from mainline
2014-11-27 Jakub Jelinek <[email protected]>
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];
+}