This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH RFC: My version of the lower-subreg patch
- From: Rask Ingemann Lambertsen <rask at sygehus dot dk>
- To: Ian Lance Taylor <iant at google dot com>
- Cc: gcc-patches at gcc dot gnu dot org, rth at redhat dot com
- Date: Fri, 29 Dec 2006 04:32:41 +0100
- Subject: Re: PATCH RFC: My version of the lower-subreg patch
- References: <m3wt4segt6.fsf@localhost.localdomain>
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