On Mon, 6 Sep 2021, liuhongt wrote: > Hi: > For the conversion from _Float16 to int, if the corresponding optab > does not exist, the compiler will try the wider mode (SFmode here), > but when floatsfsi exists but FAIL, FROM will be rewritten, which > leads to a PR runtime error. > > Boostrapped and regtested on x86_64-linux-gnu{-m32,}. > Ok for trunk? > > gcc/ChangeLog: > > PR middle-end/102182 > * optabs.c (expand_fix): Add from1 to avoid from being > overwritten. > > gcc/testsuite/ChangeLog: > > PR middle-end/102182 > *gcc.target/i386/pr101282.c: New test. > --- > gcc/optabs.c | 10 +++++++--- > gcc/testsuite/gcc.target/i386/pr101282.c | 18 ++++++++++++++++++ > 2 files changed, 25 insertions(+), 3 deletions(-) > create mode 100644 gcc/testsuite/gcc.target/i386/pr101282.c > > diff --git a/gcc/optabs.c b/gcc/optabs.c > index ebed78fda3f..6af67d05253 100644 > --- a/gcc/optabs.c > +++ b/gcc/optabs.c > @@ -5480,6 +5480,7 @@ expand_fix (rtx to, rtx from, int unsignedp) > FOR_EACH_MODE_FROM (imode, GET_MODE (to)) > { > int doing_unsigned = unsignedp; > + rtx from1 = NULL_RTX; > > icode = can_fix_p (imode, fmode, unsignedp, &must_trunc); > if (icode == CODE_FOR_nothing && imode != GET_MODE (to) && unsignedp) > @@ -5489,19 +5490,22 @@ expand_fix (rtx to, rtx from, int unsignedp) > { > rtx_insn *last = get_last_insn ();
better declare from1 here > if (fmode != GET_MODE (from)) > - from = convert_to_mode (fmode, from, 0); > + from1 = convert_to_mode (fmode, from, 0); > > if (must_trunc) > { > rtx temp = gen_reg_rtx (GET_MODE (from)); > - from = expand_unop (GET_MODE (from), ftrunc_optab, from, > + from1 = expand_unop (GET_MODE (from), ftrunc_optab, from, this must use from1 as well? > temp, 0); > } > > if (imode != GET_MODE (to)) > target = gen_reg_rtx (imode); > > - if (maybe_emit_unop_insn (icode, target, from, > + if (!from1) > + from1 = from; so move this up. > + if (maybe_emit_unop_insn (icode, target, from1, > doing_unsigned ? UNSIGNED_FIX : FIX)) > { > if (target != to) > diff --git a/gcc/testsuite/gcc.target/i386/pr101282.c > b/gcc/testsuite/gcc.target/i386/pr101282.c > new file mode 100644 > index 00000000000..2148b9294ef > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr101282.c > @@ -0,0 +1,18 @@ > +/* { dg-do run { target { ia32 } } } */ > +/* { dg-options "-Os -march=i686 -mfpmath=sse -msse2" } */ > + > +#include<stdlib.h> > +int > +main (void) > +{ > + static volatile unsigned int ivin, ivout; > + static volatile _Float16 fv1, fv2; > + ivin = ((unsigned int)1); > + fv1 = ((unsigned int)1); > + fv2 = ivin; > + ivout = fv2; > + if (ivout != ((unsigned int)1)) > + abort (); > + > + exit (0); > +} > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)