https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88739
--- Comment #8 from Richard Biener <rguenth at gcc dot gnu.org> ---
So I think part of a fix would be the following. Not sure if
REG_WORDS_BIG_ENDIAN or FLOAT_WORDS_BIG_ENDIAN come into play.
With the fix we no longer simplify this for aarch64 since
BITS_BIG_ENDIAN is 0 even in BE mode.
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c (revision 267553)
+++ gcc/tree-ssa-sccvn.c (working copy)
@@ -2229,13 +2229,18 @@ vn_reference_lookup_3 (ao_ref *ref, tree
according to endianness. */
&& (! INTEGRAL_TYPE_P (vr->type)
|| known_eq (ref->size, TYPE_PRECISION (vr->type)))
- && multiple_p (ref->size, BITS_PER_UNIT))
+ && multiple_p (ref->size, BITS_PER_UNIT)
+ && BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
+ && BITS_BIG_ENDIAN == BYTES_BIG_ENDIAN)
{
gimple_match_op op (gimple_match_cond::UNCOND,
BIT_FIELD_REF, vr->type,
vn_valueize (gimple_assign_rhs1 (def_stmt)),
bitsize_int (ref->size),
- bitsize_int (offset - offset2));
+ bitsize_int
+ (BYTES_BIG_ENDIAN
+ ? size2 - (offset - offset2) - ref->size
+ : offset - offset2));
tree val = vn_nary_build_or_lookup (&op);
if (val
&& (TREE_CODE (val) != SSA_NAME
In case both sizes/offsets
are mutliples of BITS_PER_UNIT BITS_BIG_ENDIAN shouldn't matter
though (likewise if size2 < WORD_SIZE). So a less conservative check
might be
&& (known_le (size2, BITS_PER_WORD)
|| BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN)
&& (BITS_BIG_ENDIAN == BYTES_BIG_ENDIAN
|| (multiple_p (offset2, BITS_PER_UNIT)
&& multiple_p (offset, BITS_PER_UNIT)
&& (!BYTES_BIG_ENDIAN
|| multiple_p (size2, BITS_PER_UNIT)))))
but I guess we lack exhaustive testing (and a list of targets that cover
all combinations of endianesses).
That is, not sure if BIT_FIELD_REF <_2, 16, 14> would be correct as suggested
for aarch64_be because of that BITS_BIG_ENDIAN setting.