From 37e10165c13e9860dabbf6eaf85481debec459e9 Mon Sep 17 00:00:00 2001
From: Teresa Johnson <tejohnson@google.com>
Date: Thu, 13 Nov 2014 15:36:48 +0000
Subject: [PATCH] re PR tree-optimization/63841 (Incorrect strlen optimization
 after complete unroll)

2014-11-13  Teresa Johnson  <tejohnson@google.com>

gcc:
	PR tree-optimization/63841
	* tree.c (initializer_zerop): A clobber does not zero initialize.

gcc/testsuite:
	PR tree-optimization/63841
	* g++.dg/tree-ssa/pr63841.C: New test.

From-SVN: r217505
---
 gcc/ChangeLog                           |  5 ++++
 gcc/testsuite/ChangeLog                 |  4 +++
 gcc/testsuite/g++.dg/tree-ssa/pr63841.C | 38 +++++++++++++++++++++++++
 gcc/tree.c                              |  2 ++
 4 files changed, 49 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr63841.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index dca1d5a3da0a..c6014e993a39 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-13  Teresa Johnson  <tejohnson@google.com>
+
+	PR tree-optimization/63841
+	* tree.c (initializer_zerop): A clobber does not zero initialize.
+
 2014-11-13  Ulrich Weigand  <Ulrich.Weigand@de.ibm.com>
 
 	* optabs.c (prepare_operand): Gracefully fail if the mode of X
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 279c1b4a5749..b4484b62b0da 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2014-11-13  Teresa Johnson  <tejohnson@google.com>
+	PR tree-optimization/63841
+	* g++.dg/tree-ssa/pr63841.C: New test.
+
 2014-11-13  Richard Biener  <rguenther@suse.de>
 
 	* gcc.dg/tree-ssa/forwprop-28.c: Adjust.
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr63841.C b/gcc/testsuite/g++.dg/tree-ssa/pr63841.C
new file mode 100644
index 000000000000..466e320d431c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr63841.C
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#include <cstdio>
+#include <string>
+
+std::string __attribute__ ((noinline)) comp_test_write() {
+  std::string data;
+
+  for (int i = 0; i < 2; ++i) {
+    char b = 1 >> (i * 8);
+    data.append(&b, 1);
+  }
+
+  return data;
+}
+
+std::string __attribute__ ((noinline)) comp_test_write_good() {
+  std::string data;
+
+  char b;
+  for (int i = 0; i < 2; ++i) {
+    b = 1 >> (i * 8);
+    data.append(&b, 1);
+  }
+
+  return data;
+}
+
+int main() {
+  std::string good = comp_test_write_good();
+  printf("expected: %hx\n", *(short*)good.c_str());
+
+  std::string bad = comp_test_write();
+  printf("got: %hx\n", *(short*)bad.c_str());
+
+  return good != bad;
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index 221f0dd3d578..cf37a1980c41 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -10330,6 +10330,8 @@ initializer_zerop (const_tree init)
       {
 	unsigned HOST_WIDE_INT idx;
 
+	if (TREE_CLOBBER_P (init))
+	  return false;
 	FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), idx, elt)
 	  if (!initializer_zerop (elt))
 	    return false;
-- 
GitLab