From: Richard Biener Date: Tue, 22 May 2018 11:25:14 +0000 (+0000) Subject: re PR tree-optimization/85834 (ice in set_ssa_val_to, at tree-ssa-sccvn.c:3396) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=81d5198d0093ab144c8a13b85c56ef496192f930;p=gcc.git re PR tree-optimization/85834 (ice in set_ssa_val_to, at tree-ssa-sccvn.c:3396) 2018-05-22 Richard Biener PR tree-optimization/85834 * tree-ssa-sccvn.c (vn_reference_lookup_3): Properly handle non-constant and non-zero memset arguments. * g++.dg/torture/pr85834.C: New testcase. * gcc.dg/tree-ssa/ssa-fre-64.c: Likewise. From-SVN: r260503 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ef5cbae541..fd57840aa4b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-05-22 Richard Biener + + PR tree-optimization/85834 + * tree-ssa-sccvn.c (vn_reference_lookup_3): Properly handle + non-constant and non-zero memset arguments. + 2018-05-22 Martin Liska PR ipa/85607 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0f109eb4a53..9083376af9e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-05-22 Richard Biener + + PR tree-optimization/85834 + * g++.dg/torture/pr85834.C: New testcase. + * gcc.dg/tree-ssa/ssa-fre-64.c: Likewise. + 2018-05-22 Martin Liska PR ipa/85607 diff --git a/gcc/testsuite/g++.dg/torture/pr85834.C b/gcc/testsuite/g++.dg/torture/pr85834.C new file mode 100644 index 00000000000..bbdc695849c --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr85834.C @@ -0,0 +1,38 @@ +/* { dg-do compile } */ + +typedef __SIZE_TYPE__ a; +extern "C" void *memset(void *, int, a); +typedef struct b c; +enum d { e }; +template class f { +public: + template f(g); +}; +typedef f<1, long> h; +template struct j { + enum k {}; +}; +class l { +public: + typedef j::k k; + l(k); + operator d(); +}; +struct b {}; +class m {}; +c q(h, d); +c n(unsigned char o[]) { + int i; + long r; + for (i = 0; i < 4; i++) + r = o[i]; + return q(r, l((l::k)e)); +} +m p() { + unsigned char o[4], s = 1; + for (;;) { + memset(o, s, 4); + n(o); + s = 2; + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-64.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-64.c new file mode 100644 index 00000000000..15f278e1945 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-64.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-fre1-details -fdump-tree-dse1-details" } */ + +int foo(unsigned char c, signed char d, int e) +{ + int res = 0; + char x[256]; + __builtin_memset (x, c, 256); + res += x[54]; + __builtin_memset (x, d, 256); + res += x[54]; + __builtin_memset (x, e, 256); + res += x[54]; + return res; +} + +/* The loads get replaced with conversions from c or d and e. */ +/* { dg-final { scan-tree-dump-times "Inserted" 2 "fre1" } } */ +/* { dg-final { scan-tree-dump-times "Replaced x" 3 "fre1" } } */ +/* And the memsets removed as dead. */ +/* { dg-final { scan-tree-dump-times "Deleted dead call" 3 "dse1" } } */ diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 39de866a8ce..884cce12bb3 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -1959,7 +1959,12 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, if (is_gimple_reg_type (vr->type) && gimple_call_builtin_p (def_stmt, BUILT_IN_MEMSET) && (integer_zerop (gimple_call_arg (def_stmt, 1)) - || (INTEGRAL_TYPE_P (vr->type) && known_eq (ref->size, 8))) + || (INTEGRAL_TYPE_P (vr->type) + && CHAR_BIT == 8 && BITS_PER_UNIT == 8 + && known_eq (ref->size, 8) + && known_eq (ref->size, maxsize) + && offset.is_constant (&offseti) + && offseti % BITS_PER_UNIT == 0)) && poly_int_tree_p (gimple_call_arg (def_stmt, 2)) && (TREE_CODE (gimple_call_arg (def_stmt, 0)) == ADDR_EXPR || TREE_CODE (gimple_call_arg (def_stmt, 0)) == SSA_NAME)) @@ -2026,7 +2031,16 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_, if (integer_zerop (gimple_call_arg (def_stmt, 1))) val = build_zero_cst (vr->type); else - val = fold_convert (vr->type, gimple_call_arg (def_stmt, 1)); + { + code_helper rcode = NOP_EXPR; + tree ops[3] = {}; + ops[0] = gimple_call_arg (def_stmt, 1); + val = vn_nary_build_or_lookup (rcode, vr->type, ops); + if (!val + || (TREE_CODE (val) == SSA_NAME + && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val))) + return (void *)-1; + } return vn_reference_lookup_or_insert_for_pieces (vuse, vr->set, vr->type, vr->operands, val); }