Hi,
malloc_candidate_p() in ipa-pure-const misses detecting that a
function is malloc-like if the  return value is result of PHI and one
of the arguments of PHI is 0.
For example:

void g(unsigned n)
{
  return (n) ? __builtin_malloc (n) : 0;
}

The reason is that the following check:
if (TREE_CODE (arg) != SSA_NAME)
  DUMP_AND_RETURN ("phi arg is not SSA_NAME.")

fails for arg with constant value 0 and malloc_candidate_p returns false.
The patch simply skips the arg if it equals null_pointer_node.
Does it look OK ?

One concern I have is that with the patch, malloc_candidate_p will
return true if all the args to PHI are NULL:
retval = PHI<0, 0>
return retval

However I expect that PHI with all 0 args would be constant folded to
0 earlier, so this case shouldn't occur in practice ?

Bootstrapped+tested on x86_64-unknown-linux-gnu.
Cross-testing on arm*-*-* and aarch64*-*-* in progress.

Thanks,
Prathamesh
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 09ca3590039..0406d5588d2 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -910,7 +910,8 @@ malloc_candidate_p (function *fun, bool ipa)
 #define DUMP_AND_RETURN(reason)  \
 {  \
   if (dump_file && (dump_flags & TDF_DETAILS))  \
-    fprintf (dump_file, "%s", (reason));  \
+    fprintf (dump_file, "\n%s is not a malloc candidate, reason: %s\n", \
+            (node->name()), (reason));  \
   return false;  \
 }
 
@@ -961,11 +962,14 @@ malloc_candidate_p (function *fun, bool ipa)
        for (unsigned i = 0; i < gimple_phi_num_args (phi); ++i)
          {
            tree arg = gimple_phi_arg_def (phi, i);
+           if (arg == null_pointer_node)
+             continue;
+
            if (TREE_CODE (arg) != SSA_NAME)
-             DUMP_AND_RETURN("phi arg is not SSA_NAME.")
-           if (!(arg == null_pointer_node || check_retval_uses (arg, phi)))
-             DUMP_AND_RETURN("phi arg has uses outside phi"
-                             " and comparisons against 0.")
+             DUMP_AND_RETURN ("phi arg is not SSA_NAME.");
+           if (!check_retval_uses (arg, phi))
+             DUMP_AND_RETURN ("phi arg has uses outside phi"
+                              " and comparisons against 0.")
 
            gimple *arg_def = SSA_NAME_DEF_STMT (arg);
            gcall *call_stmt = dyn_cast<gcall *> (arg_def);
diff --git a/gcc/testsuite/gcc.dg/ipa/pr83648.c 
b/gcc/testsuite/gcc.dg/ipa/pr83648.c
new file mode 100644
index 00000000000..03b45de671b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr83648.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-local-pure-const-details" } */
+
+void *g(unsigned n)
+{
+  return n ? __builtin_malloc (n) : 0;
+}
+
+/* { dg-final { scan-tree-dump "Function found to be malloc: g" 
"local-pure-const1" } } */

Reply via email to