aboutsummaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2016-11-29 02:48:30 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2016-11-29 02:48:30 +0100
commit48cf0e51e9cd4a78488dc216ed6f190df4c5b481 (patch)
tree2c9d73fb0ca8669cbec06f9357fe5860c278ac14 /gcc/simplify-rtx.c
parentdeb2bb610eae556f5337458b1ac14fdf95a4e070 (diff)
downloadgcc-48cf0e51e9cd4a78488dc216ed6f190df4c5b481.zip
gcc-48cf0e51e9cd4a78488dc216ed6f190df4c5b481.tar.gz
gcc-48cf0e51e9cd4a78488dc216ed6f190df4c5b481.tar.bz2
simplify-rtx: Handle truncate of extract
simplify_truncation changes the truncation of many operations into the operation on the truncation. This patch makes this code also handle extracts. * simplify-rtx.c (simplify_truncation): Handle truncate of zero_extract and sign_extract. From-SVN: r242946
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r--gcc/simplify-rtx.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 83fb37d..7778db5 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -747,6 +747,36 @@ simplify_truncation (machine_mode mode, rtx op,
}
}
+ /* Turn (truncate:M1 (*_extract:M2 (reg:M2) (len) (pos))) into
+ (*_extract:M1 (truncate:M1 (reg:M2)) (len) (pos')) if possible without
+ changing len. */
+ if ((GET_CODE (op) == ZERO_EXTRACT || GET_CODE (op) == SIGN_EXTRACT)
+ && REG_P (XEXP (op, 0))
+ && CONST_INT_P (XEXP (op, 1))
+ && CONST_INT_P (XEXP (op, 2)))
+ {
+ rtx op0 = XEXP (op, 0);
+ unsigned HOST_WIDE_INT len = UINTVAL (XEXP (op, 1));
+ unsigned HOST_WIDE_INT pos = UINTVAL (XEXP (op, 2));
+ if (BITS_BIG_ENDIAN && pos >= op_precision - precision)
+ {
+ op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
+ if (op0)
+ {
+ pos -= op_precision - precision;
+ return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
+ XEXP (op, 1), GEN_INT (pos));
+ }
+ }
+ else if (!BITS_BIG_ENDIAN && precision >= len + pos)
+ {
+ op0 = simplify_gen_unary (TRUNCATE, mode, op0, GET_MODE (op0));
+ if (op0)
+ return simplify_gen_ternary (GET_CODE (op), mode, mode, op0,
+ XEXP (op, 1), XEXP (op, 2));
+ }
+ }
+
/* Recognize a word extraction from a multi-word subreg. */
if ((GET_CODE (op) == LSHIFTRT
|| GET_CODE (op) == ASHIFTRT)