diff options
-rw-r--r-- | gcc/rtlanal.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr71295.c | 12 |
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]); +} |