expr.c patch to fix ia64 miscompilation problem

Jim Wilson wilson@cygnus.com
Thu Mar 9 20:04:00 GMT 2000


This fixes a problem where the ia64 compiler was miscompiling the SPEC95
134.perl sources.  This occured in eval.c, in the function eval, at one of
the recursive call sites.

The problem here is that eval returns an SImode value, which only has 4 valid
bytes out of 8.  This gets assigned to a promoted subreg, which requires
sign extension.  store_expr does this sign extension when called from
expand_assignment.  expand_assignment has some special case code for CALL_EXPR
which does not call store_expr.  There is a hack to disable this for a VAR_DECL
to force the sign extension.  In my case, I had a PARM_DECL.  So I added
another check for PARM_DECL.

I believe this problem can only occur if both PROMOTE_FUNCTION_ARGS and
PROMOTE_FUNCTION_RETURN are undefined.  This is uncommon among 64-bit port,
but is required by the ia64 ABI, which explains why this hasn't come up before.

Thu Mar  9 20:01:38 2000  Jim Wilson  <wilson@cygnus.com>

	* expr.c (expand_assignment): For a CALL_EXPR, special case PARM_DECL
	same as VAR_DECL.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/expr.c,v
retrieving revision 1.211
diff -p -r1.211 expr.c
*** expr.c	2000/03/08 16:00:00	1.211
--- expr.c	2000/03/10 04:00:10
*************** expand_assignment (to, from, want_value,
*** 3472,3484 ****
       val = setjmp (buf) on machines where reference to val
       requires loading up part of an address in a separate insn.
  
!      Don't do this if TO is a VAR_DECL whose DECL_RTL is REG since it might be
!      a promoted variable where the zero- or sign- extension needs to be done.
!      Handling this in the normal way is safe because no computation is done
!      before the call.  */
    if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from)
        && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
!       && ! (TREE_CODE (to) == VAR_DECL && GET_CODE (DECL_RTL (to)) == REG))
      {
        rtx value;
  
--- 3472,3485 ----
       val = setjmp (buf) on machines where reference to val
       requires loading up part of an address in a separate insn.
  
!      Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG
!      since it might be a promoted variable where the zero- or sign- extension
!      needs to be done.  Handling this in the normal way is safe because no
!      computation is done before the call.  */
    if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from)
        && TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
!       && ! ((TREE_CODE (to) == VAR_DECL || TREE_CODE (to) == PARM_DECL)
! 	    && GET_CODE (DECL_RTL (to)) == REG))
      {
        rtx value;
  


More information about the Gcc-patches mailing list