aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/avoid-store-forwarding.cc18
-rw-r--r--gcc/testsuite/gcc.target/aarch64/avoid-store-forwarding-be.c23
2 files changed, 28 insertions, 13 deletions
diff --git a/gcc/avoid-store-forwarding.cc b/gcc/avoid-store-forwarding.cc
index 37e0953..785efd2 100644
--- a/gcc/avoid-store-forwarding.cc
+++ b/gcc/avoid-store-forwarding.cc
@@ -119,17 +119,6 @@ generate_bit_insert_sequence (store_fwd_info *store_info, rtx dest)
unsigned HOST_WIDE_INT bitsize = store_size * BITS_PER_UNIT;
unsigned HOST_WIDE_INT start = store_info->offset * BITS_PER_UNIT;
- /* Adjust START for machines with BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN.
- Given that the bytes will be reversed in this case, we need to
- calculate the starting position from the end of the destination
- register. */
- if (BITS_BIG_ENDIAN != BYTES_BIG_ENDIAN)
- {
- unsigned HOST_WIDE_INT load_mode_bitsize
- = (GET_MODE_BITSIZE (GET_MODE (dest))).to_constant ();
- start = load_mode_bitsize - bitsize - start;
- }
-
rtx mov_reg = store_info->mov_reg;
store_bit_field (dest, bitsize, start, 0, 0, GET_MODE (mov_reg), mov_reg,
false, false);
@@ -248,11 +237,14 @@ process_store_forwarding (vec<store_fwd_info> &stores, rtx_insn *load_insn,
{
it->mov_reg = gen_reg_rtx (GET_MODE (it->store_mem));
rtx_insn *insns = NULL;
- const bool has_zero_offset = it->offset == 0;
+ const bool has_base_offset
+ = known_eq (poly_uint64 (it->offset),
+ subreg_size_lowpart_offset (MEM_SIZE (it->store_mem),
+ load_size));
/* If we're eliminating the load then find the store with zero offset
and use it as the base register to avoid a bit insert if possible. */
- if (load_elim && has_zero_offset)
+ if (load_elim && has_base_offset)
{
start_sequence ();
diff --git a/gcc/testsuite/gcc.target/aarch64/avoid-store-forwarding-be.c b/gcc/testsuite/gcc.target/aarch64/avoid-store-forwarding-be.c
new file mode 100644
index 0000000..2e8946b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/avoid-store-forwarding-be.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-require-effective-target aarch64_big_endian } */
+/* { dg-options "-O2 -favoid-store-forwarding" } */
+
+typedef union {
+ char arr[2];
+ short value;
+} DataUnion;
+
+short __attribute__ ((noinline))
+ssll (DataUnion *data, char x, char y)
+{
+ data->arr[0] = x;
+ data->arr[1] = y;
+ return data->value;
+}
+
+int main () {
+ DataUnion data = {};
+ short value = ssll (&data, 0, 1);
+ if (value != 1)
+ __builtin_abort ();
+} \ No newline at end of file