A few more. Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.
Richard. 2016-05-23 Richard Biener <rguent...@suse.de> Backport from mainline 2016-02-11 Alexandre Oliva <aol...@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 <ppa...@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 <rguent...@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 <r...@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; + } 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" } } */