On Wed, 14 Mar 2018, Jakub Jelinek wrote: > Hi! > > prepare_cmp_insn in some cases changes both the passed in comparison and the > comparison mode, e.g. by promoting the arguments from SFmode to DFmode etc. > > In emit_conditional_move we call this in a loop, for (pass = 0; pass < 2; > pass++) > and in each case construct comparison arguments as well as the comparison > passed to it from the original arguments (we have to after all, because when > not successful, we throw the whole insn sequence away), but use cmode which > the first iteration could have changed, on this testcase on powerpcspe with > -mcpu=8548 from SFmode to DFmode, so we ICE the second time, because the > arguments don't really match the comparison mode. > > Fixed by passing it an address of a copy of the cmode parameter, so that the > second pass starts with the original cmode that matches the arguments again. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok. Richard. > 2018-03-14 Jakub Jelinek <ja...@redhat.com> > > PR target/84860 > * optabs.c (emit_conditional_move): Pass address of cmode's copy > rather than address of cmode as last argument to prepare_cmp_insn. > > * gcc.c-torture/compile/pr84860.c: New test. > > --- gcc/optabs.c.jj 2018-02-09 19:11:29.000000000 +0100 > +++ gcc/optabs.c 2018-03-14 09:22:31.707873477 +0100 > @@ -4345,9 +4345,10 @@ emit_conditional_move (rtx target, enum > save_pending_stack_adjust (&save); > last = get_last_insn (); > do_pending_stack_adjust (); > + machine_mode cmpmode = cmode; > prepare_cmp_insn (XEXP (comparison, 0), XEXP (comparison, 1), > GET_CODE (comparison), NULL_RTX, unsignedp, > - OPTAB_WIDEN, &comparison, &cmode); > + OPTAB_WIDEN, &comparison, &cmpmode); > if (comparison) > { > struct expand_operand ops[4]; > --- gcc/testsuite/gcc.c-torture/compile/pr84860.c.jj 2018-03-14 > 09:26:19.988883506 +0100 > +++ gcc/testsuite/gcc.c-torture/compile/pr84860.c 2018-03-14 > 09:26:44.854884590 +0100 > @@ -0,0 +1,11 @@ > +/* PR target/84860 */ > + > +void > +foo (int x, int y) > +{ > + while (x < 1) > + { > + x = y; > + y = ((float)1 / 0) ? 2 : 0; > + } > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)