Message ID | 574D9EFE.8090806@foss.arm.com |
---|---|
State | New |
Headers | show |
On 05/31/2016 04:26 PM, Kyrill Tkachov wrote: > we're talking about (subreg:V2DI (reg/v:EI 111 [ b ]) 0). > EImode is a 24 byte arm-specific integer mode used to represent 3 > D-registers. [...] > I'm not familiar with the processes in that part of the code but my > suspicion is that we should be > rejecting that invalid subreg somewhere and this patch does that in > subreg_get_info a few lines before > the triggering assert. It rejects the subreg by setting > info->representable_p to false. > Is this the right way to go around fixing this? I'm slightly uncertain, but I can't really see anything wrong with this approach. So, OK. There are things that could be cleaned up here, moving the duplicated !rknown tests to the outer if and maybe the declarations of regsize_[xy]mode into the if, but that's not something you have to do if you don't want to. Bernd
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index bfefd968b47c530c77c50d72ce42f4a6d4955ea4..6ab96889408bc09815f5490532657ffcecf5c52e 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 0000000000000000000000000000000000000000..d2ec852fd08b307da50bfd993a6c43d42f303037 --- /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]); +}