tree-optimization/107617 - big-endian .LEN_STORE VN

Message ID 20221214074848.39A3238358AD@sourceware.org
State Repeat Merge
Headers
Series tree-optimization/107617 - big-endian .LEN_STORE VN |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Richard Biener Dec. 14, 2022, 7:48 a.m. UTC
  The following fixes a mistake in interpreting .LEN_STORE definitions
during value-numbering when in big-endian mode.  We cannot offset
the encoding of the RHS but instead encode to an offsetted position
which is then treated correctly by the endian aware copying code.

Bootstrapped and tested on x86_64-unkown-linux-gnu and on s390
by Robin, pushed.

	PR tree-optimization/107617
	* tree-ssa-sccvn.cc (vn_walk_cb_data::push_partial_def):
	Handle negative pd.rhs_off.
	(vn_reference_lookup_3): Properly provide pd.rhs_off
	for .LEN_STORE on big-endian targets.
---
 gcc/tree-ssa-sccvn.cc | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)
  

Patch

diff --git a/gcc/tree-ssa-sccvn.cc b/gcc/tree-ssa-sccvn.cc
index b9f289b6eca..fa2f65df159 100644
--- a/gcc/tree-ssa-sccvn.cc
+++ b/gcc/tree-ssa-sccvn.cc
@@ -2090,7 +2090,7 @@  vn_walk_cb_data::push_partial_def (pd_data pd,
 	    len = ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT;
 	  memset (this_buffer, 0, len);
 	}
-      else
+      else if (pd.rhs_off >= 0)
 	{
 	  len = native_encode_expr (pd.rhs, this_buffer, bufsize,
 				    (MAX (0, -pd.offset)
@@ -2105,6 +2105,24 @@  vn_walk_cb_data::push_partial_def (pd_data pd,
 	      return (void *)-1;
 	    }
 	}
+      else /* negative pd.rhs_off indicates we want to chop off first bits */
+	{
+	  if (-pd.rhs_off >= bufsize)
+	    return (void *)-1;
+	  len = native_encode_expr (pd.rhs,
+				    this_buffer + -pd.rhs_off / BITS_PER_UNIT,
+				    bufsize - -pd.rhs_off / BITS_PER_UNIT,
+				    MAX (0, -pd.offset) / BITS_PER_UNIT);
+	  if (len <= 0
+	      || len < (ROUND_UP (pd.size, BITS_PER_UNIT) / BITS_PER_UNIT
+			- MAX (0, -pd.offset) / BITS_PER_UNIT))
+	    {
+	      if (dump_file && (dump_flags & TDF_DETAILS))
+		fprintf (dump_file, "Failed to encode %u "
+			 "partial definitions\n", ndefs);
+	      return (void *)-1;
+	    }
+	}
 
       unsigned char *p = buffer;
       HOST_WIDE_INT size = pd.size;
@@ -3349,10 +3367,13 @@  vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *data_,
 		}
 	      else if (fn == IFN_LEN_STORE)
 		{
-		  pd.rhs_off = 0;
 		  pd.offset = offset2i;
 		  pd.size = (tree_to_uhwi (len)
 			     + -tree_to_shwi (bias)) * BITS_PER_UNIT;
+		  if (BYTES_BIG_ENDIAN)
+		    pd.rhs_off = pd.size - tree_to_uhwi (TYPE_SIZE (vectype));
+		  else
+		    pd.rhs_off = 0;
 		  if (ranges_known_overlap_p (offset, maxsize,
 					      pd.offset, pd.size))
 		    return data->push_partial_def (pd, set, set,