diff mbox

gcc-5-branch backports

Message ID 20160210185122.GV3017@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Feb. 10, 2016, 6:51 p.m. UTC
Hi!

I've committed following backports of my trunk commits to gcc-5-branch
after bootstrapping/regtesting them on x86_64-linux and i686-linux.

	Jakub
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-12-03  Jakub Jelinek  <jakub@redhat.com>

	PR preprocessor/57580
	* c-ppoutput.c (print): Change printed field to bool.
	Move src_file last for smaller padding.
	(init_pp_output): Set print.printed to false instead of 0.
	(scan_translation_unit): Fix up formatting.  Set print.printed
	to true after printing something other than newline.
	(scan_translation_unit_trad): Set print.printed to true instead of 1.
	(maybe_print_line_1): Set print.printed to false instead of 0.
	(print_line_1): Likewise.
	(do_line_change): Set print.printed to true instead of 1.
	(cb_define, dump_queued_macros, cb_include, cb_def_pragma,
	dump_macro): Set print.printed to false after printing newline.

	* c-c++-common/cpp/pr57580.c: New test.
	* c-c++-common/gomp/pr57580.c: New test.
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2015-12-22  Jakub Jelinek  <jakub@redhat.com>

	PR c++/67376
	* fold-const.c (size_low_cst): Removed.
	(fold_comparison): For POINTER_PLUS_EXPR where base is ADDR_EXPR
	call get_inner_reference and handle INDIRECT_REF base of it.  Use
	offset_int for computation of the bitpos.
	(fold_binary_loc) <case EQ_EXPR, NE_EXPR>: Formatting
	fixes for X +- Y CMP X and C - X CMP X folding.  Add X CMP X +- Y
	and X CMP C - X folding.

	* g++.dg/cpp0x/constexpr-67376.C: New test.

--- gcc/fold-const.c	(revision 231908)
+++ gcc/fold-const.c	(revision 231909)
@@ -8731,20 +8731,6 @@ pointer_may_wrap_p (tree base, tree offs
   return total.to_uhwi () > (unsigned HOST_WIDE_INT) size;
 }
 
-/* Return the HOST_WIDE_INT least significant bits of T, a sizetype
-   kind INTEGER_CST.  This makes sure to properly sign-extend the
-   constant.  */
-
-static HOST_WIDE_INT
-size_low_cst (const_tree t)
-{
-  HOST_WIDE_INT w = TREE_INT_CST_ELT (t, 0);
-  int prec = TYPE_PRECISION (TREE_TYPE (t));
-  if (prec < HOST_BITS_PER_WIDE_INT)
-    return sext_hwi (w, prec);
-  return w;
-}
-
 /* Subroutine of fold_binary.  This routine performs all of the
    transformations that are common to the equality/inequality
    operators (EQ_EXPR and NE_EXPR) and the ordering operators
@@ -8889,18 +8875,29 @@ fold_comparison (location_t loc, enum tr
 	  STRIP_SIGN_NOPS (base0);
 	  if (TREE_CODE (base0) == ADDR_EXPR)
 	    {
-	      base0 = TREE_OPERAND (base0, 0);
-	      indirect_base0 = true;
+	      base0
+		= get_inner_reference (TREE_OPERAND (base0, 0),
+				       &bitsize, &bitpos0, &offset0, &mode,
+				       &unsignedp, &volatilep, false);
+	      if (TREE_CODE (base0) == INDIRECT_REF)
+		base0 = TREE_OPERAND (base0, 0);
+	      else
+		indirect_base0 = true;
 	    }
-	  offset0 = TREE_OPERAND (arg0, 1);
-	  if (tree_fits_shwi_p (offset0))
-	    {
-	      HOST_WIDE_INT off = size_low_cst (offset0);
-	      if ((HOST_WIDE_INT) (((unsigned HOST_WIDE_INT) off)
-				   * BITS_PER_UNIT)
-		  / BITS_PER_UNIT == (HOST_WIDE_INT) off)
+	  if (offset0 == NULL_TREE || integer_zerop (offset0))
+	    offset0 = TREE_OPERAND (arg0, 1);
+	  else
+	    offset0 = size_binop (PLUS_EXPR, offset0,
+				  TREE_OPERAND (arg0, 1));
+	  if (TREE_CODE (offset0) == INTEGER_CST)
+	    {
+	      offset_int tem = wi::sext (wi::to_offset (offset0),
+					 TYPE_PRECISION (sizetype));
+	      tem = wi::lshift (tem, LOG2_BITS_PER_UNIT);
+	      tem += bitpos0;
+	      if (wi::fits_shwi_p (tem))
 		{
-		  bitpos0 = off * BITS_PER_UNIT;
+		  bitpos0 = tem.to_shwi ();
 		  offset0 = NULL_TREE;
 		}
 	    }
@@ -8923,18 +8920,29 @@ fold_comparison (location_t loc, enum tr
 	  STRIP_SIGN_NOPS (base1);
 	  if (TREE_CODE (base1) == ADDR_EXPR)
 	    {
-	      base1 = TREE_OPERAND (base1, 0);
-	      indirect_base1 = true;
+	      base1
+		= get_inner_reference (TREE_OPERAND (base1, 0),
+				       &bitsize, &bitpos1, &offset1, &mode,
+				       &unsignedp, &volatilep, false);
+	      if (TREE_CODE (base1) == INDIRECT_REF)
+		base1 = TREE_OPERAND (base1, 0);
+	      else
+		indirect_base1 = true;
 	    }
-	  offset1 = TREE_OPERAND (arg1, 1);
-	  if (tree_fits_shwi_p (offset1))
+	  if (offset1 == NULL_TREE || integer_zerop (offset1))
+	    offset1 = TREE_OPERAND (arg1, 1);
+	  else
+	    offset1 = size_binop (PLUS_EXPR, offset1,
+				  TREE_OPERAND (arg1, 1));
+	  if (TREE_CODE (offset1) == INTEGER_CST)
 	    {
-	      HOST_WIDE_INT off = size_low_cst (offset1);
-	      if ((HOST_WIDE_INT) (((unsigned HOST_WIDE_INT) off)
-				   * BITS_PER_UNIT)
-		  / BITS_PER_UNIT == (HOST_WIDE_INT) off)
+	      offset_int tem = wi::sext (wi::to_offset (offset1),
+					 TYPE_PRECISION (sizetype));
+	      tem = wi::lshift (tem, LOG2_BITS_PER_UNIT);
+	      tem += bitpos1;
+	      if (wi::fits_shwi_p (tem))
 		{
-		  bitpos1 = off * BITS_PER_UNIT;
+		  bitpos1 = tem.to_shwi ();
 		  offset1 = NULL_TREE;
 		}
 	    }
@@ -12375,12 +12383,27 @@ fold_binary_loc (location_t loc,
 	      || POINTER_TYPE_P (TREE_TYPE (arg0))))
 	{
 	  tree val = TREE_OPERAND (arg0, 1);
-	  return omit_two_operands_loc (loc, type,
-				    fold_build2_loc (loc, code, type,
-						 val,
-						 build_int_cst (TREE_TYPE (val),
-								0)),
-				    TREE_OPERAND (arg0, 0), arg1);
+	  val = fold_build2_loc (loc, code, type, val,
+				 build_int_cst (TREE_TYPE (val), 0));
+	  return omit_two_operands_loc (loc, type, val,
+					TREE_OPERAND (arg0, 0), arg1);
+	}
+
+      /* Transform comparisons of the form X CMP X +- Y to Y CMP 0.  */
+      if ((TREE_CODE (arg1) == PLUS_EXPR
+	   || TREE_CODE (arg1) == POINTER_PLUS_EXPR
+	   || TREE_CODE (arg1) == MINUS_EXPR)
+	  && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg1,
+									0)),
+			      arg0, 0)
+	  && (INTEGRAL_TYPE_P (TREE_TYPE (arg1))
+	      || POINTER_TYPE_P (TREE_TYPE (arg1))))
+	{
+	  tree val = TREE_OPERAND (arg1, 1);
+	  val = fold_build2_loc (loc, code, type, val,
+				 build_int_cst (TREE_TYPE (val), 0));
+	  return omit_two_operands_loc (loc, type, val,
+					TREE_OPERAND (arg1, 0), arg0);
 	}
 
       /* Transform comparisons of the form C - X CMP X if C % 2 == 1.  */
@@ -12390,12 +12413,22 @@ fold_binary_loc (location_t loc,
 									1)),
 			      arg1, 0)
 	  && wi::extract_uhwi (TREE_OPERAND (arg0, 0), 0, 1) == 1)
-	{
-	  return omit_two_operands_loc (loc, type,
-				    code == NE_EXPR
-				    ? boolean_true_node : boolean_false_node,
-				    TREE_OPERAND (arg0, 1), arg1);
-	}
+	return omit_two_operands_loc (loc, type,
+				      code == NE_EXPR
+				      ? boolean_true_node : boolean_false_node,
+				      TREE_OPERAND (arg0, 1), arg1);
+
+      /* Transform comparisons of the form X CMP C - X if C % 2 == 1.  */
+      if (TREE_CODE (arg1) == MINUS_EXPR
+	  && TREE_CODE (TREE_OPERAND (arg1, 0)) == INTEGER_CST
+	  && operand_equal_p (tree_strip_nop_conversions (TREE_OPERAND (arg1,
+									1)),
+			      arg0, 0)
+	  && wi::extract_uhwi (TREE_OPERAND (arg1, 0), 0, 1) == 1)
+	return omit_two_operands_loc (loc, type,
+				      code == NE_EXPR
+				      ? boolean_true_node : boolean_false_node,
+				      TREE_OPERAND (arg1, 1), arg0);
 
       /* Convert ABS_EXPR<x> == 0 or ABS_EXPR<x> != 0 to x == 0 or x != 0.  */
       if (TREE_CODE (arg0) == ABS_EXPR
--- gcc/testsuite/g++.dg/cpp0x/constexpr-67376.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp0x/constexpr-67376.C	(revision 231909)
@@ -0,0 +1,17 @@
+// PR c++/67376
+// { dg-do compile { target c++11 } }
+
+struct A { int e[2]; };
+constexpr A a { { 0, 1 } };
+static_assert (a.e + 1 != a.e, "");
+static_assert (a.e != a.e + 1, "");
+static_assert (a.e + 2 != a.e, "");
+static_assert (a.e != a.e + 2, "");
+static_assert (a.e + 1 > a.e, "");
+static_assert (a.e < a.e + 1, "");
+static_assert (a.e + 2 > a.e, "");
+static_assert (a.e < a.e + 2, "");
+static_assert (a.e + 1 >= a.e, "");
+static_assert (a.e <= a.e + 1, "");
+static_assert (a.e + 2 >= a.e, "");
+static_assert (a.e <= a.e + 2, "");
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-01  Jakub Jelinek  <jakub@redhat.com>

	PR target/69015
	* ifcvt.c (find_cond_trap): Give up if returnjump_p (jump).

	* gcc.dg/pr69015.c: New test.

--- gcc/ifcvt.c	(revision 232019)
+++ gcc/ifcvt.c	(revision 232020)
@@ -4526,8 +4526,11 @@ find_cond_trap (basic_block test_bb, edg
     return FALSE;
 
   /* If the conditional jump is more than just a conditional jump, then
-     we can not do if-conversion on this block.  */
-  if (! onlyjump_p (jump))
+     we can not do if-conversion on this block.  Give up for returnjump_p,
+     changing a conditional return followed by unconditional trap for
+     conditional trap followed by unconditional return is likely not
+     beneficial and harder to handle.  */
+  if (! onlyjump_p (jump) || returnjump_p (jump))
     return FALSE;
 
   /* We must be comparing objects whose modes imply the size.  */
--- gcc/testsuite/gcc.dg/pr69015.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr69015.c	(revision 232020)
@@ -0,0 +1,10 @@
+/* PR target/69015 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-if-conversion" } */
+
+void
+foo (int c)
+{
+  if (c)
+    __builtin_trap ();
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-01  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/69055
	* ubsan.c (ubsan_instrument_float_cast): Call
	initialize_sanitizer_builtins.

	* gfortran.dg/pr69055.f90: New test.

--- gcc/ubsan.c	(revision 232023)
+++ gcc/ubsan.c	(revision 232024)
@@ -1611,6 +1611,7 @@ ubsan_instrument_float_cast (location_t
     fn = build_call_expr_loc (loc, builtin_decl_explicit (BUILT_IN_TRAP), 0);
   else
     {
+      initialize_sanitizer_builtins ();
       /* Create the __ubsan_handle_float_cast_overflow fn call.  */
       tree data = ubsan_create_data ("__ubsan_float_cast_overflow_data", 0,
 				     NULL, ubsan_type_descriptor (expr_type),
--- gcc/testsuite/gfortran.dg/pr69055.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/pr69055.f90	(revision 232024)
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options "-fsanitize=float-cast-overflow" }
+
+subroutine pr69055
+  implicit none
+  integer :: n
+  real(8) :: b
+  b = huge(1.0D0)
+  n = b
+end subroutine pr69055
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-07  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/68960
	* gimple-expr.c (copy_var_decl): If var has DECL_USER_ALIGN set, copy
	it and DECL_ALIGN too.

	* testsuite/libgomp.c/pr68960.c: New test.

--- gcc/gimple-expr.c	(revision 232121)
+++ gcc/gimple-expr.c	(revision 232122)
@@ -375,6 +375,11 @@ copy_var_decl (tree var, tree name, tree
   TREE_USED (copy) = 1;
   DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
   DECL_ATTRIBUTES (copy) = DECL_ATTRIBUTES (var);
+  if (DECL_USER_ALIGN (var))
+    {
+      DECL_ALIGN (copy) = DECL_ALIGN (var);
+      DECL_USER_ALIGN (copy) = 1;
+    }
 
   return copy;
 }
--- libgomp/testsuite/libgomp.c/pr68960.c	(revision 0)
+++ libgomp/testsuite/libgomp.c/pr68960.c	(revision 232122)
@@ -0,0 +1,25 @@
+/* PR middle-end/68960 */
+/* { dg-do run } */
+
+int
+main ()
+{
+  int temp[257] __attribute__ ((aligned (256))) = { 0 };
+  #pragma omp parallel private (temp) num_threads (2)
+  {
+    int *p = &temp[0];
+    asm volatile ("" : "+g" (p));
+    if (((__UINTPTR_TYPE__) p) & 255)
+      __builtin_abort ();
+  }
+  #pragma omp parallel num_threads (2)
+  #pragma omp single
+  #pragma omp task firstprivate (temp)
+  {
+    int *p = &temp[0];
+    asm volatile ("" : "+g" (p));
+    if (((__UINTPTR_TYPE__) p) & 255)
+      __builtin_abort ();
+  }
+  return 0;
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-08  Jakub Jelinek  <jakub@redhat.com>

	PR fortran/69128
	* trans.h (OMPWS_SCALARIZER_BODY): Define.
	(OMPWS_NOWAIT): Renumber.
	* trans-stmt.c (gfc_trans_where_3): Only set OMPWS_SCALARIZER_WS
	if OMPWS_SCALARIZER_BODY is not set already, and set also
	OMPWS_SCALARIZER_BODY until the final loop creation.
	* trans-expr.c (gfc_trans_assignment_1): Likewise.
	* trans-openmp.c (gfc_trans_omp_workshare): Also clear
	OMPWS_SCALARIZER_BODY.
	* trans-array.c (gfc_trans_scalarized_loop_end): Don't create
	OMP_FOR if OMPWS_SCALARIZER_BODY is set.

	* gfortran.dg/gomp/pr69128.f90: New test.

--- gcc/fortran/trans.h	(revision 232150)
+++ gcc/fortran/trans.h	(revision 232151)
@@ -1039,7 +1039,9 @@ extern const char gfc_msg_wrong_return[]
 					   construct is not workshared.  */
 #define OMPWS_SCALARIZER_WS	4	/* Set if scalarizer should attempt
 					   to create parallel loops.  */
-#define OMPWS_NOWAIT		8	/* Use NOWAIT on OMP_FOR.  */
+#define OMPWS_SCALARIZER_BODY	8	/* Set if handling body of potential
+					   parallel loop.  */
+#define OMPWS_NOWAIT		16	/* Use NOWAIT on OMP_FOR.  */
 extern int ompws_flags;
 
 #endif /* GFC_TRANS_H */
--- gcc/fortran/trans-stmt.c	(revision 232150)
+++ gcc/fortran/trans-stmt.c	(revision 232151)
@@ -5057,10 +5057,15 @@ gfc_trans_where_3 (gfc_code * cblock, gf
   gfc_loopinfo loop;
   gfc_ss *edss = 0;
   gfc_ss *esss = 0;
+  bool maybe_workshare = false;
 
   /* Allow the scalarizer to workshare simple where loops.  */
-  if (ompws_flags & OMPWS_WORKSHARE_FLAG)
-    ompws_flags |= OMPWS_SCALARIZER_WS;
+  if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
+      == OMPWS_WORKSHARE_FLAG)
+    {
+      maybe_workshare = true;
+      ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
+    }
 
   cond = cblock->expr1;
   tdst = cblock->next->expr1;
@@ -5160,6 +5165,8 @@ gfc_trans_where_3 (gfc_code * cblock, gf
   gfc_add_expr_to_block (&body, tmp);
   gfc_add_block_to_block (&body, &cse.post);
 
+  if (maybe_workshare)
+    ompws_flags &= ~OMPWS_SCALARIZER_BODY;
   gfc_trans_scalarizing_loops (&loop, &body);
   gfc_add_block_to_block (&block, &loop.pre);
   gfc_add_block_to_block (&block, &loop.post);
--- gcc/fortran/trans-expr.c	(revision 232150)
+++ gcc/fortran/trans-expr.c	(revision 232151)
@@ -9160,6 +9160,7 @@ gfc_trans_assignment_1 (gfc_expr * expr1
   bool scalar_to_array;
   tree string_length;
   int n;
+  bool maybe_workshare = false;
 
   /* Assignment of the form lhs = rhs.  */
   gfc_start_block (&block);
@@ -9234,8 +9235,13 @@ gfc_trans_assignment_1 (gfc_expr * expr1
 	}
 
       /* Allow the scalarizer to workshare array assignments.  */
-      if ((ompws_flags & OMPWS_WORKSHARE_FLAG) && loop.temp_ss == NULL)
-	ompws_flags |= OMPWS_SCALARIZER_WS;
+      if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_BODY))
+	  == OMPWS_WORKSHARE_FLAG
+	  && loop.temp_ss == NULL)
+	{
+	  maybe_workshare = true;
+	  ompws_flags |= OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY;
+	}
 
       /* Start the scalarized loop body.  */
       gfc_start_scalarized_body (&loop, &body);
@@ -9384,6 +9390,9 @@ gfc_trans_assignment_1 (gfc_expr * expr1
 	    gfc_add_expr_to_block (&loop.code[expr1->rank - 1], tmp);
 	}
 
+      if (maybe_workshare)
+	ompws_flags &= ~OMPWS_SCALARIZER_BODY;
+
       /* Generate the copying loops.  */
       gfc_trans_scalarizing_loops (&loop, &body);
 
--- gcc/fortran/trans-openmp.c	(revision 232150)
+++ gcc/fortran/trans-openmp.c	(revision 232151)
@@ -4297,7 +4297,7 @@ gfc_trans_omp_workshare (gfc_code *code,
 
       /* By default, every gfc_code is a single unit of work.  */
       ompws_flags |= OMPWS_CURR_SINGLEUNIT;
-      ompws_flags &= ~OMPWS_SCALARIZER_WS;
+      ompws_flags &= ~(OMPWS_SCALARIZER_WS | OMPWS_SCALARIZER_BODY);
 
       switch (code->op)
 	{
--- gcc/fortran/trans-array.c	(revision 232150)
+++ gcc/fortran/trans-array.c	(revision 232151)
@@ -3601,7 +3601,8 @@ gfc_trans_scalarized_loop_end (gfc_loopi
   tree init;
   tree incr;
 
-  if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS))
+  if ((ompws_flags & (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS
+		      | OMPWS_SCALARIZER_BODY))
       == (OMPWS_WORKSHARE_FLAG | OMPWS_SCALARIZER_WS)
       && n == loop->dimen - 1)
     {
--- gcc/testsuite/gfortran.dg/gomp/pr69128.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/gomp/pr69128.f90	(revision 232151)
@@ -0,0 +1,23 @@
+! PR fortran/69128
+! { dg-do compile }
+
+program test
+  implicit none
+  interface
+    subroutine use(b, c)
+      real, allocatable :: b(:), c(:)
+    end subroutine
+  end interface
+  real, allocatable :: a(:,:), b(:), c(:)
+  integer :: dim1, dim2, i,j
+  dim1=10000
+  dim2=500
+  allocate(a(dim1,dim2),b(dim1),c(dim1))
+  call random_number(a)
+
+!$omp parallel workshare
+  b(:) = maxval(a(:,:), dim=2)
+  c(:) = sum(a(:,:), dim=2)
+!$omp end parallel workshare
+  call use(b, c)
+end program
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-11  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/69214
	* tree-vrp.c (simplify_cond_using_ranges): Don't propagate
	innerop into a comparison if SSA_NAME_OCCURS_IN_ABNORMAL_PHI.
	Formatting fix.

	* gcc.c-torture/compile/pr69214.c: New test.

--- gcc/tree-vrp.c	(revision 232234)
+++ gcc/tree-vrp.c	(revision 232235)
@@ -9534,7 +9534,8 @@ simplify_cond_using_ranges (gcond *stmt)
       innerop = gimple_assign_rhs1 (def_stmt);
 
       if (TREE_CODE (innerop) == SSA_NAME
-	  && !POINTER_TYPE_P (TREE_TYPE (innerop)))
+	  && !POINTER_TYPE_P (TREE_TYPE (innerop))
+	  && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop))
 	{
 	  value_range_t *vr = get_value_range (innerop);
 
@@ -9565,8 +9566,8 @@ simplify_cond_using_ranges (gcond *stmt)
 		  else
 		    location = gimple_location (stmt);
 		  warning_at (location, OPT_Wstrict_overflow,
-		      "assuming signed overflow does not occur when "
-		      "simplifying conditional");
+			      "assuming signed overflow does not occur when "
+			      "simplifying conditional");
 		}
 
 	      tree newconst = fold_convert (TREE_TYPE (innerop), op1);
--- gcc/testsuite/gcc.c-torture/compile/pr69214.c	(revision 0)
+++ gcc/testsuite/gcc.c-torture/compile/pr69214.c	(revision 232235)
@@ -0,0 +1,17 @@
+/* PR tree-optimization/69214 */
+
+extern void bar (void);
+extern int __setjmp (char *);
+
+void
+foo (char *p)
+{
+  int d = 0;
+  bar ();
+  if (__setjmp (p))
+    return;
+  long a = d;
+  d = 8;
+  if (!a)
+    bar ();
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-14  Jakub Jelinek  <jakub@redhat.com>

	PR target/68269
	* combine.c (expand_field_assignment): Punt if compute_mode is
	unsupported scalar mode.

--- gcc/combine.c	(revision 232365)
+++ gcc/combine.c	(revision 232366)
@@ -7247,6 +7247,10 @@ expand_field_assignment (const_rtx x)
       if (len >= HOST_BITS_PER_WIDE_INT)
 	break;
 
+      /* Don't try to compute in too wide unsupported modes.  */
+      if (!targetm.scalar_mode_supported_p (compute_mode))
+	break;
+
       /* Now compute the equivalent expression.  Make a copy of INNER
 	 for the SET_DEST in case it is a MEM into which we will substitute;
 	 we don't want shared RTL in that case.  */
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-19  Jakub Jelinek  <jakub@redhat.com>

	PR rtl-optimization/68955
	PR rtl-optimization/64557
	* dse.c (record_store, check_mem_read_rtx): Don't call get_addr
	here.  Fix up formatting.
	* alias.c (get_addr): Handle VALUE +/- CONST_SCALAR_INT_P.

	* gcc.dg/torture/pr68955.c: New test.

--- gcc/dse.c	(revision 232553)
+++ gcc/dse.c	(revision 232554)
@@ -1571,14 +1571,9 @@ record_store (rtx body, bb_info_t bb_inf
 	mem_addr = base->val_rtx;
       else
 	{
-	  group_info_t group
-	    = rtx_group_vec[group_id];
+	  group_info_t group = rtx_group_vec[group_id];
 	  mem_addr = group->canon_base_addr;
 	}
-      /* get_addr can only handle VALUE but cannot handle expr like:
-	 VALUE + OFFSET, so call get_addr to get original addr for
-	 mem_addr before plus_constant.  */
-      mem_addr = get_addr (mem_addr);
       if (offset)
 	mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset);
     }
@@ -2188,14 +2183,9 @@ check_mem_read_rtx (rtx *loc, bb_info_t
 	mem_addr = base->val_rtx;
       else
 	{
-	  group_info_t group
-	    = rtx_group_vec[group_id];
+	  group_info_t group = rtx_group_vec[group_id];
 	  mem_addr = group->canon_base_addr;
 	}
-      /* get_addr can only handle VALUE but cannot handle expr like:
-	 VALUE + OFFSET, so call get_addr to get original addr for
-	 mem_addr before plus_constant.  */
-      mem_addr = get_addr (mem_addr);
       if (offset)
 	mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset);
     }
--- gcc/alias.c	(revision 232553)
+++ gcc/alias.c	(revision 232554)
@@ -2193,8 +2193,8 @@ refs_newer_value_p (const_rtx expr, rtx
 }
 
 /* Convert the address X into something we can use.  This is done by returning
-   it unchanged unless it is a value; in the latter case we call cselib to get
-   a more useful rtx.  */
+   it unchanged unless it is a VALUE or VALUE +/- constant; for VALUE
+   we call cselib to get a more useful rtx.  */
 
 rtx
 get_addr (rtx x)
@@ -2203,7 +2203,23 @@ get_addr (rtx x)
   struct elt_loc_list *l;
 
   if (GET_CODE (x) != VALUE)
-    return x;
+    {
+      if ((GET_CODE (x) == PLUS || GET_CODE (x) == MINUS)
+	  && GET_CODE (XEXP (x, 0)) == VALUE
+	  && CONST_SCALAR_INT_P (XEXP (x, 1)))
+	{
+	  rtx op0 = get_addr (XEXP (x, 0));
+	  if (op0 != XEXP (x, 0))
+	    {
+	      if (GET_CODE (x) == PLUS
+		  && GET_CODE (XEXP (x, 1)) == CONST_INT)
+		return plus_constant (GET_MODE (x), op0, INTVAL (XEXP (x, 1)));
+	      return simplify_gen_binary (GET_CODE (x), GET_MODE (x),
+					  op0, XEXP (x, 1));
+	    }
+	}
+      return x;
+    }
   v = CSELIB_VAL_PTR (x);
   if (v)
     {
--- gcc/testsuite/gcc.dg/torture/pr68955.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr68955.c	(revision 232554)
@@ -0,0 +1,41 @@
+/* PR rtl-optimization/68955 */
+/* { dg-do run } */
+/* { dg-output "ONE1ONE" } */
+
+int a, b, c, d, g, m;
+int i[7][7][5] = { { { 5 } }, { { 5 } },
+		   { { 5 }, { 5 }, { 5 }, { 5 }, { 5 }, { -1 } } };
+static int j = 11;
+short e, f, h, k, l;
+
+static void
+foo ()
+{
+  for (; e < 5; e++)
+    for (h = 3; h; h--)
+      {
+	for (g = 1; g < 6; g++)
+	  {
+	    m = c == 0 ? b : b / c;
+	    i[e][1][e] = i[1][1][1] | (m & l) && f;
+	  }
+	for (k = 0; k < 6; k++)
+	  {
+	    for (d = 0; d < 6; d++)
+	      i[1][e][h] = i[h][k][e] >= l;
+	    i[e + 2][h + 3][e] = 6 & l;
+	    i[2][1][2] = a;
+	    for (; j < 5;)
+	      for (;;)
+		;
+	  }
+      }
+}
+
+int
+main ()
+{
+  foo ();
+  __builtin_printf ("ONE%dONE\n", i[1][0][2]);
+  return 0;
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-19  Jakub Jelinek  <jakub@redhat.com>

	PR debug/65779
	* shrink-wrap.c: Include valtrack.h.
	(move_insn_for_shrink_wrap): Add DEBUG argument.  If
	MAY_HAVE_DEBUG_INSNS, call dead_debug_add on DEBUG_INSNs
	in between insn and where it will be moved to.  Call
	dead_debug_insert_temp.
	(prepare_shrink_wrap): Adjust caller.  Call dead_debug_local_init
	first and dead_debug_local_finish at the end.
	For uses and defs bitmap, handle all regs in between REGNO and
	END_REGNO, not just the first one.

	* gcc.dg/pr65779.c: New test.

--- gcc/shrink-wrap.c	(revision 232557)
+++ gcc/shrink-wrap.c	(revision 232558)
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.
 #include "shrink-wrap.h"
 #include "regcprop.h"
 #include "rtl-iter.h"
+#include "valtrack.h"
 
 
 /* Return true if INSN requires the stack frame to be set up.
@@ -149,7 +150,8 @@ static bool
 move_insn_for_shrink_wrap (basic_block bb, rtx_insn *insn,
 			   const HARD_REG_SET uses,
 			   const HARD_REG_SET defs,
-			   bool *split_p)
+			   bool *split_p,
+			   struct dead_debug_local *debug)
 {
   rtx set, src, dest;
   bitmap live_out, live_in, bb_uses, bb_defs;
@@ -158,6 +160,8 @@ move_insn_for_shrink_wrap (basic_block b
   unsigned int end_sregno = FIRST_PSEUDO_REGISTER;
   basic_block next_block;
   edge live_edge;
+  rtx_insn *dinsn;
+  df_ref def;
 
   /* Look for a simple register assignment.  We don't use single_set here
      because we can't deal with any CLOBBERs, USEs, or REG_UNUSED secondary
@@ -302,6 +306,20 @@ move_insn_for_shrink_wrap (basic_block b
      move it as far as we can.  */
   do
     {
+      if (MAY_HAVE_DEBUG_INSNS)
+	{
+	  FOR_BB_INSNS_REVERSE (bb, dinsn)
+	    if (DEBUG_INSN_P (dinsn))
+	      {
+		df_ref use;
+		FOR_EACH_INSN_USE (use, dinsn)
+		  if (refers_to_regno_p (dregno, end_dregno,
+					 DF_REF_REG (use), (rtx *) NULL))
+		    dead_debug_add (debug, use, DF_REF_REGNO (use));
+	      }
+	    else if (dinsn == insn)
+	      break;
+	}
       live_out = df_get_live_out (bb);
       live_in = df_get_live_in (next_block);
       bb = next_block;
@@ -384,6 +402,12 @@ move_insn_for_shrink_wrap (basic_block b
 	SET_REGNO_REG_SET (bb_uses, i);
     }
 
+  /* Insert debug temps for dead REGs used in subsequent debug insns.  */
+  if (debug->used && !bitmap_empty_p (debug->used))
+    FOR_EACH_INSN_DEF (def, insn)
+      dead_debug_insert_temp (debug, DF_REF_REGNO (def), insn,
+			      DEBUG_TEMP_BEFORE_WITH_VALUE);
+
   emit_insn_after (PATTERN (insn), bb_note (bb));
   delete_insn (insn);
   return true;
@@ -404,6 +428,8 @@ prepare_shrink_wrap (basic_block entry_b
   HARD_REG_SET uses, defs;
   df_ref def, use;
   bool split_p = false;
+  unsigned int i;
+  struct dead_debug_local debug;
 
   if (JUMP_P (BB_END (entry_block)))
     {
@@ -414,19 +440,22 @@ prepare_shrink_wrap (basic_block entry_b
       copyprop_hardreg_forward_bb_without_debug_insn (entry_block);
     }
 
+  dead_debug_local_init (&debug, NULL, NULL);
   CLEAR_HARD_REG_SET (uses);
   CLEAR_HARD_REG_SET (defs);
+
   FOR_BB_INSNS_REVERSE_SAFE (entry_block, insn, curr)
     if (NONDEBUG_INSN_P (insn)
 	&& !move_insn_for_shrink_wrap (entry_block, insn, uses, defs,
-				       &split_p))
+				       &split_p, &debug))
       {
 	/* Add all defined registers to DEFs.  */
 	FOR_EACH_INSN_DEF (def, insn)
 	  {
 	    x = DF_REF_REG (def);
 	    if (REG_P (x) && HARD_REGISTER_P (x))
-	      SET_HARD_REG_BIT (defs, REGNO (x));
+	      for (i = REGNO (x); i < END_REGNO (x); i++)
+		SET_HARD_REG_BIT (defs, i);
 	  }
 
 	/* Add all used registers to USESs.  */
@@ -434,9 +463,12 @@ prepare_shrink_wrap (basic_block entry_b
 	  {
 	    x = DF_REF_REG (use);
 	    if (REG_P (x) && HARD_REGISTER_P (x))
-	      SET_HARD_REG_BIT (uses, REGNO (x));
+	      for (i = REGNO (x); i < END_REGNO (x); i++)
+		SET_HARD_REG_BIT (uses, i);
 	  }
       }
+
+  dead_debug_local_finish (&debug, NULL);
 }
 
 /* Return whether basic block PRO can get the prologue.  It can not if it
--- gcc/testsuite/gcc.dg/pr65779.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr65779.c	(revision 232558)
@@ -0,0 +1,42 @@
+/* PR debug/65779 */
+/* { dg-do assemble } */
+/* { dg-options "-O2 -fcompare-debug" } */
+
+unsigned long
+foo (unsigned long x, unsigned char *y, unsigned int z)
+{
+  unsigned long a = x & 0xffff;
+  unsigned long b = (x >> 16) & 0xffff;
+  int k;
+  if (y == 0) return 1L;
+  while (z > 0)
+    {
+      k = z < 5552 ? z : 5552;
+      z -= k;
+      while (k >= 16)
+	{
+          a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  a += *y++; b += a;
+	  k -= 16;
+        }
+      if (k != 0)
+	do { a += *y++; b += a; } while (--k);
+      a %= 65521L;
+      b %= 65521L;
+    }
+  return (b << 16) | a;
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-21  Jakub Jelinek  <jakub@redhat.com>

	PR middle-end/67653
	* gimplify.c (gimplify_asm_expr): Warn if it is too late to
	attempt to mark memory input operand addressable and
	call prepare_gimple_addressable in that case.  Don't adjust
	input_location for diagnostics, use error_at instead.

	* c-c++-common/pr67653.c: New test.
	* gcc.dg/torture/pr29119.c: Add dg-warning.

--- gcc/gimplify.c	(revision 232639)
+++ gcc/gimplify.c	(revision 232640)
@@ -5305,12 +5305,38 @@ gimplify_asm_expr (tree *expr_p, gimple_
 	    TREE_VALUE (link) = error_mark_node;
 	  tret = gimplify_expr (&TREE_VALUE (link), pre_p, post_p,
 				is_gimple_lvalue, fb_lvalue | fb_mayfail);
+	  if (tret != GS_ERROR)
+	    {
+	      /* Unlike output operands, memory inputs are not guaranteed
+		 to be lvalues by the FE, and while the expressions are
+		 marked addressable there, if it is e.g. a statement
+		 expression, temporaries in it might not end up being
+		 addressable.  They might be already used in the IL and thus
+		 it is too late to make them addressable now though.  */
+	      tree x = TREE_VALUE (link);
+	      while (handled_component_p (x))
+		x = TREE_OPERAND (x, 0);
+	      if (TREE_CODE (x) == MEM_REF
+		  && TREE_CODE (TREE_OPERAND (x, 0)) == ADDR_EXPR)
+		x = TREE_OPERAND (TREE_OPERAND (x, 0), 0);
+	      if ((TREE_CODE (x) == VAR_DECL
+		   || TREE_CODE (x) == PARM_DECL
+		   || TREE_CODE (x) == RESULT_DECL)
+		  && !TREE_ADDRESSABLE (x)
+		  && is_gimple_reg (x))
+		{
+		  warning_at (EXPR_LOC_OR_LOC (TREE_VALUE (link),
+					       input_location), 0,
+			      "memory input %d is not directly addressable",
+			      i);
+		  prepare_gimple_addressable (&TREE_VALUE (link), pre_p);
+		}
+	    }
 	  mark_addressable (TREE_VALUE (link));
 	  if (tret == GS_ERROR)
 	    {
-	      if (EXPR_HAS_LOCATION (TREE_VALUE (link)))
-	        input_location = EXPR_LOCATION (TREE_VALUE (link));
-	      error ("memory input %d is not directly addressable", i);
+	      error_at (EXPR_LOC_OR_LOC (TREE_VALUE (link), input_location),
+			"memory input %d is not directly addressable", i);
 	      ret = tret;
 	    }
 	}
--- gcc/testsuite/gcc.dg/torture/pr29119.c	(revision 232639)
+++ gcc/testsuite/gcc.dg/torture/pr29119.c	(revision 232640)
@@ -2,6 +2,5 @@
 
 void ldt_add_entry(void)
 {
-   __asm__ ("" :: "m"(({unsigned __v; __v;})));
+   __asm__ ("" :: "m"(({unsigned __v; __v;})));	/* { dg-warning "memory input 0 is not directly addressable" } */
 }
-
--- gcc/testsuite/c-c++-common/pr67653.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr67653.c	(revision 232640)
@@ -0,0 +1,8 @@
+/* PR middle-end/67653 */
+/* { dg-do compile } */
+
+void
+foo (void)
+{
+  __asm__ ("" : : "m" (({ static int a; a; })));	/* { dg-warning "memory input 0 is not directly addressable" } */
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-21  Stefan Sørensen  <stefan.sorensen@spectralink.com>
		    Jakub Jelinek  <jakub@redhat.com>

	PR target/69187
	PR target/65624
	* config/arm/arm-builtins.c (arm_expand_neon_builtin): Increase
	args array size by one to avoid buffer overflow.

	* gcc.target/arm/pr69187.c: New test.

--- gcc/config/arm/arm-builtins.c	(revision 232667)
+++ gcc/config/arm/arm-builtins.c	(revision 232668)
@@ -2246,7 +2246,7 @@ arm_expand_neon_builtin (int fcode, tree
   neon_builtin_datum *d =
 		&neon_builtin_data[fcode - ARM_BUILTIN_NEON_PATTERN_START];
   enum insn_code icode = d->code;
-  builtin_arg args[SIMD_MAX_BUILTIN_ARGS];
+  builtin_arg args[SIMD_MAX_BUILTIN_ARGS + 1];
   int num_args = insn_data[d->code].n_operands;
   int is_void = 0;
   int k;
--- gcc/testsuite/gcc.target/arm/pr69187.c	(revision 0)
+++ gcc/testsuite/gcc.target/arm/pr69187.c	(revision 232668)
@@ -0,0 +1,19 @@
+/* PR target/69187 */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon } */
+/* { dg-options "-O0" }  */
+/* { dg-add-options arm_neon }  */
+
+#include <arm_neon.h>
+
+int32x4_t
+foo (void)
+{
+  int32x4_t vector_int32x4;
+  int16x4_t vector3_int16x4;
+  int16x4_t vector4_int16x4;
+  static int32_t buffer_int32x4[32];
+
+  vector_int32x4 = vld1q_s32(buffer_int32x4);
+  return vqdmlsl_lane_s16(vector_int32x4, vector3_int16x4, vector4_int16x4, 0);
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-22  Jakub Jelinek  <jakub@redhat.com>

	PR target/69432
	* config/i386/i386.c: Include dojump.h.
	(expand_small_movmem_or_setmem,
	expand_set_or_movmem_prologue_epilogue_by_misaligned_moves): Spelling
	fixes.
	(ix86_expand_set_or_movmem): Call do_pending_stack_adjust () early
	if dynamic_check != -1.

	* g++.dg/opt/pr69432.C: New test.

--- gcc/config/i386/i386.c	(revision 232753)
+++ gcc/config/i386/i386.c	(revision 232754)
@@ -115,6 +115,7 @@ along with GCC; see the file COPYING3.
 #include "tree-iterator.h"
 #include "tree-chkp.h"
 #include "rtl-chkp.h"
+#include "dojump.h"
 
 static rtx legitimize_dllimport_symbol (rtx, bool);
 static rtx legitimize_pe_coff_extern_decl (rtx, bool);
@@ -24376,7 +24377,7 @@ expand_small_movmem_or_setmem (rtx destm
        if (DYNAMIC_CHECK)
 	 Round COUNT down to multiple of SIZE
        << optional caller supplied zero size guard is here >>
-       << optional caller suppplied dynamic check is here >>
+       << optional caller supplied dynamic check is here >>
        << caller supplied main copy loop is here >>
      }
    done_label:
@@ -24550,8 +24551,8 @@ expand_set_or_movmem_prologue_epilogue_b
       else
 	*min_size = 0;
 
-      /* Our loops always round down the bock size, but for dispatch to library
-	 we need precise value.  */
+      /* Our loops always round down the block size, but for dispatch to
+         library we need precise value.  */
       if (dynamic_check)
 	*count = expand_simple_binop (GET_MODE (*count), AND, *count,
 				      GEN_INT (-size), *count, 1, OPTAB_DIRECT);
@@ -25129,6 +25130,13 @@ ix86_expand_set_or_movmem (rtx dst, rtx
   size_needed = GET_MODE_SIZE (move_mode) * unroll_factor;
   epilogue_size_needed = size_needed;
 
+  /* If we are going to call any library calls conditionally, make sure any
+     pending stack adjustment happen before the first conditional branch,
+     otherwise they will be emitted before the library call only and won't
+     happen from the other branches.  */
+  if (dynamic_check != -1)
+    do_pending_stack_adjust ();
+
   desired_align = decide_alignment (align, alg, expected_size, move_mode);
   if (!TARGET_ALIGN_STRINGOPS || noalign)
     align = desired_align;
--- gcc/testsuite/g++.dg/opt/pr69432.C	(revision 0)
+++ gcc/testsuite/g++.dg/opt/pr69432.C	(revision 232754)
@@ -0,0 +1,62 @@
+// PR target/69432
+// { dg-do compile }
+// { dg-options "-O3" }
+// { dg-additional-options "-minline-stringops-dynamically" { target i?86-*-* x86_64-*-* } }
+
+template <typename S, typename T, typename U>
+void
+f1 (S x, T y, U z)
+{
+  for (; y; --y, ++x)
+    *x = z;
+}
+
+template <typename S, typename T, typename U>
+void f2 (S x, T y, U z)
+{
+  f1 (x, y, z);
+}
+
+struct A {};
+struct B { static char f3 (A, unsigned); };
+
+template <typename S, typename U>
+void f4 (S, U);
+
+struct C
+{
+  template <typename S, typename T, typename U>
+  static S f5 (S x, T y, U z) { f2 (x, y, z); }
+};
+
+template <typename S, typename T, typename U>
+void f6 (S x, T y, U z) { C::f5 (x, y, z); }
+
+template <typename S, typename T, typename U, typename V>
+void f7 (S x, T y, U z, V) { f6 (x, y, z); }
+
+struct E
+{
+  struct D : A { char e; D (A); };
+  A f;
+  E (int x) : g(f) { f8 (x); }
+  ~E ();
+  D g;
+  void f9 (int x) { x ? B::f3 (g, x) : char (); }
+  void f8 (int x) { f9 (x); }
+};
+
+struct F : E
+{
+  F (int x) : E(x) { f10 (x); f4 (this, 0); }
+  char h;
+  void f10 (int x) { f7 (&g.e, x, h, 0); }
+};
+
+long a;
+
+void
+test ()
+{
+  F b(a);
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-27  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/69399
	* wide-int.h (wi::lrshift): For larger precisions, only
	use fast path if shift is known to be < HOST_BITS_PER_WIDE_INT.

	* gcc.dg/torture/pr69399.c: New test.

--- gcc/wide-int.h	(revision 232868)
+++ gcc/wide-int.h	(revision 232869)
@@ -2909,7 +2909,9 @@ wi::lrshift (const T1 &x, const T2 &y)
 	 For variable-precision integers like wide_int, handle HWI
 	 and sub-HWI integers inline.  */
       if (STATIC_CONSTANT_P (xi.precision > HOST_BITS_PER_WIDE_INT)
-	  ? xi.len == 1 && xi.val[0] >= 0
+	  ? (shift < HOST_BITS_PER_WIDE_INT
+	     && xi.len == 1
+	     && xi.val[0] >= 0)
 	  : xi.precision <= HOST_BITS_PER_WIDE_INT)
 	{
 	  val[0] = xi.to_uhwi () >> shift;
--- gcc/testsuite/gcc.dg/torture/pr69399.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr69399.c	(revision 232869)
@@ -0,0 +1,18 @@
+/* { dg-do run { target int128 } } */
+
+static unsigned __attribute__((noinline, noclone))
+foo (unsigned long long u)
+{
+  unsigned __int128 v = u | 0xffffff81U;
+  v >>= 64;
+  return v;
+}
+
+int
+main ()
+{
+  unsigned x = foo (27);
+  if (x != 0)
+    __builtin_abort ();
+  return 0;
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-28  Jakub Jelinek  <jakub@redhat.com>

	PR pch/68176
	* files.c (_cpp_find_file): Set file->implicit_preinclude even if
	included from file->implicit_preinclude header.

--- libcpp/files.c	(revision 232955)
+++ libcpp/files.c	(revision 232956)
@@ -522,7 +522,10 @@ _cpp_find_file (cpp_reader *pfile, const
     return entry->u.file;
 
   file = make_cpp_file (pfile, start_dir, fname);
-  file->implicit_preinclude = implicit_preinclude;
+  file->implicit_preinclude
+    = (implicit_preinclude
+       || (pfile->buffer
+	   && pfile->buffer->file->implicit_preinclude));
 
   /* Try each path in the include chain.  */
   for (; !fake ;)
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-01-30  Jakub Jelinek  <jakub@redhat.com>

	PR tree-optimization/69546
	* wide-int.cc (wi::divmod_internal): For unsigned division
	where both operands fit into uhwi, if o1 is 1 and o0 has
	msb set, if divident_prec is larger than bits per hwi,
	clear another quotient word and return 2 instead of 1.
	Similarly for remainder with msb in HWI set, if dividend_prec
	is larger than bits per hwi.

	* gcc.dg/torture/pr69546.c: New test.

--- gcc/wide-int.cc	(revision 233011)
+++ gcc/wide-int.cc	(revision 233012)
@@ -1788,15 +1788,32 @@ wi::divmod_internal (HOST_WIDE_INT *quot
     {
       unsigned HOST_WIDE_INT o0 = dividend.to_uhwi ();
       unsigned HOST_WIDE_INT o1 = divisor.to_uhwi ();
+      unsigned int quotient_len = 1;
 
       if (quotient)
-	quotient[0] = o0 / o1;
+	{
+	  quotient[0] = o0 / o1;
+	  if (o1 == 1
+	      && (HOST_WIDE_INT) o0 < 0
+	      && dividend_prec > HOST_BITS_PER_WIDE_INT)
+	    {
+	      quotient[1] = 0;
+	      quotient_len = 2;
+	    }
+	}
       if (remainder)
 	{
 	  remainder[0] = o0 % o1;
-	  *remainder_len = 1;
+	  if ((HOST_WIDE_INT) remainder[0] < 0
+	      && dividend_prec > HOST_BITS_PER_WIDE_INT)
+	    {
+	      remainder[1] = 0;
+	      *remainder_len = 2;
+	    }
+	  else
+	    *remainder_len = 1;
 	}
-      return 1;
+      return quotient_len;
     }
 
   /* Make the divisor and dividend positive and remember what we
--- gcc/testsuite/gcc.dg/torture/pr69546-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr69546-1.c	(revision 233012)
@@ -0,0 +1,26 @@
+/* PR tree-optimization/69546 */
+/* { dg-do run { target int128 } } */
+
+unsigned __int128 __attribute__ ((noinline, noclone))
+foo (unsigned long long x)
+{
+  unsigned __int128 y = ~0ULL;
+  x >>= 63;
+  return y / (x | 1);
+}
+
+unsigned __int128 __attribute__ ((noinline, noclone))
+bar (unsigned long long x)
+{
+  unsigned __int128 y = ~33ULL;
+  x >>= 63;
+  return y / (x | 1);
+}
+
+int
+main ()
+{
+  if (foo (1) != ~0ULL || bar (17) != ~33ULL)
+    __builtin_abort ();
+  return 0;
+}
--- gcc/testsuite/gcc.dg/torture/pr69546-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr69546-2.c	(revision 233012)
@@ -0,0 +1,18 @@
+/* PR tree-optimization/69546 */
+/* { dg-do run { target int128 } } */
+
+unsigned __int128
+foo (void)
+{
+  unsigned __int128 a = 0xfffffffffffffffeULL;
+  unsigned __int128 b = 0xffffffffffffffffULL;
+  return a % b;
+}
+
+int
+main ()
+{
+  if (foo () != 0xfffffffffffffffeULL)
+    __builtin_abort ();
+  return 0;
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-02-04  Jakub Jelinek  <jakub@redhat.com>

	PR c/69669
	* c-decl.c (finish_enum): When honoring mode attribute,
	make sure to use proper TYPE_MIN_VALUE and TYPE_MAX_VALUE.

	* c-c++-common/pr69669.c: New test.

--- gcc/c/c-decl.c	(revision 233153)
+++ gcc/c/c-decl.c	(revision 233154)
@@ -8019,7 +8019,22 @@ finish_enum (tree enumtype, tree values,
   precision = MAX (tree_int_cst_min_precision (minnode, sign),
 		   tree_int_cst_min_precision (maxnode, sign));
 
-  if (TYPE_PACKED (enumtype) || precision > TYPE_PRECISION (integer_type_node))
+  /* If the precision of the type was specified with an attribute and it
+     was too small, give an error.  Otherwise, use it.  */
+  if (TYPE_PRECISION (enumtype))
+    {
+      if (precision > TYPE_PRECISION (enumtype))
+	{
+	  TYPE_PRECISION (enumtype) = 0;
+	  error ("specified mode too small for enumeral values");
+	}
+      else
+	precision = TYPE_PRECISION (enumtype);
+    }
+
+  if (TYPE_PACKED (enumtype)
+      || precision > TYPE_PRECISION (integer_type_node)
+      || TYPE_PRECISION (enumtype))
     {
       tem = c_common_type_for_size (precision, sign == UNSIGNED ? 1 : 0);
       if (tem == NULL)
@@ -8035,16 +8050,7 @@ finish_enum (tree enumtype, tree values,
   TYPE_MAX_VALUE (enumtype) = TYPE_MAX_VALUE (tem);
   TYPE_UNSIGNED (enumtype) = TYPE_UNSIGNED (tem);
   TYPE_SIZE (enumtype) = 0;
-
-  /* If the precision of the type was specific with an attribute and it
-     was too small, give an error.  Otherwise, use it.  */
-  if (TYPE_PRECISION (enumtype))
-    {
-      if (precision > TYPE_PRECISION (enumtype))
-	error ("specified mode too small for enumeral values");
-    }
-  else
-    TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem);
+  TYPE_PRECISION (enumtype) = TYPE_PRECISION (tem);
 
   layout_type (enumtype);
 
--- gcc/testsuite/c-c++-common/pr69669.c	(revision 0)
+++ gcc/testsuite/c-c++-common/pr69669.c	(revision 233154)
@@ -0,0 +1,10 @@
+/* PR c/69669 */
+/* { dg-do compile } */
+
+enum __attribute__((mode(QI))) E { F = 1 };
+
+void
+foo (enum E *x, int y)
+{
+  *x = (enum E) y;
+}
2016-02-10  Jakub Jelinek  <jakub@redhat.com>

	Backported from mainline
	2016-02-08  Jakub Jelinek  <jakub@redhat.com>

	PR c++/59627
	* parser.c (cp_parser_omp_declare_reduction): Set assembler name
	of the DECL_OMP_DECLARE_REDUCTION_P decls.

	* g++.dg/gomp/pr59627.C: New test.

--- gcc/cp/parser.c	(revision 233224)
+++ gcc/cp/parser.c	(revision 233225)
@@ -36080,6 +36080,7 @@ cp_parser_omp_declare_reduction (cp_pars
       DECL_DECLARED_INLINE_P (fndecl) = 1;
       DECL_IGNORED_P (fndecl) = 1;
       DECL_OMP_DECLARE_REDUCTION_P (fndecl) = 1;
+      SET_DECL_ASSEMBLER_NAME (fndecl, get_identifier ("<udr>"));
       DECL_ATTRIBUTES (fndecl)
 	= tree_cons (get_identifier ("gnu_inline"), NULL_TREE,
 		     DECL_ATTRIBUTES (fndecl));
--- gcc/testsuite/g++.dg/gomp/pr59627.C	(revision 0)
+++ gcc/testsuite/g++.dg/gomp/pr59627.C	(revision 233225)
@@ -0,0 +1,14 @@
+// PR c++/59627
+// { dg-do compile { target lto } }
+// { dg-options "-fopenmp -flto" }
+
+struct A { A () : i (0) {} int i; };
+
+void
+foo ()
+{
+  A a;
+  #pragma omp declare reduction (+: A: omp_out.i += omp_in.i)
+  #pragma omp parallel reduction (+: a)
+  ;
+}
diff mbox

Patch

--- gcc/c-family/c-ppoutput.c	(revision 231212)
+++ gcc/c-family/c-ppoutput.c	(revision 231213)
@@ -31,11 +31,11 @@  static struct
   const cpp_token *prev;	/* Previous token.  */
   const cpp_token *source;	/* Source token for spacing.  */
   int src_line;			/* Line number currently being written.  */
-  unsigned char printed;	/* Nonzero if something output at line.  */
+  bool printed;			/* True if something output at line.  */
   bool first_time;		/* pp_file_change hasn't been called yet.  */
-  const char *src_file;		/* Current source file.  */
   bool prev_was_system_token;	/* True if the previous token was a
 				   system token.*/
+  const char *src_file;		/* Current source file.  */
 } print;
 
 /* Defined and undefined macros being queued for output with -dU at
@@ -153,7 +153,7 @@  init_pp_output (FILE *out_stream)
 
   /* Initialize the print structure.  */
   print.src_line = 1;
-  print.printed = 0;
+  print.printed = false;
   print.prev = 0;
   print.outf = out_stream;
   print.first_time = 1;
@@ -206,12 +206,16 @@  scan_translation_unit (cpp_reader *pfile
 	    {
 	      line_marker_emitted = do_line_change (pfile, token, loc, false);
 	      putc (' ', print.outf);
+	      print.printed = true;
 	    }
 	  else if (print.source->flags & PREV_WHITE
 		   || (print.prev
 		       && cpp_avoid_paste (pfile, print.prev, token))
 		   || (print.prev == NULL && token->type == CPP_HASH))
-	    putc (' ', print.outf);
+	    {
+	      putc (' ', print.outf);
+	      print.printed = true;
+	    }
 	}
       else if (token->flags & PREV_WHITE)
 	{
@@ -222,6 +226,7 @@  scan_translation_unit (cpp_reader *pfile
 	      && !in_pragma)
 	    line_marker_emitted = do_line_change (pfile, token, loc, false);
 	  putc (' ', print.outf);
+	  print.printed = true;
 	}
 
       avoid_paste = false;
@@ -239,7 +244,7 @@  scan_translation_unit (cpp_reader *pfile
 	    fprintf (print.outf, "%s %s", space, name);
 	  else
 	    fprintf (print.outf, "%s", name);
-	  print.printed = 1;
+	  print.printed = true;
 	  in_pragma = true;
 	}
       else if (token->type == CPP_PRAGMA_EOL)
@@ -250,23 +255,23 @@  scan_translation_unit (cpp_reader *pfile
       else
 	{
 	  if (cpp_get_options (parse_in)->debug)
-	      linemap_dump_location (line_table, token->src_loc,
-				     print.outf);
+	    linemap_dump_location (line_table, token->src_loc, print.outf);
 
 	  if (do_line_adjustments
 	      && !in_pragma
 	      && !line_marker_emitted
-	      && print.prev_was_system_token != !!in_system_header_at(loc)
+	      && print.prev_was_system_token != !!in_system_header_at (loc)
 	      && !is_location_from_builtin_token (loc))
 	    /* The system-ness of this token is different from the one
 	       of the previous token.  Let's emit a line change to
 	       mark the new system-ness before we emit the token.  */
 	    {
 	      do_line_change (pfile, token, loc, false);
-	      print.prev_was_system_token = !!in_system_header_at(loc);
+	      print.prev_was_system_token = !!in_system_header_at (loc);
 	    }
 	  cpp_output_token (token, print.outf);
 	  line_marker_emitted = false;
+	  print.printed = true;
 	}
 
       /* CPP_COMMENT tokens and raw-string literal tokens can
@@ -316,7 +321,7 @@  scan_translation_unit_trad (cpp_reader *
       size_t len = pfile->out.cur - pfile->out.base;
       maybe_print_line (pfile->out.first_line);
       fwrite (pfile->out.base, 1, len, print.outf);
-      print.printed = 1;
+      print.printed = true;
       if (!CPP_OPTION (pfile, discard_comments))
 	account_for_newlines (pfile->out.base, len);
     }
@@ -339,7 +344,7 @@  maybe_print_line_1 (source_location src_
     {
       putc ('\n', stream);
       print.src_line++;
-      print.printed = 0;
+      print.printed = false;
     }
 
   if (!flag_no_line_commands
@@ -385,7 +390,7 @@  print_line_1 (source_location src_loc, c
   /* End any previous line of text.  */
   if (print.printed)
     putc ('\n', stream);
-  print.printed = 0;
+  print.printed = false;
 
   if (!flag_no_line_commands)
     {
@@ -460,7 +465,7 @@  do_line_change (cpp_reader *pfile, const
   if (!CPP_OPTION (pfile, traditional))
     {
       int spaces = LOCATION_COLUMN (src_loc) - 2;
-      print.printed = 1;
+      print.printed = true;
 
       while (-- spaces >= 0)
 	putc (' ', print.outf);
@@ -503,6 +508,7 @@  cb_define (cpp_reader *pfile, source_loc
     fputs ((const char *) NODE_NAME (node), print.outf);
 
   putc ('\n', print.outf);
+  print.printed = false;
   linemap_resolve_location (line_table, line,
 			    LRK_MACRO_DEFINITION_LOCATION,
 			    &map);
@@ -554,7 +560,7 @@  dump_queued_macros (cpp_reader *pfile AT
     {
       putc ('\n', print.outf);
       print.src_line++;
-      print.printed = 0;
+      print.printed = false;
     }
 
   for (q = define_queue; q;)
@@ -563,6 +569,7 @@  dump_queued_macros (cpp_reader *pfile AT
       fputs ("#define ", print.outf);
       fputs (q->macro, print.outf);
       putc ('\n', print.outf);
+      print.printed = false;
       print.src_line++;
       oq = q;
       q = q->next;
@@ -606,6 +613,7 @@  cb_include (cpp_reader *pfile ATTRIBUTE_
     }
 
   putc ('\n', print.outf);
+  print.printed = false;
   print.src_line++;
 }
 
@@ -671,6 +679,7 @@  cb_def_pragma (cpp_reader *pfile, source
   maybe_print_line (line);
   fputs ("#pragma ", print.outf);
   cpp_output_line (pfile, print.outf);
+  print.printed = false;
   print.src_line++;
 }
 
@@ -684,6 +693,7 @@  dump_macro (cpp_reader *pfile, cpp_hashn
       fputs ((const char *) cpp_macro_definition (pfile, node),
 	     print.outf);
       putc ('\n', print.outf);
+      print.printed = false;
       print.src_line++;
     }
 
--- gcc/testsuite/c-c++-common/cpp/pr57580.c	(revision 0)
+++ gcc/testsuite/c-c++-common/cpp/pr57580.c	(revision 231213)
@@ -0,0 +1,9 @@ 
+/* PR preprocessor/57580 */
+/* { dg-do compile } */
+/* { dg-options "-save-temps" } */
+
+#define MSG 	\
+  _Pragma("message(\"message0\")")	\
+  _Pragma("message(\"message1\")")
+MSG	/* { dg-message "message0" } */
+/* { dg-message "message1" "" { target *-*-* } 8 } */
--- gcc/testsuite/c-c++-common/gomp/pr57580.c	(revision 0)
+++ gcc/testsuite/c-c++-common/gomp/pr57580.c	(revision 231213)
@@ -0,0 +1,36 @@ 
+/* PR preprocessor/57580 */
+/* { dg-do compile } */
+/* { dg-options "-fopenmp -save-temps -fdump-tree-gimple" } */
+
+#define PS \
+  _Pragma("omp parallel num_threads(2)") \
+  { \
+    _Pragma("omp single") \
+    { \
+      ret = 0; \
+    } \
+  }
+
+int
+main ()
+{
+  int ret;
+  _Pragma("omp parallel num_threads(3)")
+  {
+    _Pragma("omp single")
+    {
+      ret = 0;
+    }
+  }
+  _Pragma("omp parallel num_threads(4)") { _Pragma("omp single") { ret = 0; } }
+  { _Pragma("omp parallel num_threads(5)") { _Pragma("omp single") { ret = 0; } } }
+  PS
+  PS
+  return ret;
+}
+
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(2\\)" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(3\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(4\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp parallel\[^\n\r]*num_threads\\(5\\)" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "#pragma omp single" 5 "gimple" } } */