Patchwork =?windows-1252?Q?Re=3A_PATCH=3A_PR_middle=2Dend=2F47449=3A_=5Bx32=5D_can=92t_find_a?= =?windows-1252?Q?_register_in_class_=91DIREG=92_while_reloading_=91asm=92?=

login
register
mail settings
Submitter H.J. Lu
Date Jan. 25, 2011, 4:08 a.m.
Message ID <AANLkTinFWdubjtoe1JLOBcRj=Z-qOC9RjsWEq9aZitqd@mail.gmail.com>
Download mbox | patch
Permalink /patch/80309/
State New
Headers show

Comments

H.J. Lu - Jan. 25, 2011, 4:08 a.m.
On Mon, Jan 24, 2011 at 7:54 PM, Paolo Bonzini <bonzini@gnu.org> wrote:
> On 01/25/2011 04:50 AM, H.J. Lu wrote:
>>
>>   /* If this is a paradoxical SUBREG...  */
>>   if (GET_MODE_SIZE (use_mode)
>>       >  GET_MODE_SIZE (GET_MODE (SUBREG_REG (use_reg))))
>>     {
>>       /* If this is a paradoxical SUBREG, we have no idea what value the
>>          extra bits would have.  However, if the operand is equivalent to
>>          a SUBREG whose operand is the same as our mode, and all the modes
>>          are within a word, we can just use the inner operand because
>>          these SUBREGs just say how to treat the register.  */
>>       use_insn = DF_REF_INSN (use);
>>       src = SET_SRC (def_set);
>>       if (GET_CODE (src) == SUBREG
>>           &&  REG_P (SUBREG_REG (src))
>>           &&  GET_MODE (SUBREG_REG (src)) == use_mode
>>           &&  subreg_lowpart_p (src)
>>           &&  all_uses_available_at (def_insn, use_insn))
>>         return try_fwprop_subst (use, DF_REF_LOC (use), SUBREG_REG (src),
>>                                  def_insn, false);
>>     }
>>
>> Should it check hard registers?
>
> Yes.

Here is a new patch.  OK for trunk and 4.5?

Thanks.

Patch

diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 7ff5135..67ef93c 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -1101,6 +1101,7 @@  forward_propagate_subreg (df_ref use, rtx
def_insn, rtx def_set)
       src = SET_SRC (def_set);
       if (GET_CODE (src) == SUBREG
 	  && REG_P (SUBREG_REG (src))
+	  && REGNO (SUBREG_REG (src)) >= FIRST_PSEUDO_REGISTER
 	  && GET_MODE (SUBREG_REG (src)) == use_mode
 	  && subreg_lowpart_p (src)
 	  && all_uses_available_at (def_insn, use_insn))
@@ -1119,6 +1120,7 @@  forward_propagate_subreg (df_ref use, rtx
def_insn, rtx def_set)
       if ((GET_CODE (src) == ZERO_EXTEND
 	   || GET_CODE (src) == SIGN_EXTEND)
 	  && REG_P (XEXP (src, 0))
+	  && REGNO (XEXP (src, 0)) >= FIRST_PSEUDO_REGISTER
 	  && GET_MODE (XEXP (src, 0)) == use_mode
 	  && !free_load_extend (src, def_insn)
 	  && all_uses_available_at (def_insn, use_insn))
diff --git a/gcc/testsuite/gcc.target/i386/pr47449.c
b/gcc/testsuite/gcc.target/i386/pr47449.c
new file mode 100644
index 0000000..99ef32f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr47449.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void bar (void *, void *);
+int
+foo (void *p1, void *p2)
+{
+  int ret1, ret2;
+  __asm ("" : "=D" (ret1), "=S" (ret2));
+  bar (p1, p2);
+  return ret1 + ret2;
+}