On 11 Jun 14:59, Uros Bizjak wrote: > On Tue, Jun 10, 2014 at 3:45 PM, Dominique Dhumieres <domi...@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.enkov...@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.enkov...@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.enkov...@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" } */ + +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; +}