diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c index 571e2337e2718add3d14b43fde835beb8c2cf2a2..d13c390a20ccf1dfafcbaf57839554c7ef215f22 100644 --- a/gcc/simplify-rtx.c +++ b/gcc/simplify-rtx.c @@ -7035,12 +7035,19 @@ simplify_immed_subreg (fixed_size_mode outermode, rtx x, while (buffer.length () < buffer_bytes) buffer.quick_push (filler); } - else + else if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes)) + return NULL_RTX; + rtx ret = native_decode_rtx (outermode, buffer, 0); + if (ret && MODE_COMPOSITE_P (outermode)) { - if (!native_encode_rtx (innermode, x, buffer, first_byte, inner_bytes)) + auto_vec<target_unit, 128> buffer2 (buffer_bytes); + if (!native_encode_rtx (outermode, ret, buffer2, 0, buffer_bytes)) return NULL_RTX; - } - return native_decode_rtx (outermode, buffer, 0); + for (unsigned int i = 0; i < buffer_bytes; ++i) + if (buffer[i] != buffer2[i]) + return NULL_RTX; + } + return ret; } /* Simplify SUBREG:OUTERMODE(OP:INNERMODE, BYTE) @@ -7336,6 +7343,13 @@ simplify_context::simplify_gen_subreg (machine_mode outermode, rtx op, || GET_MODE (op) == VOIDmode) return NULL_RTX; + if (MODE_COMPOSITE_P (outermode) + && (CONST_SCALAR_INT_P (op) + || CONST_DOUBLE_AS_FLOAT_P (op) + || CONST_FIXED_P (op) + || GET_CODE (op) == CONST_VECTOR)) + return NULL_RTX; + if (validate_subreg (outermode, innermode, op, byte)) return gen_rtx_SUBREG (outermode, op, byte);