Patch ping. This is not a regression as I can reproduce it on GCC 4.8.* but it is an ICE on legal C code. Any chance of having it approved for 4.9?
Steve Ellcey sell...@mips.com On Thu, 2014-03-20 at 09:48 -0700, Steve Ellcey wrote: > This patch fixes pr60556, a GCC ICE. The problem is in convert_move where, > if we are trying to put a 32 bit address into a 64 bit destination we > can wind up calling emit_move_insn with NULL_RTX as a source. > > The problem comes when creating fill_value. If unsignedp is false > then we call emit_store_flag to set fill_value. If lowfrom is a symbol > reference then emit_store_flag returns NULL_RTX (because symbol references > are constant) and we wind up calling emit_move_insn with NULL_RTX as a > source and getting an ICE. > > My fix is to check for a symbol reference up where we are already > checking for memory references and force the symbol into a register > before calling emit_store_flag. This will prevent emit_store_flag > from returning NULL_RTX. In theory we could force the symbol > reference into a register only if unsignedp is false, but I think > it is cleaner to always put the symbol reference into a register. > > Tested on mips-mti-linux-gnu with no regressions. > > OK for checkin? > > Steve Ellcey > sell...@mips.com > > > 2014-03-20 Steve Ellcey <sell...@mips.com> > > PR middle-end/60556 > * expr.c (convert_move): Force symbol references into register. > > > diff --git a/gcc/expr.c b/gcc/expr.c > index be62c53..d065588 100644 > --- a/gcc/expr.c > +++ b/gcc/expr.c > @@ -533,7 +533,8 @@ convert_move (rtx to, rtx from, int unsignedp) > conversion sequence might require several references to it and we > must ensure we're getting the same value every time. */ > > - if (MEM_P (from) || reg_overlap_mentioned_p (to, from)) > + if (MEM_P (from) || GET_CODE (from) == SYMBOL_REF > + || reg_overlap_mentioned_p (to, from)) > from = force_reg (from_mode, from); > > /* Get a copy of FROM widened to a word, if necessary. */ > > > > 2014-03-20 Steve Ellcey <sell...@mips.com> > > PR middle-end/60556 > gcc.dg/pr60556.c: New. > > > diff --git a/gcc/testsuite/gcc.dg/pr60556.c b/gcc/testsuite/gcc.dg/pr60556.c > new file mode 100644 > index 0000000..3b5bbe5 > --- /dev/null > +++ b/gcc/testsuite/gcc.dg/pr60556.c > @@ -0,0 +1,7 @@ > +/* { dg-do compile } */ > +/* { dg-options "-O2" } */ > + > +int g (int); > +unsigned long long f(void) { > + return (unsigned long long)(long)&g; > +}