PR80613

Prathamesh Kulkarni prathamesh.kulkarni@linaro.org
Thu May 4 16:03:00 GMT 2017


Hi,
As mentioned in PR, the issue is that cddce1 marks the call to
__builtin_strdup as necessary:
marking necessary through .MEM_6 stmt p_7 = __builtin_strdup (&d);

and since p_7 doesn't get added to worklist in propagate_necessity()
because it's used only within free(), it's treated as "dead"
and wrongly gets released.
The patch fixes that by adding strdup/strndup in corresponding condition
in eliminate_unnecessary_stmts().

Another issue, was that my previous patch failed to remove multiple
calls to strdup:
char *f(char **tt)
{
  char *t = *tt;
  char *p;

  p = __builtin_strdup (t);
  p = __builtin_strdup (t);
  return p;
}

That's fixed in patch by adding strdup/strndup to another
corresponding condition in propagate_necessity() so that only one
instance of strdup would be kept.

Bootstrapped+tested on x86_64-unknown-linux-gnu.
Cross-testing on arm*-*-* and aarch64*-*-* in progress.
OK to commit if testing passes ?

Thanks
Prathamesh
-------------- next part --------------
2017-05-04  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>

	PR tree-optimization/80613
	* tree-ssa-dce.c (propagate_necessity): Add cases for BUILT_IN_STRDUP
	and BUILT_IN_STRNDUP.
	* (eliminate_unnecessary_stmts): Likewise.

testsuite/
	* gcc.dg/tree-ssa/pr80613-1.c: New test-case.
	* gcc.dg/tree-ssa/pr80613-2.c: New test-case.

diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr80613-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr80613-1.c
new file mode 100644
index 00000000000..56176427922
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr80613-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+char *a(int);
+int b;
+
+void c() {
+  for (;;) {
+    char d = *a(b);
+    char *e = __builtin_strdup (&d);
+    __builtin_free(e);
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr80613-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr80613-2.c
new file mode 100644
index 00000000000..c58cc08d6c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr80613-2.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-cddce1" } */
+
+/* There should only be one instance of __builtin_strdup after cddce1.  */
+
+char *f(char **tt)
+{
+  char *t = *tt;
+  char *p;
+
+  p = __builtin_strdup (t);
+  p = __builtin_strdup (t);
+  return p;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_strdup" 1 "cddce1" } } */
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index e17659df91f..7c05f981307 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -852,7 +852,9 @@ propagate_necessity (bool aggressive)
 			  == BUILT_IN_ALLOCA_WITH_ALIGN)
 		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE
 		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE
-		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_ASSUME_ALIGNED))
+		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_ASSUME_ALIGNED
+		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_STRDUP
+		      || DECL_FUNCTION_CODE (callee) == BUILT_IN_STRNDUP))
 		continue;
 
 	      /* Calls implicitly load from memory, their arguments
@@ -1353,6 +1355,8 @@ eliminate_unnecessary_stmts (void)
 			  && DECL_FUNCTION_CODE (call) != BUILT_IN_MALLOC
 			  && DECL_FUNCTION_CODE (call) != BUILT_IN_CALLOC
 			  && DECL_FUNCTION_CODE (call) != BUILT_IN_ALLOCA
+			  && DECL_FUNCTION_CODE (call) != BUILT_IN_STRDUP
+			  && DECL_FUNCTION_CODE (call) != BUILT_IN_STRNDUP
 			  && (DECL_FUNCTION_CODE (call)
 			      != BUILT_IN_ALLOCA_WITH_ALIGN)))
 		  /* Avoid doing so for bndret calls for the same reason.  */


More information about the Gcc-patches mailing list