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]

Re: PATCH RFC: My version of the lower-subreg patch


On Fri, Dec 15, 2006 at 06:05:25PM -0800, Ian Lance Taylor wrote:
> Anyhow, I wanted to put this patch out for comments, to see what
> people think of it.  I'd be interested in results on machines other
> than the i386.

   The pass sometimes leaves CONCATN rtx'es behind:

expand dump:

;; gh_u.value = x
(note 19 18 24 ("../../../../../../../cvssrc/gcc/newlib/libm/common/s_finite.c") 31)

(insn 24 19 20 (clobber (subreg:DF (reg/v:DI 20 [ gh_u ]) 0)) -1 (nil)
    (nil))

subreg dump:

; Splitting reg 20 -> 31 32 33 34
[cut]
(insn 24 16 20 2 ../../../../../../../cvssrc/gcc/newlib/libm/common/s_finite.c:31 (clobber (subreg:DF (concatn/v:DI [
                    (reg:HI 31 [ gh_u ])
                    (reg:HI 32 [ gh_u+2 ])
                    (reg:HI 33 [ gh_u+4 ])
                    (reg:HI 34 [ gh_u+6 ])
                ]) 0)) -1 (nil)
    (nil))

   The problem is triggered by this code:

typedef union
{
  double value;
  struct
  {
    __uint32_t lsw;
    __uint32_t msw;
  } parts;
} ieee_double_shape_type;

int finite(double x)
{
 __int32_t hx;
 do { ieee_double_shape_type gh_u; gh_u.value = (x); (hx) = gh_u.parts.msw; } while (0);
 return (int)((__uint32_t)((hx&0x7fffffff)-0x7ff00000)>>31);
}

   GCC's target independent code expands the 64-bit move into four 16-bit
moves:

;; Function finite (finite)


;; Generating RTL for tree basic block 2

;; gh_u.value = x
(note 19 18 24 ("../../../../../../../cvssrc/gcc/newlib/libm/common/s_finite.c") 31)

(insn 24 19 20 (clobber (subreg:DF (reg/v:DI 20 [ gh_u ]) 0)) -1 (nil)
    (nil))

(insn 20 24 21 (set (subreg:HI (reg/v:DI 20 [ gh_u ]) 0)
        (subreg:HI (reg/v:DF 22 [ x ]) 0)) -1 (nil)
    (nil))

(insn 21 20 22 (set (subreg:HI (reg/v:DI 20 [ gh_u ]) 2)
        (subreg:HI (reg/v:DF 22 [ x ]) 2)) -1 (nil)
    (nil))

(insn 22 21 23 (set (subreg:HI (reg/v:DI 20 [ gh_u ]) 4)
        (subreg:HI (reg/v:DF 22 [ x ]) 4)) -1 (nil)
    (nil))

(insn 23 22 0 (set (subreg:HI (reg/v:DI 20 [ gh_u ]) 6)
        (subreg:HI (reg/v:DF 22 [ x ]) 6)) -1 (nil)
    (nil))


   The patch below tries to deal with the above as well as this insn which I
didn't try to investigate further:

(insn 427 424 425 17 ../../../../../../../cvssrc/gcc/newlib/libm/math/k_cos.c:88 (clobber (subreg:SI (concatn/v:DI [
		    (reg:HI 236 [ iw_u ])
		    (reg:HI 237 [ iw_u+2 ])
		    (reg:HI 238 [ iw_u+4 ])
		    (reg:HI 239 [ iw_u+6 ])
		]) 4)) -1 (nil)
    (nil))

   With patch:

(insn 427 424 1045 17 ../../../../../../../cvssrc/gcc/newlib/libm/math/k_cos.c:88 (clobber (reg:HI 238 [ iw_u+4 ])) -1 (nil)
    (nil))

(insn 1045 427 425 17 ../../../../../../../cvssrc/gcc/newlib/libm/math/k_cos.c:88 (clobber (reg:HI 239 [ iw_u+6 ])) -1 (nil)
    (nil))

--- gcc/lower-subreg.c~	2006-12-29 02:47:18.000000000 +0100
+++ gcc/lower-subreg.c	2006-12-29 03:11:38.000000000 +0100
@@ -320,7 +320,9 @@
 static bool
 resolve_reg_p (rtx x)
 {
-  return GET_CODE (x) == CONCATN;
+  return GET_CODE (x) == CONCATN
+	 || (GET_CODE (x) == SUBREG
+	     && GET_CODE (SUBREG_REG (x)) == CONCATN);
 }
 
 /* Return whether X is a SUBREG of a register which we need to

-- 
Rask Ingemann Lambertsen


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