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