diff options
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 38 |
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)) { |