Message ID | 20140411090755.GQ1817@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On Fri, 11 Apr 2014, Jakub Jelinek wrote: > On Thu, Mar 20, 2014 at 09:48:58AM -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. > > I think the right fix is instead to use emit_store_flag_force, that will > force into register only when necessary, and will do so even in the numerous > other cases when emit_store_flag may return NULL (LABEL_REF, other > constants, different branch costs, etc.). > > Will bootstrap/regtest this on x86_64-linux and i686-linux, Steve, can you > please test on mips? Ok for trunk if testing passes? Ok. Thanks, Richard. > 2014-04-11 Steve Ellcey <sellcey@mips.com> > Jakub Jelinek <jakub@redhat.com> > > PR middle-end/60556 > * expr.c (convert_move): Use emit_store_flag_force instead of > emit_store_flag. Pass lowpart_mode instead of VOIDmode as 5th > argument to it. > > * gcc.c-torture/compile/pr60556.c: New test. > > --- gcc/expr.c.jj 2014-03-28 23:06:44.000000000 +0100 > +++ gcc/expr.c 2014-04-11 10:59:24.664014557 +0200 > @@ -551,9 +551,9 @@ convert_move (rtx to, rtx from, int unsi > if (unsignedp) > fill_value = const0_rtx; > else > - fill_value = emit_store_flag (gen_reg_rtx (word_mode), > - LT, lowfrom, const0_rtx, > - VOIDmode, 0, -1); > + fill_value = emit_store_flag_force (gen_reg_rtx (word_mode), > + LT, lowfrom, const0_rtx, > + lowpart_mode, 0, -1); > > /* Fill the remaining words. */ > for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++) > --- gcc/testsuite/gcc.c-torture/compile/pr60556.c.jj 2014-04-11 11:01:53.535218278 +0200 > +++ gcc/testsuite/gcc.c-torture/compile/pr60556.c 2014-04-11 11:01:53.535218278 +0200 > @@ -0,0 +1,8 @@ > +/* PR middle-end/60556 */ > + > +int g (int); > + > +unsigned long long f (void) > +{ > + return (unsigned long long)(long)&g; > +}
--- gcc/expr.c.jj 2014-03-28 23:06:44.000000000 +0100 +++ gcc/expr.c 2014-04-11 10:59:24.664014557 +0200 @@ -551,9 +551,9 @@ convert_move (rtx to, rtx from, int unsi if (unsignedp) fill_value = const0_rtx; else - fill_value = emit_store_flag (gen_reg_rtx (word_mode), - LT, lowfrom, const0_rtx, - VOIDmode, 0, -1); + fill_value = emit_store_flag_force (gen_reg_rtx (word_mode), + LT, lowfrom, const0_rtx, + lowpart_mode, 0, -1); /* Fill the remaining words. */ for (i = GET_MODE_SIZE (lowpart_mode) / UNITS_PER_WORD; i < nwords; i++) --- gcc/testsuite/gcc.c-torture/compile/pr60556.c.jj 2014-04-11 11:01:53.535218278 +0200 +++ gcc/testsuite/gcc.c-torture/compile/pr60556.c 2014-04-11 11:01:53.535218278 +0200 @@ -0,0 +1,8 @@ +/* PR middle-end/60556 */ + +int g (int); + +unsigned long long f (void) +{ + return (unsigned long long)(long)&g; +}