diff mbox

[committed] 4.9 backports

Message ID 20141128133955.GP1892@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Nov. 28, 2014, 1:39 p.m. UTC
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  <jakub@redhat.com>

	Backported from mainline
	2014-10-31  Jakub Jelinek  <jakub@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.
2014-11-28  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2014-11-19  Jakub Jelinek  <jakub@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  <jakub@redhat.com>

	Backported from mainline
	2014-11-19  Jakub Jelinek  <jakub@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  <jakub@redhat.com>

	Backported from mainline
	2014-11-24  Jakub Jelinek  <jakub@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  <jakub@redhat.com>

	Backported from mainline
	2014-11-25  Jakub Jelinek  <jakub@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  <jakub@redhat.com>

	Backported from mainline
	2014-11-27  Jakub Jelinek  <jakub@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];
+}
diff mbox

Patch

--- 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 = &REG_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;
+}