Message ID | 20160108201317.GE18720@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
On 01/08/2016 03:13 PM, Jakub Jelinek wrote: > Hi! > > The following testcase ICEs, because move_plus_up attempts to > optimize (subreg:HI (plus:SI (...) (const_int 0xff78)) 0) > into (plus:HI (subreg:HI (...) 0) (const_int 0xff78)) which is > incorrect, HImode CONST_INT with MSB set should be (const_int -136) > instead. The patch also punts if the second operand of PLUS is > some CONSTANT_P that can't be simplified into a CONSTANT_P in the > narrower mode. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? Sure. Thanks, Jakub. > 2016-01-08 Jakub Jelinek <jakub@redhat.com> > > PR target/69071 > * lra-eliminations.c (move_plus_up): Only move plus up > if subreg of the constant can be simplified into constant > and use the simplified subreg of the constant instead of > the original constant. > > * gcc.dg/pr69071.c: New test. > > --- gcc/lra-eliminations.c.jj 2016-01-04 14:55:50.000000000 +0100 > +++ gcc/lra-eliminations.c 2016-01-08 10:28:39.954706210 +0100 > @@ -296,9 +296,14 @@ move_plus_up (rtx x) > if (GET_CODE (x) == SUBREG && GET_CODE (subreg_reg) == PLUS > && GET_MODE_SIZE (x_mode) <= GET_MODE_SIZE (subreg_reg_mode) > && CONSTANT_P (XEXP (subreg_reg, 1))) > - return gen_rtx_PLUS (x_mode, lowpart_subreg (x_mode, subreg_reg, > - subreg_reg_mode), > - XEXP (subreg_reg, 1)); > + { > + rtx cst = simplify_subreg (x_mode, XEXP (subreg_reg, 1), subreg_reg_mode, > + subreg_lowpart_offset (x_mode, > + subreg_reg_mode)); > + if (cst && CONSTANT_P (cst)) > + return gen_rtx_PLUS (x_mode, lowpart_subreg (x_mode, subreg_reg, > + subreg_reg_mode), cst); > + } > return x; > } > > --- gcc/testsuite/gcc.dg/pr69071.c.jj 2016-01-08 10:24:50.029922989 +0100 > +++ gcc/testsuite/gcc.dg/pr69071.c 2016-01-08 10:24:34.000000000 +0100 > @@ -0,0 +1,22 @@ > +/* PR target/69071 */ > +/* { dg-do compile } */ > +/* { dg-options "-O2 -g" } */ > + > +void *bar (void *); > + > +void > +foo (int c) > +{ > + unsigned char bf[65400]; > + unsigned char *p2 = bar (bf); > + unsigned char *p3 = bar (bf); > + for (; *p2; p2++, c++) > + { > + if (c) > + { > + short of = p2 - bf - 6; > + unsigned ofu = of; > + __builtin_memcpy (p3, &ofu, sizeof (ofu)); > + } > + } > +} > > Jakub
--- gcc/lra-eliminations.c.jj 2016-01-04 14:55:50.000000000 +0100 +++ gcc/lra-eliminations.c 2016-01-08 10:28:39.954706210 +0100 @@ -296,9 +296,14 @@ move_plus_up (rtx x) if (GET_CODE (x) == SUBREG && GET_CODE (subreg_reg) == PLUS && GET_MODE_SIZE (x_mode) <= GET_MODE_SIZE (subreg_reg_mode) && CONSTANT_P (XEXP (subreg_reg, 1))) - return gen_rtx_PLUS (x_mode, lowpart_subreg (x_mode, subreg_reg, - subreg_reg_mode), - XEXP (subreg_reg, 1)); + { + rtx cst = simplify_subreg (x_mode, XEXP (subreg_reg, 1), subreg_reg_mode, + subreg_lowpart_offset (x_mode, + subreg_reg_mode)); + if (cst && CONSTANT_P (cst)) + return gen_rtx_PLUS (x_mode, lowpart_subreg (x_mode, subreg_reg, + subreg_reg_mode), cst); + } return x; } --- gcc/testsuite/gcc.dg/pr69071.c.jj 2016-01-08 10:24:50.029922989 +0100 +++ gcc/testsuite/gcc.dg/pr69071.c 2016-01-08 10:24:34.000000000 +0100 @@ -0,0 +1,22 @@ +/* PR target/69071 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +void *bar (void *); + +void +foo (int c) +{ + unsigned char bf[65400]; + unsigned char *p2 = bar (bf); + unsigned char *p3 = bar (bf); + for (; *p2; p2++, c++) + { + if (c) + { + short of = p2 - bf - 6; + unsigned ofu = of; + __builtin_memcpy (p3, &ofu, sizeof (ofu)); + } + } +}