public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-2224] Fix couple of endianness issues in fold_ctor_reference
@ 2023-06-30 16:14 Eric Botcazou
0 siblings, 0 replies; only message in thread
From: Eric Botcazou @ 2023-06-30 16:14 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:db5d70632a6cb59521e41df7745cacb08d00a3f4
commit r14-2224-gdb5d70632a6cb59521e41df7745cacb08d00a3f4
Author: Eric Botcazou <ebotcazou@adacore.com>
Date: Fri Jun 30 18:05:34 2023 +0200
Fix couple of endianness issues in fold_ctor_reference
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.
gcc/
* gimple-fold.cc (fold_array_ctor_reference): Fix head comment.
(fold_nonarray_ctor_reference): Likewise. Specifically deal
with integral bit-fields.
(fold_ctor_reference): Make sure that the constructor uses the
native storage order.
gcc/testsuite/
* gcc.c-torture/execute/20230630-1.c: New test.
* gcc.c-torture/execute/20230630-2.c: Likewise.
* gcc.c-torture/execute/20230630-3.c: Likewise
* gcc.c-torture/execute/20230630-4.c: Likewise
Diff:
---
gcc/gimple-fold.cc | 57 +++++++++++++++---------
gcc/testsuite/gcc.c-torture/execute/20230630-1.c | 23 ++++++++++
gcc/testsuite/gcc.c-torture/execute/20230630-2.c | 29 ++++++++++++
gcc/testsuite/gcc.c-torture/execute/20230630-3.c | 27 +++++++++++
gcc/testsuite/gcc.c-torture/execute/20230630-4.c | 33 ++++++++++++++
5 files changed, 148 insertions(+), 21 deletions(-)
diff --git a/gcc/gimple-fold.cc b/gcc/gimple-fold.cc
index 6d167b116b9..8434274f69d 100644
--- a/gcc/gimple-fold.cc
+++ b/gcc/gimple-fold.cc
@@ -7851,12 +7851,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,
@@ -8021,13 +8020,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,
@@ -8039,8 +8036,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);
@@ -8112,6 +8108,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 start at their 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);
@@ -8124,7 +8133,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
@@ -8165,7 +8174,8 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
}
return ret;
}
- /* For constants and byte-aligned/sized reads try to go through
+
+ /* For constants and byte-aligned/sized reads, try to go through
native_encode/interpret. */
if (CONSTANT_CLASS_P (ctor)
&& BITS_PER_UNIT == 8
@@ -8181,7 +8191,12 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
if (len > 0)
return native_interpret_expr (type, buf, len);
}
- if (TREE_CODE (ctor) == CONSTRUCTOR)
+
+ /* For constructors, try first a recursive local processing, but in any case
+ this requires the native storage order. */
+ if (TREE_CODE (ctor) == CONSTRUCTOR
+ && !(AGGREGATE_TYPE_P (TREE_TYPE (ctor))
+ && TYPE_REVERSE_STORAGE_ORDER (TREE_TYPE (ctor))))
{
unsigned HOST_WIDE_INT dummy = 0;
if (!suboff)
@@ -8196,9 +8211,9 @@ fold_ctor_reference (tree type, tree ctor, const poly_uint64 &poly_offset,
ret = fold_nonarray_ctor_reference (type, ctor, offset, size,
from_decl, suboff);
- /* Fall back to native_encode_initializer. Needs to be done
- only in the outermost fold_ctor_reference call (because it itself
- recurses into CONSTRUCTORs) and doesn't update suboff. */
+ /* Otherwise fall back to native_encode_initializer. This may be done
+ only from the outermost fold_ctor_reference call (because it itself
+ recurses into CONSTRUCTORs and doesn't update suboff). */
if (ret == NULL_TREE
&& suboff == &dummy
&& BITS_PER_UNIT == 8
diff --git a/gcc/testsuite/gcc.c-torture/execute/20230630-1.c b/gcc/testsuite/gcc.c-torture/execute/20230630-1.c
new file mode 100644
index 00000000000..7c1f15c177f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20230630-1.c
@@ -0,0 +1,23 @@
+struct S {
+ short int i : 12;
+ char c1 : 1;
+ char c2 : 1;
+ char c3 : 1;
+ char c4 : 1;
+};
+
+int main (void)
+{
+ struct S s0 = { 341, 1, 1, 1, 1 };
+ char *p = (char *) &s0;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ if (*p != 85)
+ __builtin_abort ();
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ if (*p != 21)
+ __builtin_abort ();
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20230630-2.c b/gcc/testsuite/gcc.c-torture/execute/20230630-2.c
new file mode 100644
index 00000000000..c05c1666516
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20230630-2.c
@@ -0,0 +1,29 @@
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define REVERSE_SSO __attribute__((scalar_storage_order("big-endian")));
+#else
+#define REVERSE_SSO __attribute__((scalar_storage_order("little-endian")));
+#endif
+
+struct S {
+ short int i : 12;
+ char c1 : 1;
+ char c2 : 1;
+ char c3 : 1;
+ char c4 : 1;
+} REVERSE_SSO;
+
+int main (void)
+{
+ struct S s0 = { 341, 1, 1, 1, 1 };
+ char *p = (char *) &s0;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ if (*p != 21)
+ __builtin_abort ();
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ if (*p != 85)
+ __builtin_abort ();
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20230630-3.c b/gcc/testsuite/gcc.c-torture/execute/20230630-3.c
new file mode 100644
index 00000000000..fc106c97b5b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20230630-3.c
@@ -0,0 +1,27 @@
+struct S {
+ int i : 24;
+ char c1 : 1;
+ char c2 : 1;
+ char c3 : 1;
+ char c4 : 1;
+ char c5 : 1;
+ char c6 : 1;
+ char c7 : 1;
+ char c8 : 1;
+};
+
+int main (void)
+{
+ struct S s0 = { 1193046, 1, 1, 1, 1, 1, 1, 1, 1 };
+ char *p = (char *) &s0;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ if (*p != 86)
+ __builtin_abort ();
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ if (*p != 18)
+ __builtin_abort ();
+#endif
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20230630-4.c b/gcc/testsuite/gcc.c-torture/execute/20230630-4.c
new file mode 100644
index 00000000000..df33c18a8cd
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20230630-4.c
@@ -0,0 +1,33 @@
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#define REVERSE_SSO __attribute__((scalar_storage_order("big-endian")));
+#else
+#define REVERSE_SSO __attribute__((scalar_storage_order("little-endian")));
+#endif
+
+struct S {
+ int i : 24;
+ char c1 : 1;
+ char c2 : 1;
+ char c3 : 1;
+ char c4 : 1;
+ char c5 : 1;
+ char c6 : 1;
+ char c7 : 1;
+ char c8 : 1;
+} REVERSE_SSO;
+
+int main (void)
+{
+ struct S s0 = { 1193046, 1, 1, 1, 1, 1, 1, 1, 1 };
+ char *p = (char *) &s0;
+
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ if (*p != 18)
+ __builtin_abort ();
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ if (*p != 86)
+ __builtin_abort ();
+#endif
+
+ return 0;
+}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2023-06-30 16:14 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-30 16:14 [gcc r14-2224] Fix couple of endianness issues in fold_ctor_reference Eric Botcazou
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).