[PATCH] Fix PR88223

Richard Biener rguenther@suse.de
Wed Nov 28 13:50:00 GMT 2018


The following fixes VN looking across stores that store the same value
as we'd CSE to.  This didn't properly handle the case of partial
overlaps which can at least happen when TBAA doesn't apply.

The PR notes some additional questions around unions for which I
didn't find authorative answers in the standard and thus which
are still "broken".

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

Richard.

>From 199079636fe8352be631c462650a2387c5254dbe Mon Sep 17 00:00:00 2001
From: Richard Guenther <rguenther@suse.de>
Date: Wed, 28 Nov 2018 10:21:02 +0100
Subject: [PATCH] fix-pr88223

	PR tree-optimization/88223
	* tree-ssa-sccvn.c (vn_reference_lookup_3): When skipping
	over a stored-same value may-alias store make sure to consider
	partial overlaps which are valid when TBAA reasonings do not
	apply and byte-granular overlaps are possible at all.

	* gcc.dg/torture/pr88223.c: New testcase.

diff --git a/gcc/testsuite/gcc.dg/torture/pr88223.c b/gcc/testsuite/gcc.dg/torture/pr88223.c
new file mode 100644
index 00000000000..37df1cd6b74
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr88223.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+extern void *memmove(void *, const void *, __SIZE_TYPE__);
+extern void abort(void);
+
+extern int
+main(void)
+{
+ char s[] = "12345";
+ memmove(s + 1, s, 4);
+ memmove(s + 1, s, 4);
+ memmove(s + 1, s, 4);
+ if (s[0] != '1' || s[1] != '1' || s[2] != '1' || s[3] != '1' || s[4] != '2')
+   abort ();
+ return (0);
+}
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index b0b9d5221f4..8f2b4608b5c 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1927,7 +1927,16 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
 	 VN_WALKREWRITE guard).  */
       if (vn_walk_kind == VN_WALKREWRITE
 	  && is_gimple_reg_type (TREE_TYPE (lhs))
-	  && types_compatible_p (TREE_TYPE (lhs), vr->type))
+	  && types_compatible_p (TREE_TYPE (lhs), vr->type)
+	  /* The overlap restriction breaks down when either access
+	     alias-set is zero.  Still for accesses of the size of
+	     an addressable unit there can be no overlaps.  Overlaps
+	     between different union members are not an issue since
+	     activation of a union member via a store makes the
+	     values of untouched bytes unspecified.  */
+	  && (known_eq (ref->size, BITS_PER_UNIT)
+	      || (get_alias_set (lhs) != 0
+		  && ao_ref_alias_set (ref) != 0)))
 	{
 	  tree *saved_last_vuse_ptr = last_vuse_ptr;
 	  /* Do not update last_vuse_ptr in vn_reference_lookup_2.  */



More information about the Gcc-patches mailing list