diff options
Diffstat (limited to 'gcc/simplify-rtx.c')
-rw-r--r-- | gcc/simplify-rtx.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 03fbc75..34392dc 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -859,8 +859,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op) if (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op) && ! SUBREG_PROMOTED_UNSIGNED_P (op) - && GET_MODE (XEXP (op, 0)) == mode) - return XEXP (op, 0); + && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0)))) + return rtl_hooks.gen_lowpart_no_emit (mode, op); #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend) if (! POINTERS_EXTEND_UNSIGNED @@ -881,8 +881,8 @@ simplify_unary_operation_1 (enum rtx_code code, enum machine_mode mode, rtx op) if (GET_CODE (op) == SUBREG && SUBREG_PROMOTED_VAR_P (op) && SUBREG_PROMOTED_UNSIGNED_P (op) > 0 - && GET_MODE (XEXP (op, 0)) == mode) - return XEXP (op, 0); + && GET_MODE_SIZE (mode) <= GET_MODE_SIZE (GET_MODE (XEXP (op, 0)))) + return rtl_hooks.gen_lowpart_no_emit (mode, op); #if defined(POINTERS_EXTEND_UNSIGNED) && !defined(HAVE_ptr_extend) if (POINTERS_EXTEND_UNSIGNED > 0 @@ -5021,7 +5021,22 @@ simplify_subreg (enum machine_mode outermode, rtx op, return newx; if (validate_subreg (outermode, innermostmode, SUBREG_REG (op), final_offset)) - return gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset); + { + newx = gen_rtx_SUBREG (outermode, SUBREG_REG (op), final_offset); + if (SUBREG_PROMOTED_VAR_P (op) + && SUBREG_PROMOTED_UNSIGNED_P (op) >= 0 + && GET_MODE_CLASS (outermode) == MODE_INT + && IN_RANGE (GET_MODE_SIZE (outermode), + GET_MODE_SIZE (innermode), + GET_MODE_SIZE (innermostmode)) + && subreg_lowpart_p (newx)) + { + SUBREG_PROMOTED_VAR_P (newx) = 1; + SUBREG_PROMOTED_UNSIGNED_SET + (newx, SUBREG_PROMOTED_UNSIGNED_P (op)); + } + return newx; + } return NULL_RTX; } |