re PR tree-optimization/85834 (ice in set_ssa_val_to, at tree-ssa-sccvn.c:3396)
authorRichard Biener <rguenther@suse.de>
Tue, 22 May 2018 11:25:14 +0000 (11:25 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 22 May 2018 11:25:14 +0000 (11:25 +0000)
2018-05-22  Richard Biener  <rguenther@suse.de>

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

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/torture/pr85834.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-64.c [new file with mode: 0644]
gcc/tree-ssa-sccvn.c

index 5ef5cbae541222d40fc7ca292e2a2c17169541f8..fd57840aa4b01c7e6efa8b0b590f9a01c82a378e 100644 (file)
@@ -1,3 +1,9 @@
+2018-05-22  Richard Biener  <rguenther@suse.de>
+
+       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  <mliska@suse.cz>
 
        PR ipa/85607
index 0f109eb4a53b5e067dc76a3a2ec235f40f043e15..9083376af9e1a38dd48533d4e0793f2b745dce3b 100644 (file)
@@ -1,3 +1,9 @@
+2018-05-22  Richard Biener  <rguenther@suse.de>
+
+       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  <mliska@suse.cz>
 
        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 (file)
index 0000000..bbdc695
--- /dev/null
@@ -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 <int, typename> class f {
+public:
+    template <typename g> f(g);
+};
+typedef f<1, long> h;
+template <typename> struct j {
+    enum k {};
+};
+class l {
+public:
+    typedef j<l>::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 (file)
index 0000000..15f278e
--- /dev/null
@@ -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" } } */
index 39de866a8ce7a17a7df43f423bae82c376e8c140..884cce12bb36e95e66163ccb86f3b1efe6a1cba9 100644 (file)
@@ -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);
        }