From 48cf0e51e9cd4a78488dc216ed6f190df4c5b481 Mon Sep 17 00:00:00 2001 From: Segher Boessenkool Date: Tue, 29 Nov 2016 02:48:30 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 5 +++++ gcc/simplify-rtx.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5ce50b04f55..900f9b355d7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2016-11-28 Segher Boessenkool + + * simplify-rtx.c (simplify_truncation): Handle truncate of zero_extract + and sign_extract. + 2016-11-28 Uros Bizjak * config/i386/i386.md (*and_1): Merge insn pattern from diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 83fb37d8535..7778db55a24 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) -- 2.30.2