diff --git a/gcc/combine.cc b/gcc/combine.cc index f2c64a9..5aa2f57 100644 --- a/gcc/combine.cc +++ b/gcc/combine.cc @@ -7613,7 +7613,8 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, && (pos == 0 || REG_P (inner)) && (inner_mode == tmode || !REG_P (inner) - || TRULY_NOOP_TRUNCATION_MODES_P (tmode, inner_mode) + || (known_lt (GET_MODE_SIZE (tmode), GET_MODE_SIZE (inner_mode)) + && TRULY_NOOP_TRUNCATION_MODES_P (tmode, inner_mode)) || reg_truncated_to_mode (tmode, inner)) && (! in_dest || (REG_P (inner) @@ -7856,6 +7857,8 @@ make_extraction (machine_mode mode, rtx inner, HOST_WIDE_INT pos, /* On the LHS, don't create paradoxical subregs implicitely truncating the register unless TARGET_TRULY_NOOP_TRUNCATION. */ if (in_dest + && known_lt (GET_MODE_SIZE (GET_MODE (inner)), + GET_MODE_SIZE (wanted_inner_mode)) && !TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (inner), wanted_inner_mode)) return NULL_RTX; diff --git a/gcc/expmed.cc b/gcc/expmed.cc index 05331dd..6398bf9 100644 --- a/gcc/expmed.cc +++ b/gcc/expmed.cc @@ -651,6 +651,7 @@ store_bit_field_using_insv (const extraction_insn *insv, rtx op0, X) 0)) is (reg:N X). */ if (GET_CODE (xop0) == SUBREG && REG_P (SUBREG_REG (xop0)) + && paradoxical_subreg_p (xop0) && !TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (SUBREG_REG (xop0)), op_mode)) { @@ -1585,7 +1586,11 @@ extract_bit_field_using_extv (const extraction_insn *extv, rtx op0, mode. Instead, create a temporary and use convert_move to set the target. */ if (REG_P (target) - && TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (target), ext_mode) + && (known_lt (GET_MODE_SIZE (GET_MODE (target)), + GET_MODE_SIZE (ext_mode)) + ? TRULY_NOOP_TRUNCATION_MODES_P (GET_MODE (target), ext_mode) + : known_eq (GET_MODE_SIZE (GET_MODE (target)), + GET_MODE_SIZE (ext_mode))) && (temp = gen_lowpart_if_possible (ext_mode, target))) { target = temp; @@ -1626,7 +1631,9 @@ extract_bit_field_as_subreg (machine_mode mode, rtx op0, if (multiple_p (bitnum, BITS_PER_UNIT, &bytenum) && known_eq (bitsize, GET_MODE_BITSIZE (mode)) && lowpart_bit_field_p (bitnum, bitsize, op0_mode) - && TRULY_NOOP_TRUNCATION_MODES_P (mode, op0_mode)) + && (known_lt (GET_MODE_SIZE (mode), GET_MODE_SIZE (op0_mode)) + ? TRULY_NOOP_TRUNCATION_MODES_P (mode, op0_mode) + : known_eq (GET_MODE_SIZE (mode), GET_MODE_SIZE (op0_mode)))) return simplify_gen_subreg (mode, op0, op0_mode, bytenum); return NULL_RTX; } diff --git a/gcc/optabs-query.cc b/gcc/optabs-query.cc index 947ccef..f33253f 100644 --- a/gcc/optabs-query.cc +++ b/gcc/optabs-query.cc @@ -213,7 +213,7 @@ get_best_extraction_insn (extraction_insn *insn, FOR_EACH_MODE_FROM (mode_iter, mode) { mode = mode_iter.require (); - if (maybe_gt (GET_MODE_SIZE (mode), GET_MODE_SIZE (field_mode)) + if (maybe_ge (GET_MODE_SIZE (mode), GET_MODE_SIZE (field_mode)) || TRULY_NOOP_TRUNCATION_MODES_P (insn->field_mode, field_mode)) break; diff --git a/gcc/optabs.cc b/gcc/optabs.cc index 6a34276..fad0d59 100644 --- a/gcc/optabs.cc +++ b/gcc/optabs.cc @@ -2954,7 +2954,11 @@ expand_parity (scalar_int_mode mode, rtx op0, rtx target) if (temp) { if (mclass != MODE_INT - || !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode)) + || (known_lt (GET_MODE_SIZE (mode), + GET_MODE_SIZE (wider_mode)) + ? !TRULY_NOOP_TRUNCATION_MODES_P (mode, wider_mode) + : maybe_ne (GET_MODE_SIZE (mode), + GET_MODE_SIZE (wider_mode)))) return convert_to_mode (mode, temp, 0); else return gen_lowpart (mode, temp); diff --git a/gcc/rtlhooks.cc b/gcc/rtlhooks.cc index 989d3c9..c3313fd 100644 --- a/gcc/rtlhooks.cc +++ b/gcc/rtlhooks.cc @@ -66,7 +66,8 @@ gen_lowpart_general (machine_mode mode, rtx x) scalar_int_mode xmode; if (is_a (GET_MODE (x), &xmode) && GET_MODE_SIZE (xmode) <= UNITS_PER_WORD - && TRULY_NOOP_TRUNCATION_MODES_P (mode, xmode) + && (known_ge (GET_MODE_SIZE (mode), GET_MODE_SIZE (xmode)) + || TRULY_NOOP_TRUNCATION_MODES_P (mode, xmode)) && !reload_completed) return gen_lowpart_general (mode, force_reg (xmode, x)); diff --git a/gcc/simplify-rtx.cc b/gcc/simplify-rtx.cc index f3745d8..27518f5 100644 --- a/gcc/simplify-rtx.cc +++ b/gcc/simplify-rtx.cc @@ -617,7 +617,7 @@ simplify_context::simplify_truncation (machine_mode mode, rtx op, unsigned int op_precision = GET_MODE_UNIT_PRECISION (op_mode); scalar_int_mode int_mode, int_op_mode, subreg_mode; - gcc_assert (precision <= op_precision); + gcc_assert (precision < op_precision); /* Optimize truncations of zero and sign extended values. */ if (GET_CODE (op) == ZERO_EXTEND @@ -1207,6 +1207,10 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode, break; case TRUNCATE: + /* Check for useless truncation. */ + if (GET_MODE (op) == mode) + return op; + /* Don't optimize (lshiftrt (mult ...)) as it would interfere with the umulXi3_highpart patterns. */ if (GET_CODE (op) == LSHIFTRT @@ -1271,9 +1275,6 @@ simplify_context::simplify_unary_operation_1 (rtx_code code, machine_mode mode, return temp; } - /* Check for useless truncation. */ - if (GET_MODE (op) == mode) - return op; break; case FLOAT_TRUNCATE: