aboutsummaryrefslogtreecommitdiff
path: root/gcc/simplify-rtx.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r--gcc/simplify-rtx.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 1e4ba23..8094c75 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -3104,6 +3104,44 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode,
&& UINTVAL (trueop0) == GET_MODE_MASK (mode)
&& ! side_effects_p (op1))
return op0;
+ /* Given:
+ scalar modes M1, M2
+ scalar constants c1, c2
+ size (M2) > size (M1)
+ c1 == size (M2) - size (M1)
+ optimize:
+ (ashiftrt:M1 (subreg:M1 (lshiftrt:M2 (reg:M2)
+ (const_int <c1>))
+ <low_part>)
+ (const_int <c2>))
+ to:
+ (subreg:M1 (ashiftrt:M2 (reg:M2)
+ (const_int <c1 + c2>))
+ <low_part>). */
+ if (!VECTOR_MODE_P (mode)
+ && SUBREG_P (op0)
+ && CONST_INT_P (op1)
+ && (GET_CODE (SUBREG_REG (op0)) == LSHIFTRT)
+ && !VECTOR_MODE_P (GET_MODE (SUBREG_REG (op0)))
+ && CONST_INT_P (XEXP (SUBREG_REG (op0), 1))
+ && (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
+ > GET_MODE_BITSIZE (mode))
+ && (INTVAL (XEXP (SUBREG_REG (op0), 1))
+ == (GET_MODE_BITSIZE (GET_MODE (SUBREG_REG (op0)))
+ - GET_MODE_BITSIZE (mode)))
+ && subreg_lowpart_p (op0))
+ {
+ rtx tmp = GEN_INT (INTVAL (XEXP (SUBREG_REG (op0), 1))
+ + INTVAL (op1));
+ machine_mode inner_mode = GET_MODE (SUBREG_REG (op0));
+ tmp = simplify_gen_binary (ASHIFTRT,
+ GET_MODE (SUBREG_REG (op0)),
+ XEXP (SUBREG_REG (op0), 0),
+ tmp);
+ return simplify_gen_subreg (mode, tmp, inner_mode,
+ subreg_lowpart_offset (mode,
+ inner_mode));
+ }
canonicalize_shift:
if (SHIFT_COUNT_TRUNCATED && CONST_INT_P (op1))
{