Patchwork [DF] fix df_find_def and df_find_use

login
register
mail settings
Submitter Steven Bosscher
Date April 10, 2013, 7:33 p.m.
Message ID <CABu31nO4_1X_sfaSpS9-0CHArEE-tm0WFa+-i=u83PPs_+ovog@mail.gmail.com>
Download mbox | patch
Permalink /patch/235457/
State New
Headers show

Comments

Steven Bosscher - April 10, 2013, 7:33 p.m.
Hello,

df_find_def and df_find_use do not work properly for hard registers
because rtx_equal_p returns false for the case where
REGNO(x)==REGNO(y) but the modes are different. This happened as
follows in my case:

Breakpoint 9, df_reg_used (insn=0x3fffb6083c50, reg=0x3fffb5eb72e0) at
../../trunk/gcc/df-core.c:1856
1856      return df_find_use (insn, reg) != NULL;
(gdb) p debug_rtx(reg)
(reg:CCX 100 %icc)
$37 = void
(gdb) p debug_rtx(insn)
(jump_insn 34 33 35 3 (set (pc)
        (if_then_else (le (reg:CCX 100 %icc)
                (const_int 0 [0]))
            (label_ref 44)
            (pc))) t.c:25 48 {*normal_branch}
     (expr_list:REG_DEAD (reg:CCX 100 %icc)
        (expr_list:REG_BR_PROB (const_int 3900 [0xf3c])
            (nil)))
 -> 44)
$38 = void
(gdb) step
df_find_use (insn=0x3fffb6083c50, reg=0x3fffb5eb72e0) at
../../trunk/gcc/df-core.c:1829
...
1837          if (rtx_equal_p (DF_REF_REAL_REG (use), reg))
(gdb) p debug_rtx(reg)
(reg:CCX 100 %icc)
$39 = void
(gdb) p debug_rtx(DF_REF_REAL_REG(use))
(reg:CC 100 %icc)
$40 = void
(gdb) p rtx_equal_p (DF_REF_REAL_REG (use), reg)
$41 = 0


I think we should just compare REGNO instead of going through rtx_equal_p.

Bootstrapped&tested on x86_64-unknown-linux-gnu.
OK for trunk?

Ciao!
Steven



        * df-core.c (df_find_def): Compare register numbers.
        (df_find_use): Compare register numbers.
Paolo Bonzini - April 11, 2013, 6:42 a.m.
Il 10/04/2013 21:33, Steven Bosscher ha scritto:
> Hello,
> 
> df_find_def and df_find_use do not work properly for hard registers
> because rtx_equal_p returns false for the case where
> REGNO(x)==REGNO(y) but the modes are different. This happened as
> follows in my case:
> 
> Breakpoint 9, df_reg_used (insn=0x3fffb6083c50, reg=0x3fffb5eb72e0) at
> ../../trunk/gcc/df-core.c:1856
> 1856      return df_find_use (insn, reg) != NULL;
> (gdb) p debug_rtx(reg)
> (reg:CCX 100 %icc)
> $37 = void
> (gdb) p debug_rtx(insn)
> (jump_insn 34 33 35 3 (set (pc)
>         (if_then_else (le (reg:CCX 100 %icc)
>                 (const_int 0 [0]))
>             (label_ref 44)
>             (pc))) t.c:25 48 {*normal_branch}
>      (expr_list:REG_DEAD (reg:CCX 100 %icc)
>         (expr_list:REG_BR_PROB (const_int 3900 [0xf3c])
>             (nil)))
>  -> 44)
> $38 = void
> (gdb) step
> df_find_use (insn=0x3fffb6083c50, reg=0x3fffb5eb72e0) at
> ../../trunk/gcc/df-core.c:1829
> ...
> 1837          if (rtx_equal_p (DF_REF_REAL_REG (use), reg))
> (gdb) p debug_rtx(reg)
> (reg:CCX 100 %icc)
> $39 = void
> (gdb) p debug_rtx(DF_REF_REAL_REG(use))
> (reg:CC 100 %icc)
> $40 = void
> (gdb) p rtx_equal_p (DF_REF_REAL_REG (use), reg)
> $41 = 0
> 
> 
> I think we should just compare REGNO instead of going through rtx_equal_p.
> 
> Bootstrapped&tested on x86_64-unknown-linux-gnu.
> OK for trunk?

Ok.  Was this with out-of-tree patches?

Paolo

> Ciao!
> Steven
> 
> 
> 
>         * df-core.c (df_find_def): Compare register numbers.
>         (df_find_use): Compare register numbers.
> 
> Index: df-core.c
> ===================================================================
> --- df-core.c   (revision 197610)
> +++ df-core.c   (working copy)
> @@ -1800,7 +1800,7 @@ df_find_def (rtx insn, rtx reg)
>    for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
>      {
>        df_ref def = *def_rec;
> -      if (rtx_equal_p (DF_REF_REAL_REG (def), reg))
> +      if (DF_REF_REGNO (def) == REGNO (reg))
>         return def;
>      }
> 
> @@ -1834,14 +1834,14 @@ df_find_use (rtx insn, rtx reg)
>    for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
>      {
>        df_ref use = *use_rec;
> -      if (rtx_equal_p (DF_REF_REAL_REG (use), reg))
> +      if (DF_REF_REGNO (use) == REGNO (reg))
>         return use;
>      }
>    if (df->changeable_flags & DF_EQ_NOTES)
>      for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++)
>        {
>         df_ref use = *use_rec;
> -       if (rtx_equal_p (DF_REF_REAL_REG (use), reg))
> +       if (DF_REF_REGNO (use) == REGNO (reg))
>           return use;
>        }
>    return NULL;
>
Steven Bosscher - April 11, 2013, 8:26 a.m.
Hello,

Thanks for the quick ok. Yes, I ran into this with out of tree patches
(my new delay slot scheduling pass, based on cfg, DF, and sched-deps).
The problem only happens with hard regs and I think that of the
existing users of these functions only the mips.c ones maybe are
buggy.

Ciao!
Steven



On 4/11/13, Paolo Bonzini <bonzini@gnu.org> wrote:
> Il 10/04/2013 21:33, Steven Bosscher ha scritto:
>> Hello,
>>
>> df_find_def and df_find_use do not work properly for hard registers
>> because rtx_equal_p returns false for the case where
>> REGNO(x)==REGNO(y) but the modes are different. This happened as
>> follows in my case:
>>
>> Breakpoint 9, df_reg_used (insn=0x3fffb6083c50, reg=0x3fffb5eb72e0) at
>> ../../trunk/gcc/df-core.c:1856
>> 1856      return df_find_use (insn, reg) != NULL;
>> (gdb) p debug_rtx(reg)
>> (reg:CCX 100 %icc)
>> $37 = void
>> (gdb) p debug_rtx(insn)
>> (jump_insn 34 33 35 3 (set (pc)
>>         (if_then_else (le (reg:CCX 100 %icc)
>>                 (const_int 0 [0]))
>>             (label_ref 44)
>>             (pc))) t.c:25 48 {*normal_branch}
>>      (expr_list:REG_DEAD (reg:CCX 100 %icc)
>>         (expr_list:REG_BR_PROB (const_int 3900 [0xf3c])
>>             (nil)))
>>  -> 44)
>> $38 = void
>> (gdb) step
>> df_find_use (insn=0x3fffb6083c50, reg=0x3fffb5eb72e0) at
>> ../../trunk/gcc/df-core.c:1829
>> ...
>> 1837          if (rtx_equal_p (DF_REF_REAL_REG (use), reg))
>> (gdb) p debug_rtx(reg)
>> (reg:CCX 100 %icc)
>> $39 = void
>> (gdb) p debug_rtx(DF_REF_REAL_REG(use))
>> (reg:CC 100 %icc)
>> $40 = void
>> (gdb) p rtx_equal_p (DF_REF_REAL_REG (use), reg)
>> $41 = 0
>>
>>
>> I think we should just compare REGNO instead of going through
>> rtx_equal_p.
>>
>> Bootstrapped&tested on x86_64-unknown-linux-gnu.
>> OK for trunk?
>
> Ok.  Was this with out-of-tree patches?
>
> Paolo
>
>> Ciao!
>> Steven
>>
>>
>>
>>         * df-core.c (df_find_def): Compare register numbers.
>>         (df_find_use): Compare register numbers.
>>
>> Index: df-core.c
>> ===================================================================
>> --- df-core.c   (revision 197610)
>> +++ df-core.c   (working copy)
>> @@ -1800,7 +1800,7 @@ df_find_def (rtx insn, rtx reg)
>>    for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
>>      {
>>        df_ref def = *def_rec;
>> -      if (rtx_equal_p (DF_REF_REAL_REG (def), reg))
>> +      if (DF_REF_REGNO (def) == REGNO (reg))
>>         return def;
>>      }
>>
>> @@ -1834,14 +1834,14 @@ df_find_use (rtx insn, rtx reg)
>>    for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
>>      {
>>        df_ref use = *use_rec;
>> -      if (rtx_equal_p (DF_REF_REAL_REG (use), reg))
>> +      if (DF_REF_REGNO (use) == REGNO (reg))
>>         return use;
>>      }
>>    if (df->changeable_flags & DF_EQ_NOTES)
>>      for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++)
>>        {
>>         df_ref use = *use_rec;
>> -       if (rtx_equal_p (DF_REF_REAL_REG (use), reg))
>> +       if (DF_REF_REGNO (use) == REGNO (reg))
>>           return use;
>>        }
>>    return NULL;
>>
>
>

Patch

Index: df-core.c
===================================================================
--- df-core.c   (revision 197610)
+++ df-core.c   (working copy)
@@ -1800,7 +1800,7 @@  df_find_def (rtx insn, rtx reg)
   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
     {
       df_ref def = *def_rec;
-      if (rtx_equal_p (DF_REF_REAL_REG (def), reg))
+      if (DF_REF_REGNO (def) == REGNO (reg))
        return def;
     }

@@ -1834,14 +1834,14 @@  df_find_use (rtx insn, rtx reg)
   for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
     {
       df_ref use = *use_rec;
-      if (rtx_equal_p (DF_REF_REAL_REG (use), reg))
+      if (DF_REF_REGNO (use) == REGNO (reg))
        return use;
     }
   if (df->changeable_flags & DF_EQ_NOTES)
     for (use_rec = DF_INSN_UID_EQ_USES (uid); *use_rec; use_rec++)
       {
        df_ref use = *use_rec;
-       if (rtx_equal_p (DF_REF_REAL_REG (use), reg))
+       if (DF_REF_REGNO (use) == REGNO (reg))
          return use;
       }
   return NULL;