This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Fix bugs related to TRULY_NOOP_TRUNCATION


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
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]