[PATCH] Fix bugs related to TRULY_NOOP_TRUNCATION

Eric Botcazou ebotcazou@adacore.com
Fri Sep 26 21:23:00 GMT 2008


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?


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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: p.diff
Type: text/x-diff
Size: 1047 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20080926/7e9be326/attachment.bin>


More information about the Gcc-patches mailing list