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]

[PATCH] combine leaves superfluous mem subregs


Hi,

working on a patch for the s390 back end I've noticed that combine generates
pointless subregs which can't be handled by reload.

e.g. combine replaces the pseudo in:
(subreg:SF (reg:SI 42)) with a memory location to:

(subreg:SF (mem:SI (reg:SI 43))) and reload complaines in push_reload about that
subreg.

I think combine should have simplified this to:
(mem:SF (reg:SI 43))

The attached patch adds a call to simplify_subreg after make_compound_operation 
has called itself with the operand of this subreg. Additionally it removes an 
optimization in make_compound_statement which is already done by simplify_subreg.

Unfortunately I can't come up with a testcase showing the failure with current gcc.
In most cases these contructs do not lead to an abort in reload because eliminate_regs
reduces (subreg (mem)) to (mem) whenever possible but only if the memory location uses 
an eliminable reg (reload1.c:2551).

Bootstrapped on s390, s390x and i686 without testsuite regressions.

OK for mainline?

Bye,

-Andreas-

2005-06-17  Andreas Krebbel  <krebbel1@de.ibm.com>

	* combine.c (make_compound_operation): Use simplify_subreg. Deleted
	a optimization already done by simplify_subreg.


Index: gcc/combine.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/combine.c,v
retrieving revision 1.491
diff -p -c -r1.491 combine.c
*** gcc/combine.c	7 Jun 2005 14:30:15 -0000	1.491
--- gcc/combine.c	17 Jun 2005 08:16:05 -0000
*************** make_compound_operation (rtx x, enum rtx
*** 6731,6771 ****
  	 what it originally did, do this SUBREG as a force_to_mode.  */
  
        tem = make_compound_operation (SUBREG_REG (x), in_code);
!       if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x))
! 	  && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem))
! 	  && subreg_lowpart_p (x))
! 	{
! 	  rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0,
! 				     NULL_RTX, 0);
! 
! 	  /* If we have something other than a SUBREG, we might have
! 	     done an expansion, so rerun ourselves.  */
! 	  if (GET_CODE (newer) != SUBREG)
! 	    newer = make_compound_operation (newer, in_code);
! 
! 	  return newer;
! 	}
! 
!       /* If this is a paradoxical subreg, and the new code is a sign or
! 	 zero extension, omit the subreg and widen the extension.  If it
! 	 is a regular subreg, we can still get rid of the subreg by not
! 	 widening so much, or in fact removing the extension entirely.  */
!       if ((GET_CODE (tem) == SIGN_EXTEND
! 	   || GET_CODE (tem) == ZERO_EXTEND)
! 	  && subreg_lowpart_p (x))
! 	{
! 	  if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (tem))
! 	      || (GET_MODE_SIZE (mode) >
! 		  GET_MODE_SIZE (GET_MODE (XEXP (tem, 0)))))
! 	    {
! 	      if (! SCALAR_INT_MODE_P (mode))
! 		break;
! 	      tem = gen_rtx_fmt_e (GET_CODE (tem), mode, XEXP (tem, 0));
! 	    }
! 	  else
! 	    tem = gen_lowpart (mode, XEXP (tem, 0));
  	  return tem;
! 	}
        break;
  
      default:
--- 6731,6763 ----
  	 what it originally did, do this SUBREG as a force_to_mode.  */
  
        tem = make_compound_operation (SUBREG_REG (x), in_code);
! 
!       {
! 	rtx simplified;
! 	simplified = simplify_subreg (GET_MODE (x), tem, GET_MODE (tem),
! 				      SUBREG_BYTE (x));
! 
! 	if (simplified)
! 	  tem = simplified;
! 
! 	if (GET_CODE (tem) != GET_CODE (SUBREG_REG (x))
! 	    && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (tem))
! 	    && subreg_lowpart_p (x))
! 	  {
! 	    rtx newer = force_to_mode (tem, mode, ~(HOST_WIDE_INT) 0,
! 				       NULL_RTX, 0);
! 	    
! 	    /* If we have something other than a SUBREG, we might have
! 	       done an expansion, so rerun ourselves.  */
! 	    if (GET_CODE (newer) != SUBREG)
! 	      newer = make_compound_operation (newer, in_code);
! 	    
! 	    return newer;
! 	  }
! 
! 	if (simplified)
  	  return tem;
!       }
        break;
  
      default:


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