Message ID | CAFULd4YZ2rFX9Y3uZMiJNPa8spFsmf4b6YUfo4Ntc7ci0gWBOw@mail.gmail.com |
---|---|
State | New |
Headers | show |
On 02/10/13 09:32, Uros Bizjak wrote: > Hello! > > Attached patch prevents out-of-bounds offset in the call to > simplify_subreg, where the subreg offset is taken from the offset of a > memory access. The problem triggers on 4.6 branch and is latent on 4.7 > and mainline. > > 2013-02-10 Uros Bizjak <ubizjak@gmail.com> > > PR rtl-optimization/56275 > * simplify-rtx.c (avoid_constant_pool_reference): Check that > offset is non-negative and less than cmode size before > calling simplify_subreg. > > testsuite/ChangeLog: > > 2013-02-10 Uros Bizjak <ubizjak@gmail.com> > > PR rtl-optimization/56275 > * gcc.dg/pr56275.c: New test. > > Tested on x86_64-pc-linux-gnu {,-m32}. > > OK for mainline and release branches? OK for mainline. Please check with the appropriate release manager for the release branches. Thanks, Jeff
Index: simplify-rtx.c =================================================================== --- simplify-rtx.c (revision 195931) +++ simplify-rtx.c (working copy) @@ -242,7 +242,8 @@ 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)) + if ((offset != 0 || cmode != GET_MODE (x)) + && offset >= 0 && offset < GET_MODE_SIZE (cmode)) { rtx tem = simplify_subreg (GET_MODE (x), c, cmode, offset); if (tem && CONSTANT_P (tem)) Index: testsuite/gcc.dg/pr56275.c =================================================================== --- testsuite/gcc.dg/pr56275.c (revision 0) +++ testsuite/gcc.dg/pr56275.c (working copy) @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-mno-sse" { target { i?86-*-* x86_64-*-* } } } */ + +typedef long long v2tw __attribute__ ((vector_size (2 * sizeof (long long)))); + +void tiger_block_v2 (long long in1, v2tw *res) +{ + v2tw i1 = { in1, in1 }; + + *res = i1 << 1; +}