This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Fix bugs related to TRULY_NOOP_TRUNCATION
- From: "Richard Guenther" <richard dot guenther at gmail dot com>
- To: "Eric Botcazou" <ebotcazou at adacore dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Sat, 27 Sep 2008 18:49:00 -0700
- Subject: Re: [PATCH] Fix bugs related to TRULY_NOOP_TRUNCATION
- References: <200809262247.42034.ebotcazou@adacore.com>
On Fri, Sep 26, 2008 at 1:47 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
> Hi,
>
> the attached patch was necessary in order to fix a miscompilation of an Ada
> program at -O on MIPS n32. The problems pertained to TRULY_NOOP_TRUNCATION
> not being honored in a couple of places in expmed.c; unfortunately, I don't
> have a testcase for the FSF compiler.
>
> The first problem was in store_fixed_bit_field:
>
> if (GET_MODE (value) != mode)
> {
> if ((REG_P (value) || GET_CODE (value) == SUBREG)
> && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (value)))
> value = gen_lowpart (mode, value);
> else
> value = convert_to_mode (mode, value, 1);
> }
>
> TRULY_NOOP_TRUNCATION is not honored by gen_lowpart whereas it is by
> convert_to_mode.
>
> The second problem was in extract_bit_field_1:
>
> if (((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode)
> && bitpos % BITS_PER_WORD == 0)
> || (mode1 != BLKmode
> /* ??? The big endian test here is wrong. This is correct
> if the value is in a register, and if mode_for_size is not
> the same mode as op0. This causes us to get unnecessarily
> inefficient code from the Thumb port when -mbig-endian. */
> && (BYTES_BIG_ENDIAN
> ? bitpos + bitsize == BITS_PER_WORD
> : bitpos == 0)))
> && ((!MEM_P (op0)
> && TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (mode),
> GET_MODE_BITSIZE (GET_MODE (op0)))
> && GET_MODE_SIZE (mode1) != 0
> && byte_offset % GET_MODE_SIZE (mode1) == 0)
> || (MEM_P (op0)
> && (! SLOW_UNALIGNED_ACCESS (mode, MEM_ALIGN (op0))
> || (offset * BITS_PER_UNIT % bitsize == 0
> && MEM_ALIGN (op0) % bitsize == 0)))))
> {
> if (MEM_P (op0))
> op0 = adjust_address (op0, mode1, offset);
> else if (mode1 != GET_MODE (op0))
> {
> rtx sub = simplify_gen_subreg (mode1, op0, GET_MODE (op0),
> byte_offset);
> if (sub == NULL)
> goto no_subreg_mode_swap;
> op0 = sub;
> }
> if (mode1 != mode)
> return convert_to_mode (tmode, op0, unsignedp);
> return op0;
> }
>
> TRULY_NOOP_TRUNCATION is tested on 'mode' and 'GET_MODE (op0)' whereas
> simplify_gen_subreg is applied to 'mode1' and 'GET_MODE (op0)'.
>
> Hence the attached patch, tested on i586-suse-linux. It has been exercised in
> our 4.1 and 4.3 based compilers on MIPS n32. OK for mainline?
Ok.
Thanks,
Richard.
>
> 2008-09-26 Eric Botcazou <ebotcazou@adacore.com>
>
> * expmed.c (store_fixed_bit_field): Always use convert_to_mode in
> order to convert between modes.
> (extract_bit_field_1): Test TRULY_NOOP_TRUNCATION on the right mode.
>
>
> --
> Eric Botcazou
>