Message ID | 20140611161135.GK17894@msticlxl57.ims.intel.com |
---|---|
State | New |
Headers | show |
On Wed, Jun 11, 2014 at 6:11 PM, Ilya Enkovich <enkovich.gnu@gmail.com> wrote: > On 11 Jun 14:59, Uros Bizjak wrote: >> On Tue, Jun 10, 2014 at 3:45 PM, Dominique Dhumieres <dominiq@lps.ens.fr> wrote: >> >> This patch fixes PR61446. ... >> > >> > Confirmed, it also allows to bootstrap Core* targets. >> > Could it be reviewed and committed ASAP? >> >> > 2014-06-09 Ilya Enkovich <ilya.enkovich@intel.com> >> > >> > PR 61446 >> > * ree.c (find_and_remove_re): Narrow mode for register copy >> > if required. >> >> Please also add the testcase form the PR. >> >> (I am not RTL reviewer, so I can't approve the patch). >> >> Uros. > > Hi, > > rgis one is the same but with testcase added. > > Bootstrapped and tested on linux-x86_64. > > Thanks, > Ilya > -- > gcc/ > > 2014-06-11 Ilya Enkovich <ilya.enkovich@intel.com> > > PR 61446 > * ree.c (find_and_remove_re): Narrow mode for register copy > if required. > > gcc/testsuite/ > > 2014-06-11 Ilya Enkovich <ilya.enkovich@intel.com> > > * gcc.target/i386/pr61446.c : New. > > > diff --git a/gcc/ree.c b/gcc/ree.c > index ade413e..6d34764 100644 > --- a/gcc/ree.c > +++ b/gcc/ree.c > @@ -1088,14 +1088,24 @@ find_and_remove_re (void) > /* Use the mode of the destination of the defining insn > for the mode of the copy. This is necessary if the > defining insn was used to eliminate a second extension > - that was wider than the first. */ > + that was wider than the first. Truncate mode if it is > + too wide for destination reg. */ > rtx sub_rtx = *get_sub_rtx (def_insn); > rtx pat = PATTERN (curr_insn); > - rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)), > - REGNO (XEXP (SET_SRC (pat), 0))); > - rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)), > - REGNO (SET_DEST (pat))); > - rtx set = gen_rtx_SET (VOIDmode, new_dst, new_src); > + unsigned int regno = REGNO (XEXP (SET_SRC (pat), 0)); > + enum machine_mode mode = GET_MODE (SET_DEST (sub_rtx)); > + rtx new_dst, new_src, set; > + > + if (HARD_REGNO_NREGS (regno, mode) != 1) > + { > + mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (mode)); > + while (HARD_REGNO_NREGS (regno, GET_MODE_WIDER_MODE (mode)) == 1) > + mode = GET_MODE_WIDER_MODE (mode); > + } > + > + new_dst = gen_rtx_REG (mode, REGNO (XEXP (SET_SRC (pat), 0))); > + new_src = gen_rtx_REG (mode, REGNO (SET_DEST (pat))); > + set = gen_rtx_SET (VOIDmode, new_dst, new_src); > emit_insn_after (set, def_insn); > } > > diff --git a/gcc/testsuite/gcc.target/i386/pr61446.c b/gcc/testsuite/gcc.target/i386/pr61446.c > new file mode 100644 > index 0000000..8537cdb > --- /dev/null > +++ b/gcc/testsuite/gcc.target/i386/pr61446.c > @@ -0,0 +1,14 @@ > +/* PR rtl-optimization/61446 */ > + > +/* { dg-do compile } */ > +/* { dg-options "-O2 -m32 -march=corei7" } */ This should read: /* { dg-do compile { target { ia32 } } } */ /* { dg-options "-O2 -march=corei7 -mfpmath=387" } */ The x86 part is OK with this change. Uros.
diff --git a/gcc/ree.c b/gcc/ree.c index ade413e..6d34764 100644 --- a/gcc/ree.c +++ b/gcc/ree.c @@ -1088,14 +1088,24 @@ find_and_remove_re (void) /* Use the mode of the destination of the defining insn for the mode of the copy. This is necessary if the defining insn was used to eliminate a second extension - that was wider than the first. */ + that was wider than the first. Truncate mode if it is + too wide for destination reg. */ rtx sub_rtx = *get_sub_rtx (def_insn); rtx pat = PATTERN (curr_insn); - rtx new_dst = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)), - REGNO (XEXP (SET_SRC (pat), 0))); - rtx new_src = gen_rtx_REG (GET_MODE (SET_DEST (sub_rtx)), - REGNO (SET_DEST (pat))); - rtx set = gen_rtx_SET (VOIDmode, new_dst, new_src); + unsigned int regno = REGNO (XEXP (SET_SRC (pat), 0)); + enum machine_mode mode = GET_MODE (SET_DEST (sub_rtx)); + rtx new_dst, new_src, set; + + if (HARD_REGNO_NREGS (regno, mode) != 1) + { + mode = GET_CLASS_NARROWEST_MODE (GET_MODE_CLASS (mode)); + while (HARD_REGNO_NREGS (regno, GET_MODE_WIDER_MODE (mode)) == 1) + mode = GET_MODE_WIDER_MODE (mode); + } + + new_dst = gen_rtx_REG (mode, REGNO (XEXP (SET_SRC (pat), 0))); + new_src = gen_rtx_REG (mode, REGNO (SET_DEST (pat))); + set = gen_rtx_SET (VOIDmode, new_dst, new_src); emit_insn_after (set, def_insn); } diff --git a/gcc/testsuite/gcc.target/i386/pr61446.c b/gcc/testsuite/gcc.target/i386/pr61446.c new file mode 100644 index 0000000..8537cdb --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr61446.c @@ -0,0 +1,14 @@ +/* PR rtl-optimization/61446 */ + +/* { dg-do compile } */ +/* { dg-options "-O2 -m32 -march=corei7" } */ + +unsigned long long +foo (float a) +{ + const double dfa = a; + const unsigned int hi = dfa / 0x1p32f; + const unsigned int lo = dfa - (double) hi * 0x1p32f; + + return ((unsigned long long) hi << (4 * (8))) | lo; +}