diff mbox

GCC 5 backports

Message ID alpine.LSU.2.11.1605231420080.18037@t29.fhfr.qr
State New
Headers show

Commit Message

Richard Biener May 23, 2016, 12:20 p.m. UTC
A few more.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2016-05-23  Richard Biener  <rguenther@suse.de>

	Backport from mainline
	2016-02-11  Alexandre Oliva  <aoliva@redhat.com>

	PR target/69634
	* regstat.c (regstat_bb_compute_calls_crossed): Disregard
	debug insns.

	* gcc.dg/pr69634.c: New.

	2016-03-23  Patrick Palka  <ppalka@gcc.gnu.org>
 
	PR c++/70347
	* typeck.c (process_init_constructor_union): If the initializer
	is empty, use the union's NSDMI if it has one.
 
	* g++.dg/cpp1y/nsdmi-union1.C: New test.

	2015-10-30  Richard Biener  <rguenther@suse.de>

	PR middle-end/68142
	* fold-const.c (extract_muldiv_1): Avoid introducing undefined
	overflow.

	* c-c++-common/ubsan/pr68142.c: New testcase.

	2016-03-24  Richard Henderson  <rth@redhat.com>

        PR middle-end/69845
	* fold-const.c (extract_muldiv_1): Correct test for multiplication
	overflow.

	* gcc.dg/tree-ssa/pr69845-1.c: New test.
	* gcc.dg/tree-ssa/pr69845-2.c: New test.


Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 229517)
--- gcc/fold-const.c	(working copy)
*************** extract_muldiv_1 (tree t, tree c, enum t
*** 6008,6015 ****
  	 or (for divide and modulus) if it is a multiple of our constant.  */
        if (code == MULT_EXPR
  	  || wi::multiple_of_p (t, c, TYPE_SIGN (type)))
! 	return const_binop (code, fold_convert (ctype, t),
! 			    fold_convert (ctype, c));
        break;
  
      CASE_CONVERT: case NON_LVALUE_EXPR:
--- 6015,6031 ----
  	 or (for divide and modulus) if it is a multiple of our constant.  */
        if (code == MULT_EXPR
  	  || wi::multiple_of_p (t, c, TYPE_SIGN (type)))
! 	{
! 	  tree tem = const_binop (code, fold_convert (ctype, t),
! 				  fold_convert (ctype, c));
! 	  /* If the multiplication overflowed to INT_MIN then we lost sign
! 	     information on it and a subsequent multiplication might
! 	     spuriously overflow.  See PR68142.  */
! 	  if (TREE_OVERFLOW (tem)
! 	      && wi::eq_p (tem, wi::min_value (TYPE_PRECISION (ctype), SIGNED)))
! 	    return NULL_TREE;
! 	  return tem;
! 	}
        break;
  
      CASE_CONVERT: case NON_LVALUE_EXPR:
Index: gcc/testsuite/c-c++-common/ubsan/pr68142.c
===================================================================
*** gcc/testsuite/c-c++-common/ubsan/pr68142.c	(revision 0)
--- gcc/testsuite/c-c++-common/ubsan/pr68142.c	(working copy)
***************
*** 0 ****
--- 1,31 ----
+ /* { dg-do run } */
+ /* { dg-options "-fsanitize=undefined -fsanitize-undefined-trap-on-error" } */
+ 
+ int __attribute__((noinline,noclone))
+ h(int a)
+ {
+   return 2 * (a * (__INT_MAX__/2 + 1));
+ }
+ int __attribute__((noinline,noclone))
+ i(int a)
+ {
+   return (2 * a) * (__INT_MAX__/2 + 1);
+ }
+ int __attribute__((noinline,noclone))
+ j(int a, int b)
+ {
+   return (b * a) * (__INT_MAX__/2 + 1);
+ }
+ int __attribute__((noinline,noclone))
+ k(int a, int b)
+ {
+   return (2 * a) * b;
+ }
+ int main()
+ {
+   volatile int tem = h(-1);
+   tem = i(-1);
+   tem = j(-1, 2);
+   tem = k(-1, __INT_MAX__/2 + 1);
+   return 0;
+ }
diff mbox

Patch

Index: gcc/regstat.c
===================================================================
--- gcc/regstat.c	(revision 233249)
+++ gcc/regstat.c	(revision 233250)
@@ -444,7 +444,7 @@  regstat_bb_compute_calls_crossed (unsign
       struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
       unsigned int regno;
 
-      if (!INSN_P (insn))
+      if (!NONDEBUG_INSN_P (insn))
 	continue;
 
       /* Process the defs.  */
Index: gcc/testsuite/gcc.dg/pr69634.c
===================================================================
--- gcc/testsuite/gcc.dg/pr69634.c	(revision 0)
+++ gcc/testsuite/gcc.dg/pr69634.c	(revision 233250)
@@ -0,0 +1,21 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-dce -fschedule-insns -fno-tree-vrp -fcompare-debug" } */
+/* { dg-additional-options "-Wno-psabi -mno-sse" { target i?86-*-* x86_64-*-* } } */
+
+typedef unsigned short u16;
+typedef short v16u16 __attribute__ ((vector_size (16)));
+typedef unsigned v16u32 __attribute__ ((vector_size (16)));
+typedef unsigned long long v16u64 __attribute__ ((vector_size (16)));
+
+u16
+foo(u16 u16_1, v16u16 v16u16_0, v16u32 v16u64_0, v16u16 v16u16_1, v16u32 v16u32_1, v16u64 v16u64_1)
+{
+  v16u64_1 /= (v16u64){~v16u32_1[1]};
+  u16_1 = 0;
+  u16_1 /= v16u32_1[2];
+  v16u64_1 -= (v16u64) v16u16_1;
+  u16_1 >>= 1;
+  u16_1 -= ~0;
+  v16u16_1 /= (v16u16){~u16_1, 1 - v16u64_0[0], 0xffb6};
+  return u16_1 + v16u16_0[1] + v16u16_1[3] + v16u64_1[0] + v16u64_1[1];
+}
Index: gcc/testsuite/g++.dg/cpp1y/nsdmi-union1.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/nsdmi-union1.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/nsdmi-union1.C	(revision 234443)
@@ -0,0 +1,33 @@ 
+// PR c++/70347
+// { dg-do run { target c++14 } }
+
+union A {
+  char a;
+  long b = -42;
+};
+
+struct B {
+  union {
+    char a = 10;
+    long b;
+  };
+};
+
+A c1{};
+A c2{4};
+B c3{};
+B c4{{9}};
+
+int main() {
+  if (c1.b != -42)
+    __builtin_abort ();
+
+  if (c2.a != 4)
+    __builtin_abort ();
+
+  if (c3.a != 10)
+    __builtin_abort ();
+
+  if (c4.a != 9)
+    __builtin_abort ();
+}
Index: gcc/cp/typeck2.c
===================================================================
--- gcc/cp/typeck2.c	(revision 234442)
+++ gcc/cp/typeck2.c	(revision 234443)
@@ -1499,9 +1499,24 @@  process_init_constructor_union (tree typ
   constructor_elt *ce;
   int len;
 
-  /* If the initializer was empty, use default zero initialization.  */
+  /* If the initializer was empty, use the union's NSDMI if it has one.
+     Otherwise use default zero initialization.  */
   if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
-    return 0;
+    {
+      for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
+	{
+	  if (DECL_INITIAL (field))
+	    {
+	      CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (init),
+				      field,
+				      get_nsdmi (field, /*in_ctor=*/false));
+	      break;
+	    }
+	}
+
+      if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
+	return 0;
+    }
 
   len = CONSTRUCTOR_ELTS (init)->length ();
   if (len > 1)
Index: gcc/fold-const.c
===================================================================
--- gcc/fold-const.c	(revision 234461)
+++ gcc/fold-const.c	(revision 234462)
@@ -6116,11 +6116,9 @@  extract_muldiv_1 (tree t, tree c, enum t
 	{
 	  tree tem = const_binop (code, fold_convert (ctype, t),
 				  fold_convert (ctype, c));
-	  /* If the multiplication overflowed to INT_MIN then we lost sign
-	     information on it and a subsequent multiplication might
-	     spuriously overflow.  See PR68142.  */
-	  if (TREE_OVERFLOW (tem)
-	      && wi::eq_p (tem, wi::min_value (TYPE_PRECISION (ctype), SIGNED)))
+	  /* If the multiplication overflowed, we lost information on it.
+	     See PR68142 and PR69845.  */
+	  if (TREE_OVERFLOW (tem))
 	    return NULL_TREE;
 	  return tem;
 	}
Index: gcc/testsuite/gcc.dg/tree-ssa/pr69845-1.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr69845-1.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr69845-1.c	(revision 234462)
@@ -0,0 +1,19 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target int32 } */
+/* { dg-options "-O -fdump-tree-gimple -fdump-tree-optimized" } */
+
+int
+main ()
+{
+  struct S { char s; } v;
+  v.s = 47;
+  int a = (int) v.s;
+  int b = (27005061 + (a + 680455));
+  int c = ((1207142401 * (((8 * b) + 9483541) - 230968044)) + 469069442);
+  if (c != 1676211843)
+    __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "b \\\* 8" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/pr69845-2.c
===================================================================
--- gcc/testsuite/gcc.dg/tree-ssa/pr69845-2.c	(revision 0)
+++ gcc/testsuite/gcc.dg/tree-ssa/pr69845-2.c	(revision 234462)
@@ -0,0 +1,20 @@ 
+/* { dg-do compile } */
+/* { dg-require-effective-target int32 } */
+/* { dg-options "-O -fdump-tree-gimple -fdump-tree-optimized" } */
+
+int
+main ()
+{
+  struct S { char s; } v;
+  v.s = 47;
+  unsigned int a = (unsigned int) v.s;
+  unsigned int b = (27005061 + (a + 680455));
+  unsigned int c
+    = ((1207142401u * (((8u * b) + 9483541u) - 230968044u)) + 469069442u);
+  if (c != 1676211843u)
+    __builtin_abort ();
+  return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "b \\\* 1067204616" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */