From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7617 invoked by alias); 28 Jun 2011 14:49:24 -0000 Received: (qmail 7605 invoked by uid 22791); 28 Jun 2011 14:49:22 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW X-Spam-Check-By: sourceware.org Received: from mail-qy0-f175.google.com (HELO mail-qy0-f175.google.com) (209.85.216.175) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 28 Jun 2011 14:49:04 +0000 Received: by qyk30 with SMTP id 30so1999312qyk.20 for ; Tue, 28 Jun 2011 07:49:03 -0700 (PDT) MIME-Version: 1.0 Received: by 10.229.98.206 with SMTP id r14mr1581421qcn.18.1309272543816; Tue, 28 Jun 2011 07:49:03 -0700 (PDT) Received: by 10.229.214.83 with HTTP; Tue, 28 Jun 2011 07:49:03 -0700 (PDT) In-Reply-To: References: <201106281424.p5SEONuw027532@d06av02.portsmouth.uk.ibm.com> Date: Tue, 28 Jun 2011 15:19:00 -0000 Message-ID: Subject: Re: PATCH [10/n]: Prepare x32: PR rtl-optimization/49114: Reload failed to handle (set reg:X (plus:X (subreg:X (reg:Y) 0) (const From: "H.J. Lu" To: Ulrich Weigand Cc: gcc-patches@gcc.gnu.org, bernds@codesourcery.com Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-06/txt/msg02142.txt.bz2 On Tue, Jun 28, 2011 at 7:47 AM, H.J. Lu wrote: > On Tue, Jun 28, 2011 at 7:24 AM, Ulrich Weigand wro= te: >> H.J. Lu wrote: >>> > find_replacement never checks subreg: >>> > >>> > Breakpoint 3, find_replacement (loc=3D3D0x7ffff068ab00) >>> > =3DA0 =3DA0at /export/gnu/import/git/gcc-x32/gcc/reload.c:6411 >>> > 6411 =3DA0 =3DA0 =3DA0 =3DA0 =3DA0if (reloadreg && r->where =3D3D=3D3= D loc) >>> > (reg:DI 0 ax) >>> > (reg/v/f:DI 182 [ b ]) >>> > (gdb) call debug_rtx (*loc) >>> > (subreg:SI (reg/v/f:DI 182 [ b ]) 0) >>> > (gdb) >>> > >>> >>> This seems to work. =A0Does it make any senses? >> >> Ah, I see. =A0This was supposed to be handled via the SUBREG_LOC >> member of the replacement struct. =A0Unfortunately, it turns out >> that this is no longer reliably set these days ... >> >> At first I was concerned that this might also cause problems at >> the other location where replacements are processed, subst_reloads. >> However, it turns out that code in subst_reloads is dead these days >> anyway, as the reloadreg is *always* a REG, and never a SUBREG. >> >> Once that code (and similar code in find_replacement that tries >> to handle SUBREG reloadregs) is removed, the only remaining user >> of the SUBREG_LOC field is actually find_replacement. =A0But here >> we're doing a recursive descent through an RTL anyway, so we >> always know we're replacing inside a SUBREG. >> >> This makes the whole SUBREG_LOC field obsolete. >> >> The patch below implements those changes (untested so far). >> Can you verify that this works for you as well? >> >> Thanks, >> Ulrich >> >> >> ChangeLog: >> >> =A0 =A0 =A0 =A0* reload.c (struct replacement): Remove SUBREG_LOC member. >> =A0 =A0 =A0 =A0(push_reload): Do not set it. >> =A0 =A0 =A0 =A0(push_replacement): Likewise. >> =A0 =A0 =A0 =A0(subst_reload): Remove dead code. >> =A0 =A0 =A0 =A0(copy_replacements): Remove assertion. >> =A0 =A0 =A0 =A0(copy_replacements_1): Do not handle SUBREG_LOC. >> =A0 =A0 =A0 =A0(move_replacements): Likewise. >> =A0 =A0 =A0 =A0(find_replacement): Remove dead code. =A0Detect subregs v= ia >> =A0 =A0 =A0 =A0recursive descent instead of via SUBREG_LOC. >> >> Index: gcc/reload.c >> =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D >> *** gcc/reload.c =A0 =A0 =A0 =A0(revision 175580) >> --- gcc/reload.c =A0 =A0 =A0 =A0(working copy) >> *************** static int replace_reloads; >> *** 158,165 **** >> =A0struct replacement >> =A0{ >> =A0 =A0rtx *where; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* Location to store = in */ >> - =A0 rtx *subreg_loc; =A0 =A0 =A0 =A0 =A0 =A0/* Location of SUBREG if W= HERE is inside >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0a S= UBREG; 0 otherwise. =A0*/ >> =A0 =A0int what; =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* which reload thi= s is for */ >> =A0 =A0enum machine_mode mode; =A0 =A0 /* mode it must have */ >> =A0}; >> --- 158,163 ---- >> *************** push_reload (rtx in, rtx out, rtx *inloc >> *** 1496,1502 **** >> =A0 =A0 =A0 =A0{ >> =A0 =A0 =A0 =A0 =A0struct replacement *r =3D &replacements[n_replacement= s++]; >> =A0 =A0 =A0 =A0 =A0r->what =3D i; >> - =A0 =A0 =A0 =A0 r->subreg_loc =3D in_subreg_loc; >> =A0 =A0 =A0 =A0 =A0r->where =3D inloc; >> =A0 =A0 =A0 =A0 =A0r->mode =3D inmode; >> =A0 =A0 =A0 =A0} >> --- 1494,1499 ---- >> *************** push_reload (rtx in, rtx out, rtx *inloc >> *** 1505,1511 **** >> =A0 =A0 =A0 =A0 =A0struct replacement *r =3D &replacements[n_replacement= s++]; >> =A0 =A0 =A0 =A0 =A0r->what =3D i; >> =A0 =A0 =A0 =A0 =A0r->where =3D outloc; >> - =A0 =A0 =A0 =A0 r->subreg_loc =3D out_subreg_loc; >> =A0 =A0 =A0 =A0 =A0r->mode =3D outmode; >> =A0 =A0 =A0 =A0} >> =A0 =A0 =A0} >> --- 1502,1507 ---- >> *************** push_replacement (rtx *loc, int reloadnu >> *** 1634,1640 **** >> =A0 =A0 =A0 =A0struct replacement *r =3D &replacements[n_replacements++]; >> =A0 =A0 =A0 =A0r->what =3D reloadnum; >> =A0 =A0 =A0 =A0r->where =3D loc; >> - =A0 =A0 =A0 r->subreg_loc =3D 0; >> =A0 =A0 =A0 =A0r->mode =3D mode; >> =A0 =A0 =A0} >> =A0} >> --- 1630,1635 ---- >> *************** subst_reloads (rtx insn) >> *** 6287,6319 **** >> =A0 =A0 =A0 =A0 =A0if (GET_MODE (reloadreg) !=3D r->mode && r->mode !=3D= VOIDmode) >> =A0 =A0 =A0 =A0 =A0 =A0reloadreg =3D reload_adjust_reg_for_mode (reloadr= eg, r->mode); >> >> ! =A0 =A0 =A0 =A0 /* If we are putting this into a SUBREG and RELOADREG = is a >> ! =A0 =A0 =A0 =A0 =A0 =A0SUBREG, we would be making nested SUBREGs, so w= e have to fix >> ! =A0 =A0 =A0 =A0 =A0 =A0this up. =A0Note that r->where =3D=3D &SUBREG_R= EG (*r->subreg_loc). =A0*/ >> ! >> ! =A0 =A0 =A0 =A0 if (r->subreg_loc !=3D 0 && GET_CODE (reloadreg) =3D= =3D SUBREG) >> ! =A0 =A0 =A0 =A0 =A0 { >> ! =A0 =A0 =A0 =A0 =A0 =A0 if (GET_MODE (*r->subreg_loc) >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =3D=3D GET_MODE (SUBREG_REG (reloadreg= ))) >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 *r->subreg_loc =3D SUBREG_REG (reloadreg); >> ! =A0 =A0 =A0 =A0 =A0 =A0 else >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 { >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 int final_offset =3D >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 SUBREG_BYTE (*r->subreg_loc) + SUB= REG_BYTE (reloadreg); >> ! >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 /* When working with SUBREGs the rule = is that the byte >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0offset must be a multiple of th= e SUBREG's mode. =A0*/ >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 final_offset =3D (final_offset / >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GET_MO= DE_SIZE (GET_MODE (*r->subreg_loc))); >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 final_offset =3D (final_offset * >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 GET_MO= DE_SIZE (GET_MODE (*r->subreg_loc))); >> ! >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 *r->where =3D SUBREG_REG (reloadreg); >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 SUBREG_BYTE (*r->subreg_loc) =3D final= _offset; >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 } >> ! =A0 =A0 =A0 =A0 =A0 } >> ! =A0 =A0 =A0 =A0 else >> ! =A0 =A0 =A0 =A0 =A0 *r->where =3D reloadreg; >> =A0 =A0 =A0 =A0} >> =A0 =A0 =A0 =A0/* If reload got no reg and isn't optional, something's w= rong. =A0*/ >> =A0 =A0 =A0 =A0else >> --- 6282,6288 ---- >> =A0 =A0 =A0 =A0 =A0if (GET_MODE (reloadreg) !=3D r->mode && r->mode !=3D= VOIDmode) >> =A0 =A0 =A0 =A0 =A0 =A0reloadreg =3D reload_adjust_reg_for_mode (reloadr= eg, r->mode); >> >> ! =A0 =A0 =A0 =A0 *r->where =3D reloadreg; >> =A0 =A0 =A0 =A0} >> =A0 =A0 =A0 =A0/* If reload got no reg and isn't optional, something's w= rong. =A0*/ >> =A0 =A0 =A0 =A0else >> *************** subst_reloads (rtx insn) >> *** 6327,6336 **** >> =A0void >> =A0copy_replacements (rtx x, rtx y) >> =A0{ >> - =A0 /* We can't support X being a SUBREG because we might then need to= know its >> - =A0 =A0 =A0location if something inside it was replaced. =A0*/ >> - =A0 gcc_assert (GET_CODE (x) !=3D SUBREG); >> - >> =A0 =A0copy_replacements_1 (&x, &y, n_replacements); >> =A0} >> >> --- 6296,6301 ---- >> *************** copy_replacements_1 (rtx *px, rtx *py, i >> *** 6344,6367 **** >> =A0 =A0const char *fmt; >> >> =A0 =A0for (j =3D 0; j < orig_replacements; j++) >> ! =A0 =A0 { >> ! =A0 =A0 =A0 if (replacements[j].subreg_loc =3D=3D px) >> ! =A0 =A0 =A0 { >> ! =A0 =A0 =A0 =A0 r =3D &replacements[n_replacements++]; >> ! =A0 =A0 =A0 =A0 r->where =3D replacements[j].where; >> ! =A0 =A0 =A0 =A0 r->subreg_loc =3D py; >> ! =A0 =A0 =A0 =A0 r->what =3D replacements[j].what; >> ! =A0 =A0 =A0 =A0 r->mode =3D replacements[j].mode; >> ! =A0 =A0 =A0 } >> ! =A0 =A0 =A0 else if (replacements[j].where =3D=3D px) >> ! =A0 =A0 =A0 { >> ! =A0 =A0 =A0 =A0 r =3D &replacements[n_replacements++]; >> ! =A0 =A0 =A0 =A0 r->where =3D py; >> ! =A0 =A0 =A0 =A0 r->subreg_loc =3D 0; >> ! =A0 =A0 =A0 =A0 r->what =3D replacements[j].what; >> ! =A0 =A0 =A0 =A0 r->mode =3D replacements[j].mode; >> ! =A0 =A0 =A0 } >> ! =A0 =A0 } >> >> =A0 =A0x =3D *px; >> =A0 =A0y =3D *py; >> --- 6309,6321 ---- >> =A0 =A0const char *fmt; >> >> =A0 =A0for (j =3D 0; j < orig_replacements; j++) >> ! =A0 =A0 if (replacements[j].where =3D=3D px) >> ! =A0 =A0 =A0 { >> ! =A0 =A0 =A0 r =3D &replacements[n_replacements++]; >> ! =A0 =A0 =A0 r->where =3D py; >> ! =A0 =A0 =A0 r->what =3D replacements[j].what; >> ! =A0 =A0 =A0 r->mode =3D replacements[j].mode; >> ! =A0 =A0 =A0 } >> >> =A0 =A0x =3D *px; >> =A0 =A0y =3D *py; >> *************** move_replacements (rtx *x, rtx *y) >> *** 6387,6399 **** >> =A0 =A0int i; >> >> =A0 =A0for (i =3D 0; i < n_replacements; i++) >> ! =A0 =A0 if (replacements[i].subreg_loc =3D=3D x) >> ! =A0 =A0 =A0 replacements[i].subreg_loc =3D y; >> ! =A0 =A0 else if (replacements[i].where =3D=3D x) >> ! =A0 =A0 =A0 { >> ! =A0 =A0 =A0 replacements[i].where =3D y; >> ! =A0 =A0 =A0 replacements[i].subreg_loc =3D 0; >> ! =A0 =A0 =A0 } >> =A0} >> >> =A0/* If LOC was scheduled to be replaced by something, return the repla= cement. >> --- 6341,6348 ---- >> =A0 =A0int i; >> >> =A0 =A0for (i =3D 0; i < n_replacements; i++) >> ! =A0 =A0 if (replacements[i].where =3D=3D x) >> ! =A0 =A0 =A0 replacements[i].where =3D y; >> =A0} >> >> =A0/* If LOC was scheduled to be replaced by something, return the repla= cement. >> *************** find_replacement (rtx *loc) >> *** 6415,6446 **** >> >> =A0 =A0 =A0 =A0 =A0return reloadreg; >> =A0 =A0 =A0 =A0} >> ! =A0 =A0 =A0 else if (reloadreg && r->subreg_loc =3D=3D loc) >> =A0 =A0 =A0 =A0{ >> ! =A0 =A0 =A0 =A0 /* RELOADREG must be either a REG or a SUBREG. >> ! >> ! =A0 =A0 =A0 =A0 =A0 =A0??? Is it actually still ever a SUBREG? =A0If s= o, why? =A0*/ >> ! >> ! =A0 =A0 =A0 =A0 if (REG_P (reloadreg)) >> ! =A0 =A0 =A0 =A0 =A0 return gen_rtx_REG (GET_MODE (*loc), >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (REGNO (re= loadreg) + >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0subreg_= regno_offset (REGNO (SUBREG_REG (*loc)), >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0GET_MODE (SUBREG_REG (*loc)), >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0SUBREG_BYTE (*loc), >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0GET_MODE (*loc)))); >> - =A0 =A0 =A0 =A0 else if (GET_MODE (reloadreg) =3D=3D GET_MODE (*loc)) >> - =A0 =A0 =A0 =A0 =A0 return reloadreg; >> - =A0 =A0 =A0 =A0 else >> - =A0 =A0 =A0 =A0 =A0 { >> - =A0 =A0 =A0 =A0 =A0 =A0 int final_offset =3D SUBREG_BYTE (reloadreg) += SUBREG_BYTE (*loc); >> - >> - =A0 =A0 =A0 =A0 =A0 =A0 /* When working with SUBREGs the rule is that = the byte >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0offset must be a multiple of the SUBREG= 's mode. =A0*/ >> - =A0 =A0 =A0 =A0 =A0 =A0 final_offset =3D (final_offset / GET_MODE_SIZE= (GET_MODE (*loc))); >> - =A0 =A0 =A0 =A0 =A0 =A0 final_offset =3D (final_offset * GET_MODE_SIZE= (GET_MODE (*loc))); >> - =A0 =A0 =A0 =A0 =A0 =A0 return gen_rtx_SUBREG (GET_MODE (*loc), SUBREG= _REG (reloadreg), >> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0final_offset); >> - =A0 =A0 =A0 =A0 =A0 } >> =A0 =A0 =A0 =A0} >> =A0 =A0 =A0} >> >> --- 6364,6378 ---- >> >> =A0 =A0 =A0 =A0 =A0return reloadreg; >> =A0 =A0 =A0 =A0} >> ! =A0 =A0 =A0 else if (reloadreg && GET_CODE (*loc) =3D=3D SUBREG >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0&& r->where =3D=3D &SUBREG_REG (*loc)) >> =A0 =A0 =A0 =A0{ >> ! =A0 =A0 =A0 =A0 return gen_rtx_REG (GET_MODE (*loc), >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 (REGNO (reload= reg) >> ! =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0+ subreg_re= gno_offset (REGNO (SUBREG_REG (*loc)), >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0GET_MODE (SUBREG_REG (*loc)), >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0SUBREG_BYTE (*loc), >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 = =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0GET_MODE (*loc)))); >> =A0 =A0 =A0 =A0} >> =A0 =A0 =A0} >> >> >> -- >> =A0Dr. Ulrich Weigand >> =A0GNU Toolchain for Linux on System z and Cell BE >> =A0Ulrich.Weigand@de.ibm.com >> > > it doesn't work; > > allocation.f: In function 'allocation': > allocation.f:1048:0: internal compiler error: in subreg_get_info, at > rtlanal.c:3235 > Please submit a full bug report, > with preprocessed source if appropriate. > See for instructions. > > (gdb) bt > #0 =A0fancy_abort (file=3D0xe7d920 "/export/gnu/import/git/gcc-x32/gcc/rt= lanal.c", > =A0 =A0line=3D3235, function=3D0xe7d8c0 "subreg_get_info") > =A0 =A0at /export/gnu/import/git/gcc-x32/gcc/diagnostic.c:892 > #1 =A00x0000000000888c8e in subreg_get_info (xregno=3D, > =A0 =A0xmode=3D, offset=3D0, ymode=3D, > =A0 =A0info=3D) at /export/gnu/import/git/gcc-x32/gcc/rtla= nal.c:3235 > #2 =A00x0000000000888d4c in subreg_regno_offset (xregno=3D, > =A0 =A0xmode=3D, offset=3D, ymode=3D) > =A0 =A0at /export/gnu/import/git/gcc-x32/gcc/rtlanal.c:3387 > #3 =A00x0000000000868546 in find_replacement (loc=3D0x7ffff063ee80) > =A0 =A0at /export/gnu/import/git/gcc-x32/gcc/reload.c:6372 > #4 =A00x00000000008685b8 in find_replacement (loc=3D0x7ffff063ba48) > =A0 =A0at /export/gnu/import/git/gcc-x32/gcc/reload.c:6385 > #5 =A00x0000000000877182 in gen_reload (out=3D0x7ffff062be80, in=3D0x7fff= f063ba40, > =A0 =A0opnum=3D0, type=3DRELOAD_FOR_OPERAND_ADDRESS) > =A0 =A0at /export/gnu/import/git/gcc-x32/gcc/reload1.c:8599 > > since subreg_regno_offset only works on hard registers. > + int offset; + + if (r->mode !=3D VOIDmode && GET_MODE (reloadreg) !=3D r->mode) + reloadreg =3D gen_rtx_REG (r->mode, REGNO (reloadreg)); + + if ((WORDS_BIG_ENDIAN || BYTES_BIG_ENDIAN) + && GET_MODE_SIZE (Pmode) > GET_MODE_SIZE (ptr_mode)) + { + offset =3D GET_MODE_SIZE (Pmode) - GET_MODE_SIZE (ptr_mode); + if (! BYTES_BIG_ENDIAN) + offset =3D (offset / UNITS_PER_WORD) * UNITS_PER_WORD; + else if (! WORDS_BIG_ENDIAN) + offset %=3D UNITS_PER_WORD; + } + else + offset =3D 0; + + return gen_rtx_SUBREG (ptr_mode, reloadreg, offset); works for me. --=20 H.J.