aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristophe Lyon <christophe.lyon@linaro.org>2016-07-12 12:15:36 +0200
committerYvan Roux <yvan.roux@linaro.org>2016-08-25 12:50:23 +0000
commit9dd1dea6aca393eebc68128802125be9cb68e16b (patch)
treefcf6b6fcdc702d8e24137f7c798d93f8fce32346
parent1399abbb869648cb6a04254f0f0f13479a34ec93 (diff)
gcc/
Backport from trunk r237034. 2016-06-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com> PR rtl-optimization/71295 * rtlanal.c (subreg_get_info): If taking a subreg at the requested offset would go over the size of the inner mode reject it. gcc/testsuite/ Backport from trunk r237034. 2016-06-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com> PR rtl-optimization/71295 * gcc.c-torture/compile/pr71295.c: New test. Change-Id: I620aa65019e981cb43ff964781ed2158362c484d
-rw-r--r--gcc/rtlanal.c10
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr71295.c12
2 files changed, 22 insertions, 0 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index b4dff86c0e9..c5a6d7939ef 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -3657,6 +3657,16 @@ subreg_get_info (unsigned int xregno, machine_mode xmode,
info->offset = offset / regsize_xmode;
return;
}
+ /* It's not valid to extract a subreg of mode YMODE at OFFSET that
+ would go outside of XMODE. */
+ if (!rknown
+ && GET_MODE_SIZE (ymode) + offset > GET_MODE_SIZE (xmode))
+ {
+ info->representable_p = false;
+ info->nregs = nregs_ymode;
+ info->offset = offset / regsize_xmode;
+ return;
+ }
/* Quick exit for the simple and common case of extracting whole
subregisters from a multiregister value. */
/* ??? It would be better to integrate this into the code below,
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr71295.c b/gcc/testsuite/gcc.c-torture/compile/pr71295.c
new file mode 100644
index 00000000000..d2ec852fd08
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr71295.c
@@ -0,0 +1,12 @@
+extern void fn2 (long long);
+int a;
+
+void
+fn1 ()
+{
+ long long b[3];
+ a = 0;
+ for (; a < 3; a++)
+ b[a] = 1;
+ fn2 (b[1]);
+}