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.

Reply via email to