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]

expmed.c patch for IA-64 glibc ICE


We are getting an incorrect TFmode to XFmode conversion on ia64-linux.  The
problem here is that we have mode == XFmode, and there is a call to
	mode_for_size (128, MODE_FLOAT, 0)
which returns TFmode.  This is because mode_for_size despite its name actually
uses mode precisions not mode sizes, and XFmode has a precision of 96 bits,
so it thinks we need TFmode.  There are no TFmode to XFmode conversions and
the resulting code fails to link.

There is no mode_for_size equivalent that uses mode sizes instead of mode
precisions, but we don't need one.  The code that is using mode_for_size is
using subregs and simple conversions, but that only works for integers.  The
code has already been modified to exclude vector modes.  We can fix the FP
problem by excluding all modes except scalar integers.

This patch also fixes one place that uses mode_for_size that should be using
mode1.

This was tested with a make bootstrap and make check on an ia64-linux system.
There were no regressions.

2003-12-08  James E Wilson  <wilson@specifixinc.com>

	PR target/13132
	* expmed.c (extract_bit_field): Only call mode_for_size for scalar
	integer modes.

Index: expmed.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expmed.c,v
retrieving revision 1.146
diff -p -r1.146 expmed.c
*** expmed.c	11 Nov 2003 20:54:38 -0000	1.146
--- expmed.c	5 Dec 2003 08:08:57 -0000
*************** extract_bit_field (rtx str_rtx, unsigned
*** 1079,1091 ****
       If that's wrong, the solution is to test for it and set TARGET to 0
       if needed.  */
  
!   mode1  = (VECTOR_MODE_P (tmode)
! 	    ? mode
! 	    : mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0));
  
    if (((bitsize >= BITS_PER_WORD && bitsize == GET_MODE_BITSIZE (mode)
  	&& bitpos % BITS_PER_WORD == 0)
!        || (mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0) != 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
--- 1079,1096 ----
       If that's wrong, the solution is to test for it and set TARGET to 0
       if needed.  */
  
!   /* Only scalar integer modes can be converted via subregs.  There is an
!      additional problem for FP modes here in that they can have a precision
!      which is different from the size.  mode_for_size uses precision, but
!      we want a mode based on the size, so we must avoid calling it for FP
!      modes.  */
!   mode1  = (SCALAR_INT_MODE_P (tmode)
! 	    ? mode_for_size (bitsize, GET_MODE_CLASS (tmode), 0)
! 	    : mode);
  
    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
-- 
Jim Wilson, GNU Tools Support, http://www.SpecifixInc.com


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