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]

IA64 HP-UX patch for gcc.c-torture/compile/20040624-1.c


This is a patch to fix gcc.c-torture/compile/20040624-1.c on HP-UX IA64.
The test has a return type of a structure containing a single floating
point variable (Which makes it an HFA, a homogeneous floating point
aggregate, in IA64 terms) and currently generates an ICE.

| 20040624-1.c:3: internal compiler error: in convert_move, at expr.c:335
| Please submit a full bug report,
| with preprocessed source if appropriate.
| See <URL:http://gcc.gnu.org/bugs.html> for instructions.

The bug is in
ia64_function_value where we have:

      if (i == 1)
        return XEXP (loc[0], 0);
      else
        return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));

The corresponding code from ia64_function_arg is:

      /* If we ended up using just one location, just return that one loc, but
         change the mode back to the argument mode.  However, we can't do this
         when hfa_mode is XFmode and mode is TImode.  In that case, we would
         return a TImode reference to an FP reg, but FP regs can't hold TImode.
         We need the PARALLEL to make this work.  This can happen for a union
         containing a single __float80 member.  */
      if (i == 1 && ! (hfa_mode == XFmode && mode == TImode))
        return gen_rtx_REG (mode, REGNO (XEXP (loc[0], 0)));
      else
        return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));

Now I could fix the test by copying the ia64_function_arg code into
ia64_function_value but I was wondering about the value of special
casing the single element situation, because I can also fix this by
simply using PARALLEL all the time.

In terms of the code generated, the code generated with PARALLEL
actually seems better because it loads/stores directly into or out of
the floaing point register.  With the gen_rtx_REG version we generate
code that uses an integer register as an intermediary.

The only downside I could see to using PARALLEL all the time is in
expand_call, where if the return value is in a PARALLEL we decide that
the call is not "cse'able" but maybe the SSA work / tree optimizations
make that a moot point.

Anyway, here is a patch to use PARALLEL all the time (in
ia64_function_arg and in ia64_function_value) and which was tested with
no regressions.  Let me know if this is OK or if I should do it the
other way.

Steve Ellcey
sje@cup.hp.com


2004-07-15  Steve Ellcey  <sje@cup.hp.com>

	* config/ia64/ia64.c (ia64_function_arg): Use PARALLEL even if there
	is only one reg.
	(ia64_function_value): Ditto.
*** gcc.orig/gcc/gcc/config/ia64/ia64.c	Fri Aug  6 14:56:47 2004
--- gcc/gcc/gcc/config/ia64/ia64.c	Fri Aug  6 14:57:29 2004
*************** ia64_function_arg (CUMULATIVE_ARGS *cum,
*** 3682,3698 ****
  	  else if (gr_size > UNITS_PER_WORD)
  	    int_regs += gr_size / UNITS_PER_WORD;
  	}
! 
!       /* If we ended up using just one location, just return that one loc, but
! 	 change the mode back to the argument mode.  However, we can't do this
! 	 when hfa_mode is XFmode and mode is TImode.  In that case, we would
! 	 return a TImode reference to an FP reg, but FP regs can't hold TImode.
! 	 We need the PARALLEL to make this work.  This can happen for a union
! 	 containing a single __float80 member.  */
!       if (i == 1 && ! (hfa_mode == XFmode && mode == TImode))
! 	return gen_rtx_REG (mode, REGNO (XEXP (loc[0], 0)));
!       else
! 	return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
      }
  
    /* Integral and aggregates go in general registers.  If we have run out of
--- 3682,3688 ----
  	  else if (gr_size > UNITS_PER_WORD)
  	    int_regs += gr_size / UNITS_PER_WORD;
  	}
!       return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
      }
  
    /* Integral and aggregates go in general registers.  If we have run out of
*************** ia64_function_value (tree valtype, tree 
*** 3990,4000 ****
  				      GEN_INT (offset));
  	  offset += hfa_size;
  	}
! 
!       if (i == 1)
! 	return XEXP (loc[0], 0);
!       else
! 	return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
      }
    else if (FLOAT_TYPE_P (valtype) && mode != TFmode && mode != TCmode)
      return gen_rtx_REG (mode, FR_ARG_FIRST);
--- 3980,3986 ----
  				      GEN_INT (offset));
  	  offset += hfa_size;
  	}
!       return gen_rtx_PARALLEL (mode, gen_rtvec_v (i, loc));
      }
    else if (FLOAT_TYPE_P (valtype) && mode != TFmode && mode != TCmode)
      return gen_rtx_REG (mode, FR_ARG_FIRST);


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