diff options
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 54 |
1 files changed, 23 insertions, 31 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index d618c9f..c4e6f95 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -6732,41 +6732,33 @@ make_compound_operation (rtx x, enum rtx_code in_code) what it originally did, do this SUBREG as a force_to_mode. */ tem = make_compound_operation (SUBREG_REG (x), in_code); - if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x)) - && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem)) - && subreg_lowpart_p (x)) - { - rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0, - NULL_RTX, 0); - /* If we have something other than a SUBREG, we might have - done an expansion, so rerun ourselves. */ - if (GET_CODE (newer) != SUBREG) - newer = make_compound_operation (newer, in_code); + { + rtx simplified; + simplified = simplify_subreg (GET_MODE (x), tem, GET_MODE (tem), + SUBREG_BYTE (x)); - return newer; - } + if (simplified) + tem = simplified; - /* If this is a paradoxical subreg, and the new code is a sign or - zero extension, omit the subreg and widen the extension. If it - is a regular subreg, we can still get rid of the subreg by not - widening so much, or in fact removing the extension entirely. */ - if ((GET_CODE (tem) == SIGN_EXTEND - || GET_CODE (tem) == ZERO_EXTEND) - && subreg_lowpart_p (x)) - { - if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (tem)) - || (GET_MODE_SIZE (mode) > - GET_MODE_SIZE (GET_MODE (XEXP (tem, 0))))) - { - if (! SCALAR_INT_MODE_P (mode)) - break; - tem = gen_rtx_fmt_e (GET_CODE (tem), mode, XEXP (tem, 0)); - } - else - tem = gen_lowpart (mode, XEXP (tem, 0)); + if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x)) + && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem)) + && subreg_lowpart_p (x)) + { + rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0, + NULL_RTX, 0); + + /* If we have something other than a SUBREG, we might have + done an expansion, so rerun ourselves. */ + if (GET_CODE (newer) != SUBREG) + newer = make_compound_operation (newer, in_code); + + return newer; + } + + if (simplified) return tem; - } + } break; default: |