diff options
Diffstat (limited to 'gcc/combine.c')
-rw-r--r-- | gcc/combine.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/gcc/combine.c b/gcc/combine.c index 6d58b19..0792ba3 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -7697,8 +7697,24 @@ make_compound_operation (rtx x, enum rtx_code in_code) what it originally did, do this SUBREG as a force_to_mode. */ { rtx inner = SUBREG_REG (x), simplified; - - tem = make_compound_operation (inner, in_code); + enum rtx_code subreg_code = in_code; + + /* If in_code is COMPARE, it isn't always safe to pass it through + to the recursive make_compound_operation call. */ + if (subreg_code == COMPARE + && (!subreg_lowpart_p (x) + || GET_CODE (inner) == SUBREG + /* (subreg:SI (and:DI (reg:DI) (const_int 0x800000000)) 0) + is (const_int 0), rather than + (subreg:SI (lshiftrt:DI (reg:DI) (const_int 35)) 0). */ + || (GET_CODE (inner) == AND + && CONST_INT_P (XEXP (inner, 1)) + && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (inner)) + && exact_log2 (UINTVAL (XEXP (inner, 1))) + >= GET_MODE_BITSIZE (mode)))) + subreg_code = SET; + + tem = make_compound_operation (inner, subreg_code); simplified = simplify_subreg (mode, tem, GET_MODE (inner), SUBREG_BYTE (x)); |