Fix PR91126

Message ID alpine.LSU.2.20.1907101313280.2976@zhemvz.fhfr.qr
State New
Headers show
Series
  • Fix PR91126
Related show

Commit Message

Richard Biener July 10, 2019, 11:15 a.m.
The following patch fixes an old (but now manifesting in a testsuite
fail) issue with value-numbering on big-endian machines.  I've
checked the VN results after the patch on aarch64 with -mbig-endian.

Bootstrap and regtest running on x86_64-unknown-linux-gnu.

I'll commit after this succeeded.

Richard.

2019-07-10  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/91126
	* tree-ssa-sccvn.c (n_walk_cb_data::push_partial_def): Adjust
	native encoding offset for BYTES_BIG_ENDIAN.
	(vn_reference_lookup_3): Likewise.

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

Comments

Jeff Law July 10, 2019, 2:11 p.m. | #1
On 7/10/19 5:15 AM, Richard Biener wrote:
> 

> The following patch fixes an old (but now manifesting in a testsuite

> fail) issue with value-numbering on big-endian machines.  I've

> checked the VN results after the patch on aarch64 with -mbig-endian.

> 

> Bootstrap and regtest running on x86_64-unknown-linux-gnu.

> 

> I'll commit after this succeeded.

> 

> Richard.

> 

> 2019-07-10  Richard Biener  <rguenther@suse.de>

> 

> 	PR tree-optimization/91126

> 	* tree-ssa-sccvn.c (n_walk_cb_data::push_partial_def): Adjust

> 	native encoding offset for BYTES_BIG_ENDIAN.

> 	(vn_reference_lookup_3): Likewise.

> 

> 	* gcc.dg/torture/pr91126.c: New testcase.

FWIW, the easiest big endian system to test is ppc64 as there's a
machine in the build farm.  It gets a bootstrap & regression cycle
daily.  Including the glibc & kernel build it takes ~4hrs.

My tester will also bootstrap aarch64_be, m68k and armeb, but I think
the ppc64 tester is the most effective and you can debug natively if
something goes wrong.  Debugging gcc via the qemu stub is, umm, painful.

jeff

Patch

Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c	(revision 273353)
+++ gcc/tree-ssa-sccvn.c	(working copy)
@@ -1832,10 +1832,19 @@  vn_walk_cb_data::push_partial_def (const
 			    0, MIN ((HOST_WIDE_INT)sizeof (buffer), pd.size));
 		  else
 		    {
+		      unsigned pad = 0;
+		      if (BYTES_BIG_ENDIAN)
+			{
+			  /* On big-endian the padding is at the 'front' so
+			     just skip the initial bytes.  */
+			  fixed_size_mode mode = as_a <fixed_size_mode>
+					       (TYPE_MODE (TREE_TYPE (pd.rhs)));
+			  pad = GET_MODE_SIZE (mode) - pd.size;
+			}
 		      len = native_encode_expr (pd.rhs,
 						buffer + MAX (0, pd.offset),
 						sizeof (buffer - MAX (0, pd.offset)),
-						MAX (0, -pd.offset));
+						MAX (0, -pd.offset) + pad);
 		      if (len <= 0
 			  || len < (pd.size - MAX (0, -pd.offset)))
 			{
@@ -2568,9 +2577,19 @@  vn_reference_lookup_3 (ao_ref *ref, tree
 	      tree rhs = gimple_assign_rhs1 (def_stmt);
 	      if (TREE_CODE (rhs) == SSA_NAME)
 		rhs = SSA_VAL (rhs);
+	      unsigned pad = 0;
+	      if (BYTES_BIG_ENDIAN)
+		{
+		  /* On big-endian the padding is at the 'front' so
+		     just skip the initial bytes.  */
+		  fixed_size_mode mode
+		    = as_a <fixed_size_mode> (TYPE_MODE (TREE_TYPE (rhs)));
+		  pad = GET_MODE_SIZE (mode) - size2i / BITS_PER_UNIT;
+		}
 	      len = native_encode_expr (rhs,
 					buffer, sizeof (buffer),
-					(offseti - offset2i) / BITS_PER_UNIT);
+					((offseti - offset2i) / BITS_PER_UNIT
+					 + pad));
 	      if (len > 0 && len * BITS_PER_UNIT >= maxsizei)
 		{
 		  tree type = vr->type;
Index: gcc/testsuite/gcc.dg/torture/pr91126.c
===================================================================
--- gcc/testsuite/gcc.dg/torture/pr91126.c	(revision 0)
+++ gcc/testsuite/gcc.dg/torture/pr91126.c	(working copy)
@@ -0,0 +1,28 @@ 
+/* { dg-do run } */
+
+struct S
+{
+  __INT32_TYPE__ a : 24;
+  __INT32_TYPE__ b : 8;
+} s;
+
+int
+main()
+{
+  s.a = 0xfefefe;
+  s.b = 0xfe;
+  unsigned char c;
+  c = ((unsigned char *)&s)[0];
+  if (c != 0xfe)
+    __builtin_abort ();
+  c = ((unsigned char *)&s)[1];
+  if (c != 0xfe)
+    __builtin_abort ();
+  c = ((unsigned char *)&s)[2];
+  if (c != 0xfe)
+    __builtin_abort ();
+  c = ((unsigned char *)&s)[3];
+  if (c != 0xfe)
+    __builtin_abort ();
+  return 0;
+}