+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
+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
--- /dev/null
+/* { 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;
+ }
+}
--- /dev/null
+/* { 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" } } */
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))
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);
}