diff mbox series

PR81703 and Martin's fix for PR83501

Message ID CAAgBjM=FW0qK83nE0jJ52d7EKAv_HGgHte3=qne2aBGtSAVZhQ@mail.gmail.com
State New
Headers show
Series PR81703 and Martin's fix for PR83501 | expand

Commit Message

Prathamesh Kulkarni Jan. 10, 2018, 6:42 p.m. UTC
Hi,
I have attached patch for PR81703 rebased on Martin's fix for PR83501
posted here since both had considerable overlaps:
https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00180.html

The patch passes bootstrap+test on x86_64-unknown-linux-gnu
and cross-tested on aarch64-*-*.
Currently it fails to pass validation on arm targets because of PR83775.

Does it look OK?

Thanks,
Prathamesh
2018-10-01  Martin Sebor  <msebor@gmail.com>
	    Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>

	PR tree-optimization/83501
	PR tree-optimization/81703

	* tree-ssa-strlen.c (get_string_cst): Rename...
	(get_string_len): ...to this.  Handle global constants.
	(handle_char_store): Adjust.

testsuite/
	* gcc.dg/strlenopt-39.c: New test-case.
	* gcc.dg/pr81703.c: Likewise.

Comments

Jeff Law Jan. 10, 2018, 9:29 p.m. UTC | #1
On 01/10/2018 11:42 AM, Prathamesh Kulkarni wrote:
> Hi,
> I have attached patch for PR81703 rebased on Martin's fix for PR83501
> posted here since both had considerable overlaps:
> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00180.html
> 
> The patch passes bootstrap+test on x86_64-unknown-linux-gnu
> and cross-tested on aarch64-*-*.
> Currently it fails to pass validation on arm targets because of PR83775.
> 
> Does it look OK?
> 
> Thanks,
> Prathamesh
> 
> 
> pr81703-1.txt
> 
> 
> 2018-10-01  Martin Sebor  <msebor@gmail.com>
> 	    Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
> 
> 	PR tree-optimization/83501
> 	PR tree-optimization/81703
> 
> 	* tree-ssa-strlen.c (get_string_cst): Rename...
> 	(get_string_len): ...to this.  Handle global constants.
> 	(handle_char_store): Adjust.
> 
> testsuite/
> 	* gcc.dg/strlenopt-39.c: New test-case.
> 	* gcc.dg/pr81703.c: Likewise.
OK.

Jeff
Christophe Lyon Jan. 11, 2018, 9:22 a.m. UTC | #2
Hi

On 10 January 2018 at 19:42, Prathamesh Kulkarni
<prathamesh.kulkarni@linaro.org> wrote:
> Hi,
> I have attached patch for PR81703 rebased on Martin's fix for PR83501
> posted here since both had considerable overlaps:
> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00180.html
>
> The patch passes bootstrap+test on x86_64-unknown-linux-gnu
> and cross-tested on aarch64-*-*.
> Currently it fails to pass validation on arm targets because of PR83775.
>

I don't think the new failure is because of PR83775 (which is an ICE
when calling cc1 directly without -march).

The failure we have on arm is:
FAIL: gcc.dg/strlenopt-39.c scan-tree-dump-not optimized "(abort|strlen) \\(\\)"
but just before that, we have:
PASS: gcc.dg/strlenopt-39.c (test for excess errors)
so the compilation did not ICE

Christophe

> Does it look OK?
>
> Thanks,
> Prathamesh
Prathamesh Kulkarni Jan. 11, 2018, 10:44 a.m. UTC | #3
On 11 January 2018 at 14:52, Christophe Lyon <christophe.lyon@linaro.org> wrote:
> Hi
>
> On 10 January 2018 at 19:42, Prathamesh Kulkarni
> <prathamesh.kulkarni@linaro.org> wrote:
>> Hi,
>> I have attached patch for PR81703 rebased on Martin's fix for PR83501
>> posted here since both had considerable overlaps:
>> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00180.html
>>
>> The patch passes bootstrap+test on x86_64-unknown-linux-gnu
>> and cross-tested on aarch64-*-*.
>> Currently it fails to pass validation on arm targets because of PR83775.
>>
>
> I don't think the new failure is because of PR83775 (which is an ICE
> when calling cc1 directly without -march).
>
> The failure we have on arm is:
> FAIL: gcc.dg/strlenopt-39.c scan-tree-dump-not optimized "(abort|strlen) \\(\\)"
> but just before that, we have:
> PASS: gcc.dg/strlenopt-39.c (test for excess errors)
> so the compilation did not ICE
Ah, I think you're right. For some reason I mixed up the two :/
Thanks for pointing out, I will take a look at the failure.

Regards,
Prathamesh
>
> Christophe
>
>> Does it look OK?
>>
>> Thanks,
>> Prathamesh
Prathamesh Kulkarni Jan. 11, 2018, 12:02 p.m. UTC | #4
On 11 January 2018 at 16:14, Prathamesh Kulkarni
<prathamesh.kulkarni@linaro.org> wrote:
> On 11 January 2018 at 14:52, Christophe Lyon <christophe.lyon@linaro.org> wrote:
>> Hi
>>
>> On 10 January 2018 at 19:42, Prathamesh Kulkarni
>> <prathamesh.kulkarni@linaro.org> wrote:
>>> Hi,
>>> I have attached patch for PR81703 rebased on Martin's fix for PR83501
>>> posted here since both had considerable overlaps:
>>> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00180.html
>>>
>>> The patch passes bootstrap+test on x86_64-unknown-linux-gnu
>>> and cross-tested on aarch64-*-*.
>>> Currently it fails to pass validation on arm targets because of PR83775.
>>>
>>
>> I don't think the new failure is because of PR83775 (which is an ICE
>> when calling cc1 directly without -march).
>>
>> The failure we have on arm is:
>> FAIL: gcc.dg/strlenopt-39.c scan-tree-dump-not optimized "(abort|strlen) \\(\\)"
>> but just before that, we have:
>> PASS: gcc.dg/strlenopt-39.c (test for excess errors)
>> so the compilation did not ICE
> Ah, I think you're right. For some reason I mixed up the two :/
> Thanks for pointing out, I will take a look at the failure.
Sorry about this once again.
The real issue seems to be differences in gimplification for ARM and x86_64.

Test-case:

#define STR "1234567"

const char str[] = STR;

char dst[10];

void copy_from_local_memstr (void)
{
  struct {
    char s[sizeof STR];
  } x = { STR };

  strcpy (dst, x.s);

  if (strlen (dst) != sizeof x.s - 1)
    abort ();
}

The difference between x86-64 and armhf dumps starts from 004t.gimple:
-      x = *.LC0;
+      x.s = "1234567";
       strcpy (&dst, &x.s);

While x86_64 emits a load from constant string, armhf has x = *.LC0
and thus strlen pass doesn't convert strcpy (&dst, &x.s) to memcpy
(&dst, &x.s, 8)
which inhibits the transform added in the patch and thus the test-case fails.

I am not sure why constant string is not emitted for arm-linux-gnueabihf ?
As far as this issue is concerned, should I simply XFAIL it on arm for now ?

Thanks,
Prathamesh
>
> Regards,
> Prathamesh
>>
>> Christophe
>>
>>> Does it look OK?
>>>
>>> Thanks,
>>> Prathamesh
Martin Sebor Jan. 11, 2018, 4:33 p.m. UTC | #5
On 01/11/2018 05:02 AM, Prathamesh Kulkarni wrote:
> On 11 January 2018 at 16:14, Prathamesh Kulkarni
> <prathamesh.kulkarni@linaro.org> wrote:
>> On 11 January 2018 at 14:52, Christophe Lyon <christophe.lyon@linaro.org> wrote:
>>> Hi
>>>
>>> On 10 January 2018 at 19:42, Prathamesh Kulkarni
>>> <prathamesh.kulkarni@linaro.org> wrote:
>>>> Hi,
>>>> I have attached patch for PR81703 rebased on Martin's fix for PR83501
>>>> posted here since both had considerable overlaps:
>>>> https://gcc.gnu.org/ml/gcc-patches/2018-01/msg00180.html
>>>>
>>>> The patch passes bootstrap+test on x86_64-unknown-linux-gnu
>>>> and cross-tested on aarch64-*-*.
>>>> Currently it fails to pass validation on arm targets because of PR83775.
>>>>
>>>
>>> I don't think the new failure is because of PR83775 (which is an ICE
>>> when calling cc1 directly without -march).
>>>
>>> The failure we have on arm is:
>>> FAIL: gcc.dg/strlenopt-39.c scan-tree-dump-not optimized "(abort|strlen) \\(\\)"
>>> but just before that, we have:
>>> PASS: gcc.dg/strlenopt-39.c (test for excess errors)
>>> so the compilation did not ICE
>> Ah, I think you're right. For some reason I mixed up the two :/
>> Thanks for pointing out, I will take a look at the failure.
> Sorry about this once again.
> The real issue seems to be differences in gimplification for ARM and x86_64.
>
> Test-case:
>
> #define STR "1234567"
>
> const char str[] = STR;
>
> char dst[10];
>
> void copy_from_local_memstr (void)
> {
>   struct {
>     char s[sizeof STR];
>   } x = { STR };
>
>   strcpy (dst, x.s);
>
>   if (strlen (dst) != sizeof x.s - 1)
>     abort ();
> }
>
> The difference between x86-64 and armhf dumps starts from 004t.gimple:
> -      x = *.LC0;
> +      x.s = "1234567";
>        strcpy (&dst, &x.s);
>
> While x86_64 emits a load from constant string, armhf has x = *.LC0
> and thus strlen pass doesn't convert strcpy (&dst, &x.s) to memcpy
> (&dst, &x.s, 8)
> which inhibits the transform added in the patch and thus the test-case fails.
>
> I am not sure why constant string is not emitted for arm-linux-gnueabihf ?
> As far as this issue is concerned, should I simply XFAIL it on arm for now ?

This is not unique to the arm back end but affects other targets
as well, including powerpc64.  There's a bug open (PR 83462) for
one of the tests I recently added with the same root cause:
a case not being handled by the strlen pass.  I'm tracking this
missed optimization in PR 83543.   I would expect handling it
to be fairly easy but it seems that every I think that it turns
out to be anything but.  Either way, either fixing 83543 or
marking this failure (and those in PR 83462) XFAIL until it
the optimization is added should work.

If you feel like tackling 83462 before stage 3 closes please
let me know so we don't duplicate our efforts.

Martin

>
> Thanks,
> Prathamesh
>>
>> Regards,
>> Prathamesh
>>>
>>> Christophe
>>>
>>>> Does it look OK?
>>>>
>>>> Thanks,
>>>> Prathamesh
Rainer Orth Jan. 11, 2018, 9:48 p.m. UTC | #6
Hi Martin,

>> I am not sure why constant string is not emitted for arm-linux-gnueabihf ?
>> As far as this issue is concerned, should I simply XFAIL it on arm for now ?
>
> This is not unique to the arm back end but affects other targets
> as well, including powerpc64.  There's a bug open (PR 83462) for
> one of the tests I recently added with the same root cause:
> a case not being handled by the strlen pass.  I'm tracking this
> missed optimization in PR 83543.   I would expect handling it
> to be fairly easy but it seems that every I think that it turns
> out to be anything but.  Either way, either fixing 83543 or
> marking this failure (and those in PR 83462) XFAIL until it
> the optimization is added should work.

I'm seeing the same failure on sparc*-sun-solaris*, and gcc-testresults
shows it on mips64el-unknown-linux-gnu and powerpc-ibm-aix7.2.0.0, too.
XFAILing may become unwieldly if more targets are affected.

	Rainer
Martin Sebor Jan. 12, 2018, 12:45 a.m. UTC | #7
On 01/11/2018 02:48 PM, Rainer Orth wrote:
> Hi Martin,
>
>>> I am not sure why constant string is not emitted for arm-linux-gnueabihf ?
>>> As far as this issue is concerned, should I simply XFAIL it on arm for now ?
>>
>> This is not unique to the arm back end but affects other targets
>> as well, including powerpc64.  There's a bug open (PR 83462) for
>> one of the tests I recently added with the same root cause:
>> a case not being handled by the strlen pass.  I'm tracking this
>> missed optimization in PR 83543.   I would expect handling it
>> to be fairly easy but it seems that every I think that it turns
>> out to be anything but.  Either way, either fixing 83543 or
>> marking this failure (and those in PR 83462) XFAIL until it
>> the optimization is added should work.
>
> I'm seeing the same failure on sparc*-sun-solaris*, and gcc-testresults
> shows it on mips64el-unknown-linux-gnu and powerpc-ibm-aix7.2.0.0, too.
> XFAILing may become unwieldly if more targets are affected.

Thanks for pointing it out.  I see it there as well with
Prathamesh's test case, though not with the test case in
bug 83543.  It is the same root cause in both.  I agree
that enhancing the strlen pass to handle this case would
be preferable to just xfailing the test.  I'm just not
sure it's possible before stage 3 closes.  If not, I'll
work on it in GCC 9.  Although the details are target-
specific, the limitation affects all targets and so
having a solution will benefit all all of them.

Martin
Prathamesh Kulkarni Jan. 12, 2018, 6:44 a.m. UTC | #8
On 12 January 2018 at 06:15, Martin Sebor <msebor@gmail.com> wrote:
> On 01/11/2018 02:48 PM, Rainer Orth wrote:
>>
>> Hi Martin,
>>
>>>> I am not sure why constant string is not emitted for arm-linux-gnueabihf
>>>> ?
>>>> As far as this issue is concerned, should I simply XFAIL it on arm for
>>>> now ?
>>>
>>>
>>> This is not unique to the arm back end but affects other targets
>>> as well, including powerpc64.  There's a bug open (PR 83462) for
>>> one of the tests I recently added with the same root cause:
>>> a case not being handled by the strlen pass.  I'm tracking this
>>> missed optimization in PR 83543.   I would expect handling it
>>> to be fairly easy but it seems that every I think that it turns
>>> out to be anything but.  Either way, either fixing 83543 or
>>> marking this failure (and those in PR 83462) XFAIL until it
>>> the optimization is added should work.
>>
>>
>> I'm seeing the same failure on sparc*-sun-solaris*, and gcc-testresults
>> shows it on mips64el-unknown-linux-gnu and powerpc-ibm-aix7.2.0.0, too.
>> XFAILing may become unwieldly if more targets are affected.
>
>
> Thanks for pointing it out.  I see it there as well with
> Prathamesh's test case, though not with the test case in
> bug 83543.  It is the same root cause in both.  I agree
> that enhancing the strlen pass to handle this case would
> be preferable to just xfailing the test.  I'm just not
> sure it's possible before stage 3 closes.  If not, I'll
> work on it in GCC 9.  Although the details are target-
> specific, the limitation affects all targets and so
> having a solution will benefit all all of them.
Indeed, however for now I am not sure what would be the best approach ?
If the test-case starts failing for many targets, not sure if XFAIL
would be the right choice.
Should I just restrict it to x86_64 target for now ?

Thanks,
Prathamesh
>
> Martin
>
Martin Sebor Jan. 12, 2018, 4:23 p.m. UTC | #9
On 01/11/2018 11:44 PM, Prathamesh Kulkarni wrote:
> On 12 January 2018 at 06:15, Martin Sebor <msebor@gmail.com> wrote:
>> On 01/11/2018 02:48 PM, Rainer Orth wrote:
>>>
>>> Hi Martin,
>>>
>>>>> I am not sure why constant string is not emitted for arm-linux-gnueabihf
>>>>> ?
>>>>> As far as this issue is concerned, should I simply XFAIL it on arm for
>>>>> now ?
>>>>
>>>>
>>>> This is not unique to the arm back end but affects other targets
>>>> as well, including powerpc64.  There's a bug open (PR 83462) for
>>>> one of the tests I recently added with the same root cause:
>>>> a case not being handled by the strlen pass.  I'm tracking this
>>>> missed optimization in PR 83543.   I would expect handling it
>>>> to be fairly easy but it seems that every I think that it turns
>>>> out to be anything but.  Either way, either fixing 83543 or
>>>> marking this failure (and those in PR 83462) XFAIL until it
>>>> the optimization is added should work.
>>>
>>>
>>> I'm seeing the same failure on sparc*-sun-solaris*, and gcc-testresults
>>> shows it on mips64el-unknown-linux-gnu and powerpc-ibm-aix7.2.0.0, too.
>>> XFAILing may become unwieldly if more targets are affected.
>>
>>
>> Thanks for pointing it out.  I see it there as well with
>> Prathamesh's test case, though not with the test case in
>> bug 83543.  It is the same root cause in both.  I agree
>> that enhancing the strlen pass to handle this case would
>> be preferable to just xfailing the test.  I'm just not
>> sure it's possible before stage 3 closes.  If not, I'll
>> work on it in GCC 9.  Although the details are target-
>> specific, the limitation affects all targets and so
>> having a solution will benefit all all of them.
> Indeed, however for now I am not sure what would be the best approach ?
> If the test-case starts failing for many targets, not sure if XFAIL
> would be the right choice.
> Should I just restrict it to x86_64 target for now ?

That sounds like a good approach in the interim, until we have
a general solution.  It will avoid having to maintain a list
of targets where it's known to fail.

Martin
Jeff Law Jan. 12, 2018, 5:38 p.m. UTC | #10
On 01/12/2018 09:23 AM, Martin Sebor wrote:
> On 01/11/2018 11:44 PM, Prathamesh Kulkarni wrote:
>> On 12 January 2018 at 06:15, Martin Sebor <msebor@gmail.com> wrote:
>>> On 01/11/2018 02:48 PM, Rainer Orth wrote:
>>>>
>>>> Hi Martin,
>>>>
>>>>>> I am not sure why constant string is not emitted for
>>>>>> arm-linux-gnueabihf
>>>>>> ?
>>>>>> As far as this issue is concerned, should I simply XFAIL it on arm
>>>>>> for
>>>>>> now ?
>>>>>
>>>>>
>>>>> This is not unique to the arm back end but affects other targets
>>>>> as well, including powerpc64.  There's a bug open (PR 83462) for
>>>>> one of the tests I recently added with the same root cause:
>>>>> a case not being handled by the strlen pass.  I'm tracking this
>>>>> missed optimization in PR 83543.   I would expect handling it
>>>>> to be fairly easy but it seems that every I think that it turns
>>>>> out to be anything but.  Either way, either fixing 83543 or
>>>>> marking this failure (and those in PR 83462) XFAIL until it
>>>>> the optimization is added should work.
>>>>
>>>>
>>>> I'm seeing the same failure on sparc*-sun-solaris*, and gcc-testresults
>>>> shows it on mips64el-unknown-linux-gnu and powerpc-ibm-aix7.2.0.0, too.
>>>> XFAILing may become unwieldly if more targets are affected.
>>>
>>>
>>> Thanks for pointing it out.  I see it there as well with
>>> Prathamesh's test case, though not with the test case in
>>> bug 83543.  It is the same root cause in both.  I agree
>>> that enhancing the strlen pass to handle this case would
>>> be preferable to just xfailing the test.  I'm just not
>>> sure it's possible before stage 3 closes.  If not, I'll
>>> work on it in GCC 9.  Although the details are target-
>>> specific, the limitation affects all targets and so
>>> having a solution will benefit all all of them.
>> Indeed, however for now I am not sure what would be the best approach ?
>> If the test-case starts failing for many targets, not sure if XFAIL
>> would be the right choice.
>> Should I just restrict it to x86_64 target for now ?
> 
> That sounds like a good approach in the interim, until we have
> a general solution.  It will avoid having to maintain a list
> of targets where it's known to fail.
Agreed and pre-approved.
jeff
Jakub Jelinek Jan. 12, 2018, 5:55 p.m. UTC | #11
On Fri, Jan 12, 2018 at 10:38:39AM -0700, Jeff Law wrote:
> >>> Thanks for pointing it out.  I see it there as well with
> >>> Prathamesh's test case, though not with the test case in
> >>> bug 83543.  It is the same root cause in both.  I agree
> >>> that enhancing the strlen pass to handle this case would
> >>> be preferable to just xfailing the test.  I'm just not
> >>> sure it's possible before stage 3 closes.  If not, I'll
> >>> work on it in GCC 9.  Although the details are target-
> >>> specific, the limitation affects all targets and so
> >>> having a solution will benefit all all of them.
> >> Indeed, however for now I am not sure what would be the best approach ?
> >> If the test-case starts failing for many targets, not sure if XFAIL
> >> would be the right choice.
> >> Should I just restrict it to x86_64 target for now ?
> > 
> > That sounds like a good approach in the interim, until we have
> > a general solution.  It will avoid having to maintain a list
> > of targets where it's known to fail.
> Agreed and pre-approved.

Just please test with
RUNTESTFLAGS='--target_board=unix\{-m64,-m32,-m32/-mno-sse\} dg.exp=strlenopt-*.c'
and restrict to { i?86-*-* x86_64-*-* }, e.g. on Solaris it is i?86-*-*
canonical target, even when it supports -m64 multilib.
If you need x86_64 64-bit, that would be { { i?86-*-* x86_64-*-* } && lp64 }
or ! ia32, depending on if -mx32 works or not.

	Jakub
Prathamesh Kulkarni Jan. 14, 2018, 9:04 a.m. UTC | #12
On 12 January 2018 at 23:25, Jakub Jelinek <jakub@redhat.com> wrote:
> On Fri, Jan 12, 2018 at 10:38:39AM -0700, Jeff Law wrote:
>> >>> Thanks for pointing it out.  I see it there as well with
>> >>> Prathamesh's test case, though not with the test case in
>> >>> bug 83543.  It is the same root cause in both.  I agree
>> >>> that enhancing the strlen pass to handle this case would
>> >>> be preferable to just xfailing the test.  I'm just not
>> >>> sure it's possible before stage 3 closes.  If not, I'll
>> >>> work on it in GCC 9.  Although the details are target-
>> >>> specific, the limitation affects all targets and so
>> >>> having a solution will benefit all all of them.
>> >> Indeed, however for now I am not sure what would be the best approach ?
>> >> If the test-case starts failing for many targets, not sure if XFAIL
>> >> would be the right choice.
>> >> Should I just restrict it to x86_64 target for now ?
>> >
>> > That sounds like a good approach in the interim, until we have
>> > a general solution.  It will avoid having to maintain a list
>> > of targets where it's known to fail.
>> Agreed and pre-approved.
>
> Just please test with
> RUNTESTFLAGS='--target_board=unix\{-m64,-m32,-m32/-mno-sse\} dg.exp=strlenopt-*.c'
> and restrict to { i?86-*-* x86_64-*-* }, e.g. on Solaris it is i?86-*-*
> canonical target, even when it supports -m64 multilib.
> If you need x86_64 64-bit, that would be { { i?86-*-* x86_64-*-* } && lp64 }
> or ! ia32, depending on if -mx32 works or not.
Thanks, committed in r256657 after verifying that -m32 works.

Thanks,
Prathamesh
>
>         Jakub
diff mbox series

Patch

diff --git a/gcc/testsuite/gcc.dg/pr81703.c b/gcc/testsuite/gcc.dg/pr81703.c
new file mode 100644
index 00000000000..190f4a833dd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr81703.c
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-strlen" } */
+
+unsigned g (void)
+{
+  char d[8];
+  const char s[] = "0123";
+  __builtin_memcpy (d, s, sizeof s);
+  return __builtin_strlen (d);
+}
+
+/* { dg-final { scan-tree-dump-not "__builtin_strlen" "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-39.c b/gcc/testsuite/gcc.dg/strlenopt-39.c
new file mode 100644
index 00000000000..a4177c918ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strlenopt-39.c
@@ -0,0 +1,66 @@ 
+/* PR tree-optimization/83444
+   { dg-do compile }
+   { dg-options "-O2 -fdump-tree-optimized" } */
+
+#include "strlenopt.h"
+
+#define STR "1234567"
+
+const char str[] = STR;
+
+char dst[10];
+
+void copy_from_global_str (void)
+{
+  strcpy (dst, str);
+
+  if (strlen (dst) != sizeof str - 1)
+    abort ();
+}
+
+void copy_from_local_str (void)
+{
+  const char s[] = STR;
+
+  strcpy (dst, s);
+
+  if (strlen (dst) != sizeof s - 1)
+    abort ();
+}
+
+void copy_from_local_memstr (void)
+{
+  struct {
+    char s[sizeof STR];
+  } x = { STR };
+
+  strcpy (dst, x.s);
+
+  if (strlen (dst) != sizeof x.s - 1)
+    abort ();
+}
+
+void copy_to_local_str (void)
+{
+  char d[sizeof STR];
+
+  strcpy (d, str);
+
+  if (strlen (d) != sizeof str - 1)
+    abort ();
+}
+
+void copy_to_local_memstr (void)
+{
+  struct {
+    char d[sizeof STR];
+  } x;
+
+  strcpy (x.d, str);
+
+  if (strlen (x.d) != sizeof str- 1)
+    abort ();
+}
+
+/* Verify that all calls to strlen have been eliminated.
+  { dg-final { scan-tree-dump-not "(abort|strlen) \\(\\)" "optimized" } } */
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index aae242d93d6..4e363278ea2 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -2773,18 +2773,40 @@  handle_pointer_plus (gimple_stmt_iterator *gsi)
 }
 
 /* Check if RHS is string_cst possibly wrapped by mem_ref.  */
-static tree
-get_string_cst (tree rhs)
+static int
+get_string_len (tree rhs)
 {
   if (TREE_CODE (rhs) == MEM_REF
       && integer_zerop (TREE_OPERAND (rhs, 1)))
     {
-      rhs = TREE_OPERAND (rhs, 0);
+      tree rhs_addr = rhs = TREE_OPERAND (rhs, 0);
       if (TREE_CODE (rhs) == ADDR_EXPR)
-	rhs = TREE_OPERAND (rhs, 0);
+	{
+	  rhs = TREE_OPERAND (rhs, 0);
+	  if (TREE_CODE (rhs) != STRING_CST)
+	    {
+	      int idx = get_stridx (rhs_addr);
+	      if (idx > 0)
+		{
+		  strinfo *si = get_strinfo (idx);
+		  if (si && si->full_string_p)
+		    return tree_to_shwi (si->nonzero_chars);
+		}
+	    }
+	}
     }
 
-  return (TREE_CODE (rhs) == STRING_CST) ? rhs : NULL_TREE;
+  if (TREE_CODE (rhs) == VAR_DECL
+      && TREE_READONLY (rhs))
+    rhs = DECL_INITIAL (rhs);
+
+  if (rhs && TREE_CODE (rhs) == STRING_CST)
+    {
+      unsigned HOST_WIDE_INT ilen = strlen (TREE_STRING_POINTER (rhs));
+      return ilen <= INT_MAX ? ilen : -1;
+    }
+
+  return -1;
 }
 
 /* Handle a single character store.  */
@@ -2799,6 +2821,9 @@  handle_char_store (gimple_stmt_iterator *gsi)
   tree rhs = gimple_assign_rhs1 (stmt);
   unsigned HOST_WIDE_INT offset = 0;
 
+  /* Set to the length of the string being assigned if known.  */
+  int rhslen;
+
   if (TREE_CODE (lhs) == MEM_REF
       && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME)
     {
@@ -2942,19 +2967,18 @@  handle_char_store (gimple_stmt_iterator *gsi)
 	}
     }
   else if (idx == 0
-	   && (rhs = get_string_cst (gimple_assign_rhs1 (stmt)))
+	   && (rhslen = get_string_len (gimple_assign_rhs1 (stmt))) >= 0
 	   && ssaname == NULL_TREE
 	   && TREE_CODE (TREE_TYPE (lhs)) == ARRAY_TYPE)
     {
-      size_t l = strlen (TREE_STRING_POINTER (rhs));
       HOST_WIDE_INT a = int_size_in_bytes (TREE_TYPE (lhs));
-      if (a > 0 && (unsigned HOST_WIDE_INT) a > l)
+      if (a > 0 && (unsigned HOST_WIDE_INT) a > (unsigned HOST_WIDE_INT) rhslen)
 	{
 	  int idx = new_addr_stridx (lhs);
 	  if (idx != 0)
 	    {
 	      si = new_strinfo (build_fold_addr_expr (lhs), idx,
-				build_int_cst (size_type_node, l), true);
+				build_int_cst (size_type_node, rhslen), true);
 	      set_strinfo (idx, si);
 	      si->dont_invalidate = true;
 	    }