Thanks for the review. Eric Botcazou <ebotca...@adacore.com> writes: >> Tested on x86_64-linux-gnu, mipsisa32-elf and mipsisa64-elf. Also tested >> by making sure that there were no code differences for a set of gcc .ii >> files on gcc20 (-O2 -march=native). OK to install? > > Are you sure that generating TRUNCATEs out of nowhere in simplify_subreg is > always correct?
We only use TRUNCATEs when truncating the operands of an existing operation. We don't convert the SUBREG itself to a TRUNCATE. I don't think it matters whether the narrowing of the operation was brought about by a TRUNCATE or by a SUBREG. I think modelling it as a TRUNCATE operation is correct for !TRULY_NOOP_TRUNCATION (it's the bug that Andrew pointed out). And we shouldn't generate an actual TRUNCATE rtx for TRULY_NOOP_TRUNCATION (the thing about making simplify_gen_unary (TRUNCATE, ...) no worse than simplify_gen_subreg for those targets). I suppose: /* We can't handle truncation to a partial integer mode here because we don't know the real bitsize of the partial integer mode. */ if (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT) break; might be a problem though; we should still allow a subreg to be generated. Is that what you were thinking of, or something else? I'm certainly open to other ideas though. Or do you think that I was wrong about doing this narrowing in simplify_subreg to begin with? >> gcc/ >> * machmode.h (GET_MODE_UNIT_PRECISION): New macro. >> * simplify-rtx.c (simplify_truncation): New function. > > You should say where it comes from. OK. >> (simplify_unary_operation_1): Use it. Remove sign bit test >> for !TRULY_NOOP_TRUNCATION_MODES_P. > > (simplify_unary_operation_1) <TRUNCATE>: ... > >> (simplify_subreg): Use simplify_int_lowpart for TRUNCATE. > > This function doesn't exist. And this is misleading, it's not just for > TRUNCATE, it's for a truncation to the lowpart. Curses, forgot to update that part. Thanks. >> /* Try to simplify a unary operation CODE whose output mode is to be >> MODE with input operand OP whose mode was originally OP_MODE. >> Return zero if no simplification can be made. */ >> @@ -689,12 +850,6 @@ simplify_unary_operation_1 (enum rtx_cod >> op_mode = mode; >> in2 = simplify_gen_unary (NOT, op_mode, in2, op_mode); >> >> - if (GET_CODE (in2) == NOT && GET_CODE (in1) != NOT) >> - { >> - rtx tem = in2; >> - in2 = in1; in1 = tem; >> - } >> - >> return gen_rtx_fmt_ee (GET_CODE (op) == IOR ? AND : IOR, >> mode, in1, in2); >> } > > Why is this hunk here? Sorry, I've no idea :-( >> @@ -5595,14 +5730,6 @@ simplify_subreg (enum machine_mode outer >> return NULL_RTX; >> } >> >> - /* Merge implicit and explicit truncations. */ >> - >> - if (GET_CODE (op) == TRUNCATE >> - && GET_MODE_SIZE (outermode) < GET_MODE_SIZE (innermode) >> - && subreg_lowpart_offset (outermode, innermode) == byte) >> - return simplify_gen_unary (TRUNCATE, outermode, XEXP (op, 0), >> - GET_MODE (XEXP (op, 0))); >> - >> /* SUBREG of a hard register => just change the register number >> and/or mode. If the hard register is not valid in that mode, >> suppress this simplification. If the hard register is the stack, > > Likewise. This moved to simplify_truncation: /* (truncate:A (truncate:B X)) is (truncate:A X). */ if (GET_CODE (op) == TRUNCATE) return simplify_gen_unary (TRUNCATE, mode, XEXP (op, 0), GET_MODE (XEXP (op, 0))); I haven't included an updated patch because of your general concern above. Richard