summaryrefslogtreecommitdiff
path: root/gcc/gimple-ssa-store-merging.c
diff options
context:
space:
mode:
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-02-28 22:39:11 +0000
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>2017-02-28 22:39:11 +0000
commita425d9aff519672639ebcc6f27d674bbc9b91cf9 (patch)
treeff4ffb92de5c47b0d5e963ed565075997888b190 /gcc/gimple-ssa-store-merging.c
parent9ee6024bcc5ecead901a58523fc30dc97cebdfce (diff)
downloadgcc-a425d9aff519672639ebcc6f27d674bbc9b91cf9.tar.gz
PR tree-optimization/79737
* gimple-ssa-store-merging.c (encode_tree_to_bitpos): If bitlen is a multiple of BITS_PER_UNIT and !BYTES_BIG_ENDIAN, clear tmpbuf[byte_size - 1]. Call natice_encode_expr with byte_size - 1 instead of byte_size. Formatting fix. (shift_bytes_in_array_right): Formatting fix. * gcc.c-torture/execute/pr79737-1.c: New test. * gcc.c-torture/execute/pr79737-2.c: New test. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@245795 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gimple-ssa-store-merging.c')
-rw-r--r--gcc/gimple-ssa-store-merging.c47
1 files changed, 25 insertions, 22 deletions
diff --git a/gcc/gimple-ssa-store-merging.c b/gcc/gimple-ssa-store-merging.c
index c59fdcbdf38..17ac94ab2a7 100644
--- a/gcc/gimple-ssa-store-merging.c
+++ b/gcc/gimple-ssa-store-merging.c
@@ -253,9 +253,9 @@ shift_bytes_in_array_right (unsigned char *ptr, unsigned int sz,
unsigned prev_carry_over = carry_over;
carry_over = ptr[i] & carry_mask;
- carry_over <<= (unsigned char) BITS_PER_UNIT - amnt;
- ptr[i] >>= amnt;
- ptr[i] |= prev_carry_over;
+ carry_over <<= (unsigned char) BITS_PER_UNIT - amnt;
+ ptr[i] >>= amnt;
+ ptr[i] |= prev_carry_over;
}
}
@@ -352,8 +352,9 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos,
{
unsigned int first_byte = bitpos / BITS_PER_UNIT;
tree tmp_int = expr;
- bool sub_byte_op_p = (bitlen % BITS_PER_UNIT) || (bitpos % BITS_PER_UNIT)
- || mode_for_size (bitlen, MODE_INT, 0) == BLKmode;
+ bool sub_byte_op_p = ((bitlen % BITS_PER_UNIT)
+ || (bitpos % BITS_PER_UNIT)
+ || mode_for_size (bitlen, MODE_INT, 0) == BLKmode);
if (!sub_byte_op_p)
return (native_encode_expr (tmp_int, ptr + first_byte, total_bytes, 0)
@@ -407,7 +408,7 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos,
memset (tmpbuf, '\0', byte_size);
/* The store detection code should only have allowed constants that are
accepted by native_encode_expr. */
- if (native_encode_expr (expr, tmpbuf, byte_size, 0) == 0)
+ if (native_encode_expr (expr, tmpbuf, byte_size - 1, 0) == 0)
gcc_unreachable ();
/* The native_encode_expr machinery uses TYPE_MODE to determine how many
@@ -418,25 +419,27 @@ encode_tree_to_bitpos (tree expr, unsigned char *ptr, int bitlen, int bitpos,
contain a sign bit due to sign-extension). */
unsigned int padding
= byte_size - ROUND_UP (bitlen, BITS_PER_UNIT) / BITS_PER_UNIT - 1;
- if (padding != 0
- || bitlen % BITS_PER_UNIT != 0)
+ /* On big-endian the padding is at the 'front' so just skip the initial
+ bytes. */
+ if (BYTES_BIG_ENDIAN)
+ tmpbuf += padding;
+
+ byte_size -= padding;
+
+ if (bitlen % BITS_PER_UNIT != 0)
{
- /* On big-endian the padding is at the 'front' so just skip the initial
- bytes. */
if (BYTES_BIG_ENDIAN)
- tmpbuf += padding;
-
- byte_size -= padding;
- if (bitlen % BITS_PER_UNIT != 0)
- {
- if (BYTES_BIG_ENDIAN)
- clear_bit_region_be (tmpbuf, BITS_PER_UNIT - 1,
- BITS_PER_UNIT - (bitlen % BITS_PER_UNIT));
- else
- clear_bit_region (tmpbuf, bitlen,
- byte_size * BITS_PER_UNIT - bitlen);
- }
+ clear_bit_region_be (tmpbuf, BITS_PER_UNIT - 1,
+ BITS_PER_UNIT - (bitlen % BITS_PER_UNIT));
+ else
+ clear_bit_region (tmpbuf, bitlen,
+ byte_size * BITS_PER_UNIT - bitlen);
}
+ /* Left shifting relies on the last byte being clear if bitlen is
+ a multiple of BITS_PER_UNIT, which might not be clear if
+ there are padding bytes. */
+ else if (!BYTES_BIG_ENDIAN)
+ tmpbuf[byte_size - 1] = '\0';
/* Clear the bit region in PTR where the bits from TMPBUF will be
inserted into. */