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] Complex MEM adjust_address instead of subreg (PR middle-end/21742)


	The testcases reported in the PR exercise floating point complex
support.  When compiled on PowerPC without optimization,
emit_move_complex() is called with a complex float MEM corresponding to a
virtual stack var.

(mem/s/j:DC (plus:SI (reg/f:SI 114 virtual-stack-vars)
        (const_int 33112 [0x8158])) [0 <variable>.e.m+0 S16 A64])

emit_move_complex() invokes read_complex_part() and write_complex_part()
for the real and imaginary parts, which call simplify_gen_subreg()
creating float SUBREGs that cannot be recognized on PowerPC.

(set (reg:DF 130 [ D.1250+8 ])
        (subreg:DF (mem/s/j:DC (plus:SI (reg/f:SI 114 virtual-stack-vars)
                    (const_int 33112 [0x8158])) [0 <variable>.e.m+0 S16
        A64])
8)) -1 (nil)
    (nil))

When compiled with optimization, the variables are decomposed earlier into
fundamental GCC floating point modes, avoiding processing of complex
values in the expander.

	The following patch modifies write_complex_part() and
read_complex_part() to reference the real and imaginary parts of the
complex MEMs using adjust_address() instead of creating MEM SUBREGs that
need to be decomposed later.  This same approach for MEMs is used
elsewhere in GCC, e.g., expmed.c for bit fields.  adjust_address()
produces MEMs similar to the ones created for the testcases when
optimizing.

	The patch tests for MEM_P() first and invokes adjust_address().
The test could be restricted to multi-word complex modes or float complex
modes, but currently is not.  It assumes that adjust_address() of a MEM
cannot fail, not falling back to bit field functions.

	Because of the current mainline bootstrap breakage, I cannot fully
test the patch, but the patch does correct the failures.  The comment will
be updated as appropriate depending on the final decision about when to
apply adjust_address().  Is this patch an acceptable solution or should
another approach be used?

Assuming this bootstraps with no regressions, is this patch okay for
mainline with the comment updated?

Thanks,
David

	PR middle-end/21742
	* expr.c (write_complex_part): Use adjust_address for MEM.
	(read_complex_part): Same.

Index: expr.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/expr.c,v
retrieving revision 1.798
diff -c -p -r1.798 expr.c
*** expr.c	25 Jun 2005 01:59:50 -0000	1.798
--- expr.c	29 Jun 2005 01:03:50 -0000
*************** write_complex_part (rtx cplx, rtx val, b
*** 2656,2661 ****
--- 2656,2668 ----
    imode = GET_MODE_INNER (cmode);
    ibitsize = GET_MODE_BITSIZE (imode);
  
+   /* For MEMs we always try to make a "subreg", that is to adjust
+      the MEM, because store_bit_field may generate overly
+      convoluted RTL for sub-word fields.  */
+   if (MEM_P (cplx))
+     emit_move_insn (adjust_address (cplx, imode, imag_p ? ibitsize : 0),
+ 		    val);
+ 
    /* If the sub-object is at least word sized, then we know that subregging
       will work.  This special case is important, since store_bit_field
       wants to operate on integer modes, and there's rarely an OImode to
*************** write_complex_part (rtx cplx, rtx val, b
*** 2667,2677 ****
  	 where the natural size of floating-point regs is 32-bit.  */
        || (REG_P (cplx)
  	  && REGNO (cplx) < FIRST_PSEUDO_REGISTER
! 	  && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0)
!       /* For MEMs we always try to make a "subreg", that is to adjust
! 	 the MEM, because store_bit_field may generate overly
! 	 convoluted RTL for sub-word fields.  */
!       || MEM_P (cplx))
      {
        rtx part = simplify_gen_subreg (imode, cplx, cmode,
  				      imag_p ? GET_MODE_SIZE (imode) : 0);
--- 2674,2680 ----
  	 where the natural size of floating-point regs is 32-bit.  */
        || (REG_P (cplx)
  	  && REGNO (cplx) < FIRST_PSEUDO_REGISTER
! 	  && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0))
      {
        rtx part = simplify_gen_subreg (imode, cplx, cmode,
  				      imag_p ? GET_MODE_SIZE (imode) : 0);
*************** read_complex_part (rtx cplx, bool imag_p
*** 2716,2721 ****
--- 2719,2730 ----
  	}
      }
  
+   /* For MEMs we always try to make a "subreg", that is to adjust
+      the MEM, because extract_bit_field may generate overly
+      convoluted RTL for sub-word fields.  */
+   if (MEM_P (cplx))
+     return adjust_address (cplx, imode, imag_p ? ibitsize : 0);
+ 
    /* If the sub-object is at least word sized, then we know that subregging
       will work.  This special case is important, since extract_bit_field
       wants to operate on integer modes, and there's rarely an OImode to
*************** read_complex_part (rtx cplx, bool imag_p
*** 2727,2737 ****
  	 where the natural size of floating-point regs is 32-bit.  */
        || (REG_P (cplx)
  	  && REGNO (cplx) < FIRST_PSEUDO_REGISTER
! 	  && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0)
!       /* For MEMs we always try to make a "subreg", that is to adjust
! 	 the MEM, because extract_bit_field may generate overly
! 	 convoluted RTL for sub-word fields.  */
!       || MEM_P (cplx))
      {
        rtx ret = simplify_gen_subreg (imode, cplx, cmode,
  				     imag_p ? GET_MODE_SIZE (imode) : 0);
--- 2736,2742 ----
  	 where the natural size of floating-point regs is 32-bit.  */
        || (REG_P (cplx)
  	  && REGNO (cplx) < FIRST_PSEUDO_REGISTER
! 	  && hard_regno_nregs[REGNO (cplx)][cmode] % 2 == 0))
      {
        rtx ret = simplify_gen_subreg (imode, cplx, cmode,
  				     imag_p ? GET_MODE_SIZE (imode) : 0);


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