Re: [PATCH] Fix couple of endianness issues in fold_ctor_reference

2023-06-30 Thread Richard Biener via Gcc-patches
On Fri, Jun 30, 2023 at 11:29 AM Eric Botcazou via Gcc-patches
 wrote:
>
> Hi,
>
> fold_ctor_reference attempts to use a recursive local processing in order to
> call native_encode_expr on the leaf nodes of the constructor, before falling
> back to calling native_encode_initializer if this fails.  There are a couple
> of issues related to endianness present in it:
>   1) it does not specifically handle integral bit-fields; now these are left
> justified on big-endian platforms so cannot be treated like ordinary fields.
>   2) it does not check that the constructor uses the native storage order.
>
> Proposed fix attached, tested on x86-64/Linux and SPARC/Solaris, OK for the
> mainline and some branches?

OK.

thanks,
Richard.

>
> 2023-06-30  Eric Botcazou  
>
> * gimple-fold.cc (fold_array_ctor_reference): Fix head comment.
> (fold_nonarray_ctor_reference): Likewise.  Specifically deal
> with integral bit-fields.
> (fold_ctor_reference): Check that the constructor uses the
> native storage order.
>
>
> 2023-06-30  Eric Botcazou  
>
> * gcc.c-torture/execute/20230630-1.c: New test.
> * gcc.c-torture/execute/20230630-2.c: Likewise.
>
> --
> Eric Botcazou


[PATCH] Fix couple of endianness issues in fold_ctor_reference

2023-06-30 Thread Eric Botcazou via Gcc-patches
Hi,

fold_ctor_reference attempts to use a recursive local processing in order to 
call native_encode_expr on the leaf nodes of the constructor, before falling 
back to calling native_encode_initializer if this fails.  There are a couple 
of issues related to endianness present in it:
  1) it does not specifically handle integral bit-fields; now these are left 
justified on big-endian platforms so cannot be treated like ordinary fields.
  2) it does not check that the constructor uses the native storage order.

Proposed fix attached, tested on x86-64/Linux and SPARC/Solaris, OK for the 
mainline and some branches?


2023-06-30  Eric Botcazou  

* gimple-fold.cc (fold_array_ctor_reference): Fix head comment.
(fold_nonarray_ctor_reference): Likewise.  Specifically deal
with integral bit-fields.
(fold_ctor_reference): Check that the constructor uses the
native storage order.


2023-06-30  Eric Botcazou  

* gcc.c-torture/execute/20230630-1.c: New test.
* gcc.c-torture/execute/20230630-2.c: Likewise.

-- 
Eric Botcazoudiff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 3d46b76edeb..e80a72dfa22 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -7849,12 +7849,11 @@ get_base_constructor (tree base, poly_int64_pod *bit_offset,
 }
 }
 
-/* CTOR is CONSTRUCTOR of an array type.  Fold a reference of SIZE bits
-   to the memory at bit OFFSET. When non-null, TYPE is the expected
-   type of the reference; otherwise the type of the referenced element
-   is used instead. When SIZE is zero, attempt to fold a reference to
-   the entire element which OFFSET refers to.  Increment *SUBOFF by
-   the bit offset of the accessed element.  */
+/* CTOR is a CONSTRUCTOR of an array or vector type.  Fold a reference of SIZE
+   bits to the memory at bit OFFSET.  If non-null, TYPE is the expected type of
+   the reference; otherwise the type of the referenced element is used instead.
+   When SIZE is zero, attempt to fold a reference to the entire element OFFSET
+   refers to.  Increment *SUBOFF by the bit offset of the accessed element.  */
 
 static tree
 fold_array_ctor_reference (tree type, tree ctor,
@@ -8019,13 +8018,11 @@ fold_array_ctor_reference (tree type, tree ctor,
   return type ? build_zero_cst (type) : NULL_TREE;
 }
 
-/* CTOR is CONSTRUCTOR of an aggregate or vector.  Fold a reference
-   of SIZE bits to the memory at bit OFFSET.   When non-null, TYPE
-   is the expected type of the reference; otherwise the type of
-   the referenced member is used instead.  When SIZE is zero,
-   attempt to fold a reference to the entire member which OFFSET
-   refers to; in this case.  Increment *SUBOFF by the bit offset
-   of the accessed member.  */
+/* CTOR is a CONSTRUCTOR of a record or union type.  Fold a reference of SIZE
+   bits to the memory at bit OFFSET.  If non-null, TYPE is the expected type of
+   the reference; otherwise the type of the referenced member is used instead.
+   When SIZE is zero, attempt to fold a reference to the entire member OFFSET
+   refers to.  Increment *SUBOFF by the bit offset of the accessed member.  */
 
 static tree
 fold_nonarray_ctor_reference (tree type, tree ctor,
@@ -8037,8 +8034,7 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
   unsigned HOST_WIDE_INT cnt;
   tree cfield, cval;
 
-  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield,
-			cval)
+  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (ctor), cnt, cfield, cval)
 {
   tree byte_offset = DECL_FIELD_OFFSET (cfield);
   tree field_offset = DECL_FIELD_BIT_OFFSET (cfield);
@@ -8110,6 +8106,19 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
 	return NULL_TREE;
 
 	  offset_int inner_offset = offset_int (offset) - bitoffset;
+
+	  /* Integral bit-fields are left-justified on big-endian targets, so
+	 we must arrange for native_encode_int to look at the MSB.  */
+  if (DECL_BIT_FIELD (cfield) && INTEGRAL_TYPE_P (TREE_TYPE (cfield)))
+	{
+	  if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
+		return NULL_TREE;
+	  const unsigned int encoding_size
+		= GET_MODE_BITSIZE (SCALAR_INT_TYPE_MODE (TREE_TYPE (cfield)));
+	  if (BYTES_BIG_ENDIAN)
+		inner_offset += encoding_size - wi::to_offset (field_size);
+	}
+
 	  return fold_ctor_reference (type, cval,
   inner_offset.to_uhwi (), size,
   from_decl, suboff);
@@ -8122,7 +8131,7 @@ fold_nonarray_ctor_reference (tree type, tree ctor,
   return build_zero_cst (type);
 }
 
-/* CTOR is value initializing memory.  Fold a reference of TYPE and
+/* CTOR is a value initializing memory.  Fold a reference of TYPE and
bit size POLY_SIZE to the memory at bit POLY_OFFSET.  When POLY_SIZE
is zero, attempt to fold a reference to the entire subobject
which OFFSET refers to.  This is used when folding accesses to
@@ -8163,7 +8172,8 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 _offset,
 	}
   return ret;