aboutsummaryrefslogtreecommitdiff
path: root/gcc/rtlanal.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-09-19 09:04:28 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-09-19 09:04:28 +0000
commitf24f4c15884bf1ee65a10e2f959842eec4198876 (patch)
tree36f90ba89bf92546561ae999a4a48cd9c5a4704f /gcc/rtlanal.c
parent4736041b5aa5681c44cbb9c183b11bbb781492fc (diff)
downloadgcc-f24f4c15884bf1ee65a10e2f959842eec4198876.zip
gcc-f24f4c15884bf1ee65a10e2f959842eec4198876.tar.gz
gcc-f24f4c15884bf1ee65a10e2f959842eec4198876.tar.bz2
Rework constant subreg folds and handle more variable-length cases
This patch rewrites the way simplify_subreg handles constants. It uses similar native_encode/native_decode routines to the tree-level handling of VIEW_CONVERT_EXPR, meaning that we can move between rtx constants and the target memory image of them. The main point of this patch is to support subregs of constant-length vectors for VLA vectors, beyond the very simple cases that were already handled. Many of the new tests failed before the patch for variable- length vectors. The boolean side is tested more by the upcoming SVE ACLE work. 2019-09-19 Richard Sandiford <richard.sandiford@arm.com> gcc/ * defaults.h (TARGET_UNIT): New macro. (target_unit): New type. * rtl.h (native_encode_rtx, native_decode_rtx) (native_decode_vector_rtx, subreg_size_lsb): Declare. (subreg_lsb_1): Turn into an inline wrapper around subreg_size_lsb. * rtlanal.c (subreg_lsb_1): Delete. (subreg_size_lsb): New function. * simplify-rtx.c: Include rtx-vector-builder.h (simplify_immed_subreg): Delete. (native_encode_rtx, native_decode_vector_rtx, native_decode_rtx) (simplify_const_vector_byte_offset, simplify_const_vector_subreg): New functions. (simplify_subreg): Use them. (test_vector_subregs_modes, test_vector_subregs_repeating) (test_vector_subregs_fore_back, test_vector_subregs_stepped) (test_vector_subregs): New functions. (test_vector_ops): Call test_vector_subregs for integer vector modes with at least 2 elements. From-SVN: r275959
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r--gcc/rtlanal.c28
1 files changed, 18 insertions, 10 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 3a72db7..28b399c 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -3637,23 +3637,31 @@ loc_mentioned_in_p (rtx *loc, const_rtx in)
return 0;
}
-/* Helper function for subreg_lsb. Given a subreg's OUTER_MODE, INNER_MODE,
- and SUBREG_BYTE, return the bit offset where the subreg begins
- (counting from the least significant bit of the operand). */
+/* Reinterpret a subreg as a bit extraction from an integer and return
+ the position of the least significant bit of the extracted value.
+ In other words, if the extraction were performed as a shift right
+ and mask, return the number of bits to shift right.
+
+ The outer value of the subreg has OUTER_BYTES bytes and starts at
+ byte offset SUBREG_BYTE within an inner value of INNER_BYTES bytes. */
poly_uint64
-subreg_lsb_1 (machine_mode outer_mode,
- machine_mode inner_mode,
- poly_uint64 subreg_byte)
+subreg_size_lsb (poly_uint64 outer_bytes,
+ poly_uint64 inner_bytes,
+ poly_uint64 subreg_byte)
{
poly_uint64 subreg_end, trailing_bytes, byte_pos;
/* A paradoxical subreg begins at bit position 0. */
- if (paradoxical_subreg_p (outer_mode, inner_mode))
- return 0;
+ gcc_checking_assert (ordered_p (outer_bytes, inner_bytes));
+ if (maybe_gt (outer_bytes, inner_bytes))
+ {
+ gcc_checking_assert (known_eq (subreg_byte, 0U));
+ return 0;
+ }
- subreg_end = subreg_byte + GET_MODE_SIZE (outer_mode);
- trailing_bytes = GET_MODE_SIZE (inner_mode) - subreg_end;
+ subreg_end = subreg_byte + outer_bytes;
+ trailing_bytes = inner_bytes - subreg_end;
if (WORDS_BIG_ENDIAN && BYTES_BIG_ENDIAN)
byte_pos = trailing_bytes;
else if (!WORDS_BIG_ENDIAN && !BYTES_BIG_ENDIAN)