public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] Fix PR85834
@ 2018-05-22 11:43 Richard Biener
  2018-05-23  8:56 ` Eric Botcazou
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Biener @ 2018-05-22 11:43 UTC (permalink / raw)
  To: gcc-patches; +Cc: ebotcazou


I originally forgot to restrict memset args to constants - instead of
adding that check the following properly fixes non-constant handling.

I'm not quite sure that ao_ref with offset % 8 == 0 but size != maxsize
has any guarantee that all accesses that this covers are aligned to 8
bits but I failed to create a testcase with a variable bit-alignment.
But I'm quite sure Ada can do that, right?  There may be existing code
that assumes that if offset is byte-aligned all covered accesses are.

Eric?

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

This should restore -O3 bootstrap.

Richard.

From 07481b3c924f095e7330337649172b6c237d2e09 Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Tue, 22 May 2018 10:36:13 +0200
Subject: [PATCH 2/2] fix-pr85834

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.

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 <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
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);
 	}
-- 
2.12.3

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Fix PR85834
  2018-05-22 11:43 [PATCH] Fix PR85834 Richard Biener
@ 2018-05-23  8:56 ` Eric Botcazou
  2018-05-23  9:01   ` Richard Biener
  0 siblings, 1 reply; 3+ messages in thread
From: Eric Botcazou @ 2018-05-23  8:56 UTC (permalink / raw)
  To: Richard Biener; +Cc: gcc-patches

> I'm not quite sure that ao_ref with offset % 8 == 0 but size != maxsize
> has any guarantee that all accesses that this covers are aligned to 8
> bits but I failed to create a testcase with a variable bit-alignment.
> But I'm quite sure Ada can do that, right?  There may be existing code
> that assumes that if offset is byte-aligned all covered accesses are.

The middle-end assumes that variable offsets are always byte-aligned, see 
DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.  Does that answer the above?

-- 
Eric Botcazou

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] Fix PR85834
  2018-05-23  8:56 ` Eric Botcazou
@ 2018-05-23  9:01   ` Richard Biener
  0 siblings, 0 replies; 3+ messages in thread
From: Richard Biener @ 2018-05-23  9:01 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches

On Wed, 23 May 2018, Eric Botcazou wrote:

> > I'm not quite sure that ao_ref with offset % 8 == 0 but size != maxsize
> > has any guarantee that all accesses that this covers are aligned to 8
> > bits but I failed to create a testcase with a variable bit-alignment.
> > But I'm quite sure Ada can do that, right?  There may be existing code
> > that assumes that if offset is byte-aligned all covered accesses are.
> 
> The middle-end assumes that variable offsets are always byte-aligned, see 
> DECL_FIELD_OFFSET and DECL_FIELD_BIT_OFFSET.  Does that answer the above?

Ah, yes.

Thanks,
Richard.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-05-23  8:56 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-22 11:43 [PATCH] Fix PR85834 Richard Biener
2018-05-23  8:56 ` Eric Botcazou
2018-05-23  9:01   ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).