Ping 2, and pasted my observation about this ICE, and may someone can help?

The main cause for the ICE is in the function symtab_get_node:

  gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL
                       || (TREE_CODE (decl) == VAR_DECL
                           && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
                               || in_lto_p)));

It's a check for the tree attribute for VAR_DECL, but as the register type 
variable is neither static nor
external(not sure if this is correct), the compiler will raise ICE here, but in 
function
make_decl_rtl(gcc/varasm.c:1357), there's one line comment:

                globalize_reg (decl, reg_number + --nregs);
            }

          /* As a register variable, it has no section.  */
          return;
        }

And for the correct register type declaration like: register int *a asm("r1"), 
the program will just directly
return(gcc/varasm.c:1358), and won't sink into the symbol ref generation part. 
So symtab_get_node won't be
called.

Currently invalid register type declaration will always sink into the symbol 
ref generation part of function
make_decl_rtl, which will also lead to wrong rtx generation.
register int *a asm("r1")=>(reg:SI 1 r1 [orig:0 a] [0])
register int *a asm("unknown register")=>(symbol_ref:SI ("unknown register") 
[flag 0x80])

Also the reason that x86 wont't have sunch an ICE is in the code:

if (use_object_blocks_p () && use_blocks_for_decl_p (decl))
    x = create_block_symbol (name, get_block_for_decl (decl), -1);

function use_object_blocks_p will always return false on target doesn't support 
section anchor, so function
get_block_for_decl which will call symtab_get_node will never be called.

This patch just move the else condition in  make_decl_rtl to make all register 
type declaration to get the
same rtx, it this a reasonable fix?

> -----Original Message-----
> From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-ow...@gcc.gnu.org] On 
> Behalf Of Tony Wang
> Sent: Tuesday, August 05, 2014 9:35 AM
> To: gcc-patches@gcc.gnu.org
> Cc: 'Richard Biener'; 'Jakub Jelinek'
> Subject: [PING][Patch]Fix ICE for gcc.dg/noncompile/920507-1.c
> 
> Ping, any comment and suggestion on this bug fix?
> 
> > -----Original Message-----
> > From: gcc-patches-ow...@gcc.gnu.org [mailto:gcc-patches-
> > ow...@gcc.gnu.org] On Behalf Of Tony Wang
> > Sent: Tuesday, July 29, 2014 10:31 AM
> > To: gcc-patches@gcc.gnu.org; 'Richard Biener'; 'Jakub Jelinek'
> > Subject: [Patch]Fix ICE for gcc.dg/noncompile/920507-1.c
> >
> > Hi there,
> >
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61330.
> > There will be an ICE in gcc trunk for targets support section anchor
> > optimization when compiling this case(like arm and mips). This looks like
> an
> 
> The target should be aarch64, arm, powerpc, alpha
> 
> > old bug which is exposed by recent patch.
> >
> > In make_decl_rtl, when you declare register type incorrectly like
> "register int
> > *a asm("unknown register");", the compiler will raise an error messge but
> > doesn't return directly. It will continue to run into the rtx generation
> code for
> > general variable declaration and generate a wrong rtx:(symbol_ref:SI...).
> So I
> > just remove the else condition which used to be the rtx generation part
> for
> > correctly declared register type, and let all the register type
> declaration(no
> > matter it declared correct or not) go through it and generate the same
> type
> > of rtx:(reg:SI...).
> >
> > gcc/ChangeLog:
> >
> > 2014-07-29  Tony Wang  tony.w...@arm.com
> >
> >         * gcc/varasm.c (make_decl_rtl): Remove the else condition
> >           for properly declared static register variables.
> >
> > diff --git a/gcc/varasm.c b/gcc/varasm.c index 819ec26..a6fae0c 100644
> > --- a/gcc/varasm.c
> > +++ b/gcc/varasm.c
> > @@ -1333,45 +1333,42 @@ make_decl_rtl (tree decl)
> >                error ("register specified for %q+D isn%'t suitable for
> data type",
> >                 decl);
> >        /* Now handle properly declared static register variables.  */
> > -      else
> > -              {
> > -                int nregs;
> > +      int nregs;
> >
> > -                if (DECL_INITIAL (decl) != 0 && TREE_STATIC (decl))
> > -                  {
> > -                    DECL_INITIAL (decl) = 0;
> > -                    error ("global register variable has initial value");
> > -                  }
> > -                if (TREE_THIS_VOLATILE (decl))
> > -                  warning (OPT_Wvolatile_register_var,
> > -                                   "optimization may eliminate reads 
> > and/or"
> > -                                   "writes to register variables");
> > +      if (DECL_INITIAL (decl) != 0 && TREE_STATIC (decl))
> > +        {
> > +           DECL_INITIAL (decl) = 0;
> > +           error ("global register variable has initial value");
> > +        }
> > +      if (TREE_THIS_VOLATILE (decl))
> > +        warning (OPT_Wvolatile_register_var,
> > +                 "optimization may eliminate reads and/or "
> > +                      "writes to register variables");
> >
> > -                /* If the user specified one of the eliminables 
> > registershere,
> > -                   e.g., FRAME_POINTER_REGNUM, we don't want to get this 
> > variable
> > -                   confused with that register and be eliminated.  This 
> > usage is
> > -                   somewhat suspect...  */
> > +      /* If the user specified one of the eliminables registers here,
> > +         e.g., FRAME_POINTER_REGNUM, we don't want to get this variable
> > +         confused with that register and be eliminated.  This usage is
> > +         somewhat suspect...  */
> >
> > -                SET_DECL_RTL (decl, gen_rtx_raw_REG (mode, reg_number));
> > -                ORIGINAL_REGNO (DECL_RTL (decl)) = reg_number;
> > -                REG_USERVAR_P (DECL_RTL (decl)) = 1;
> > +      SET_DECL_RTL (decl, gen_rtx_raw_REG (mode, reg_number));
> > +      ORIGINAL_REGNO (DECL_RTL (decl)) = reg_number;
> > +      REG_USERVAR_P (DECL_RTL (decl)) = 1;
> >
> > -                if (TREE_STATIC (decl))
> > -                  {
> > -                    /* Make this register global, so not usable for 
> > anything
> > -                              else.  */
> > +      if (TREE_STATIC (decl))
> > +        {
> > +          /* Make this register global, so not usable for anything
> > +             else.  */
> > #ifdef ASM_DECLARE_REGISTER_GLOBAL
> > -                    name = IDENTIFIER_POINTER (DECL_NAME (decl));
> > -                    ASM_DECLARE_REGISTER_GLOBAL (asm_out_file, decl, 
> > reg_number, name);
> > +          name = IDENTIFIER_POINTER (DECL_NAME (decl));
> > +          ASM_DECLARE_REGISTER_GLOBAL (asm_out_file, decl, reg_number, 
> > name);
> > #endif
> > -                    nregs = hard_regno_nregs[reg_number][mode];
> > -                    while (nregs > 0)
> > -                              globalize_reg (decl, reg_number + --nregs);
> > -                  }
> > +          nregs = hard_regno_nregs[reg_number][mode];
> > +          while (nregs > 0)
> > +            globalize_reg (decl, reg_number + --nregs);
> > +        }
> >
> > -                /* As a register variable, it has no section.  */
> > -                return;
> > -              }
> > +      /* As a register variable, it has no section.  */
> > +      return;
> >      }
> >    /* Now handle ordinary static variables and functions (in memory).
> >       Also handle vars declared register invalidly.  */
> >
> > BR,
> > Tony
> 
> 

Attachment: 920507.diff
Description: Binary data

Reply via email to