public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Extend ipa-fnsummary to skip __builtin_expect
@ 2023-06-29 20:49 Jan Hubicka
  0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2023-06-29 20:49 UTC (permalink / raw)
  To: gcc-patches, jwakely

Compute ipa-predicates for conditionals involving __builtin_expect_p

std::vector allocator looks as follows:

__attribute__((nodiscard))
struct pair * std::__new_allocator<std::pair<unsigned int, unsigned int> >::allocate (struct __new_allocator * const this, size_type __n, const void * D.27753)
{
  bool _1;
  long int _2;
  long int _3;
  long unsigned int _5;
  struct pair * _9;

  <bb 2> [local count: 1073741824]:
  _1 = __n_7(D) > 1152921504606846975;
  _2 = (long int) _1;
  _3 = __builtin_expect (_2, 0);
  if (_3 != 0)
    goto <bb 3>; [10.00%]
  else
    goto <bb 6>; [90.00%]

  <bb 3> [local count: 107374184]:
  if (__n_7(D) > 2305843009213693951)
    goto <bb 4>; [50.00%]
  else
    goto <bb 5>; [50.00%]

  <bb 4> [local count: 53687092]:
  std::__throw_bad_array_new_length ();

  <bb 5> [local count: 53687092]:
  std::__throw_bad_alloc ();

  <bb 6> [local count: 966367641]:
  _5 = __n_7(D) * 8;
  _9 = operator new (_5);
  return _9;
}


So there is check for allocated block size being greater than max_size which is
wrapper in __builtin_expect.  This makes ipa-fnsummary to give up analyzing
predicates and it will miss the fact that the two different calls to __throw
will be optimized out if __n is larady smaller than 1152921504606846975 which
it is after _M_check_len.

This patch extends ipa-fnsummary to understand functions that return their
parameter.

We still do not get the value range propagated sicne _M_check_len is not
inlined early and ipa-prop misses return functions, but we get closer :)

Bootstrapped/regtested x86_64-linux, comitted.


gcc/ChangeLog:

	PR tree-optimization/109849
	* ipa-fnsummary.cc (decompose_param_expr): Skip
	functions returning its parameter.
	(set_cond_stmt_execution_predicate): Return early
	if predicate was constructed.

gcc/testsuite/ChangeLog:

	PR tree-optimization/109849
	* gcc.dg/ipa/pr109849.c: New test.

diff --git a/gcc/ipa-fnsummary.cc b/gcc/ipa-fnsummary.cc
index 78cbb60d056..a09f6305c63 100644
--- a/gcc/ipa-fnsummary.cc
+++ b/gcc/ipa-fnsummary.cc
@@ -1516,6 +1516,19 @@ decompose_param_expr (struct ipa_func_body_info *fbi,
 
       if (TREE_CODE (expr) != SSA_NAME || SSA_NAME_IS_DEFAULT_DEF (expr))
 	break;
+      stmt = SSA_NAME_DEF_STMT (expr);
+
+      if (gcall *call = dyn_cast <gcall *> (stmt))
+	{
+	  int flags = gimple_call_return_flags (call);
+	  if (!(flags & ERF_RETURNS_ARG))
+	    goto fail;
+	  int arg = flags & ERF_RETURN_ARG_MASK;
+	  if (arg >= (int)gimple_call_num_args (call))
+	    goto fail;
+	  expr = gimple_call_arg (stmt, arg);
+	  continue;
+	}
 
       if (!is_gimple_assign (stmt = SSA_NAME_DEF_STMT (expr)))
 	break;
@@ -1664,6 +1677,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
 	    }
 	}
       vec_free (param_ops);
+      return;
     }
 
   if (TREE_CODE (op) != SSA_NAME)
diff --git a/gcc/testsuite/gcc.dg/ipa/pr109849.c b/gcc/testsuite/gcc.dg/ipa/pr109849.c
new file mode 100644
index 00000000000..09b62f90d70
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr109849.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fdump-ipa-inline-details" } */
+void bad (void);
+void
+test(int a)
+{
+	if (__builtin_expect (a>3, 0))
+	{
+		bad ();
+		bad ();
+		bad ();
+		bad ();
+		bad ();
+		bad ();
+		bad ();
+		bad ();
+	}
+}
+void
+foo (int a)
+{
+	if (a>0)
+		__builtin_unreachable ();
+	test (a);
+}
+/* { dg-final { scan-ipa-dump "Inlined 2 calls" "inline"  } } */
+/* { dg-final { scan-ipa-dump "Inlining test" "inline"  } } */

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-29 20:49 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-29 20:49 Extend ipa-fnsummary to skip __builtin_expect Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).