On August 29, 2016 9:43:50 PM GMT+02:00, Jakub Jelinek <ja...@redhat.com> wrote: >Hi! > >Returning c from avoid_constant_pool_reference for constant pool >references >is only fine if the modes match and offset is zero, otherwise if the >offset >is sane, we can try to simplify it as subreg. But, returning c for out >of >bounds offsets is always wrong, and especially if the mode doesn't >match, it >can results in all kinds of ICEs. > >Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
OK. Thanks, Richard. >2016-08-29 Jakub Jelinek <ja...@redhat.com> > > PR middle-end/77377 > * simplify-rtx.c (avoid_constant_pool_reference): For out of bounds > constant pool reference return x instead of c. > > * gcc.target/i386/pr77377.c: New test. > >--- gcc/simplify-rtx.c.jj 2016-08-12 17:33:46.000000000 +0200 >+++ gcc/simplify-rtx.c 2016-08-29 13:32:38.126859949 +0200 >@@ -251,15 +251,14 @@ avoid_constant_pool_reference (rtx x) > /* If we're accessing the constant in a different mode than it was > originally stored, attempt to fix that up via subreg simplifications. > If that fails we have no choice but to return the original memory. */ >- if ((offset != 0 || cmode != GET_MODE (x)) >- && offset >= 0 && offset < GET_MODE_SIZE (cmode)) >+ if (offset == 0 && cmode == GET_MODE (x)) >+ return c; >+ else if (offset >= 0 && offset < GET_MODE_SIZE (cmode)) > { > rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset); > if (tem && CONSTANT_P (tem)) > return tem; > } >- else >- return c; > } > > return x; >--- gcc/testsuite/gcc.target/i386/pr77377.c.jj 2016-08-29 >13:39:01.707328239 +0200 >+++ gcc/testsuite/gcc.target/i386/pr77377.c 2016-08-29 >13:38:55.901396832 +0200 >@@ -0,0 +1,6 @@ >+/* PR middle-end/77377 */ >+/* { dg-do compile } */ >+/* { dg-options "-O3 -msse" } */ >+/* { dg-additional-options "-fpic" { target fpic } } */ >+ >+#include "../../c-c++-common/pr59037.c" > > Jakub