diff mbox series

[3/8] ipa: Skip type conversions in jump function constructions

Message ID ri6fro6q6o8.fsf@virgil.suse.cz
State New
Headers show
Series [1/8] ipa: Fix jump function copying | expand

Commit Message

Martin Jambor Nov. 5, 2024, 11:08 a.m. UTC
Hi,

originally, we did not stream any formal parameter types into WPA and
were generally very conservative when it came to type mismatches in
IPA-CP.  Over the time, mismatches that happen in code and blew up in
WPA made us be much more resilient and also stream the types of the
parameters which we now use commonly.

With that information, we can skip conversions when looking at the IL
from which we build jump functions because we can check that they are
indeed OK and emulate them with fold_convert or, if not, at least deal
with the undefined behavior input gracefully.

With this change, we can nicely propagate non-NULLness in IPA-VR as
demonstrated with the new test case.

I have gone through all other uses of (all components of) jump
functions which could be affected by this and verified they do indeed
check types and can handle mismatches.

Bootstrapped and tested on x86_64-linux, the whole patch series has
additionally passed LTO and profiled-LTO bootstrap on the same platform
and a bootstrap and testsuite on ppc64-linux.  Aarch64-linux bootstrap
and testing is in progress.  OK for master is that passes too?

Thanks,

Martin


gcc/ChangeLog:

2024-11-01  Martin Jambor  <mjambor@suse.cz>

	* ipa-prop.cc (skip_a_conversion_op): New function.
	(ipa_compute_jump_functions_for_edge): Use it.

gcc/testsuite/ChangeLog:

2024-11-01  Martin Jambor  <mjambor@suse.cz>

	* gcc.dg/ipa/vrp9.c: New test.
---
 gcc/ipa-prop.cc                 | 20 ++++++++++++++
 gcc/testsuite/gcc.dg/ipa/vrp9.c | 48 +++++++++++++++++++++++++++++++++
 2 files changed, 68 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/ipa/vrp9.c

Comments

Aldy Hernandez Nov. 5, 2024, 11:57 a.m. UTC | #1
Martin Jambor <mjambor@suse.cz> writes:

> +/* If T is an SSA_NAME that is a result of a simple type conversion statement,

I think "the result" sounds better than "a result", assuming there is
just one result.

> +   return the operand of that conversion, otherwise treturn T. */

s/treturn/return/

Aldy
diff mbox series

Patch

diff --git a/gcc/ipa-prop.cc b/gcc/ipa-prop.cc
index db8eda8c361..9bd2e4bc60c 100644
--- a/gcc/ipa-prop.cc
+++ b/gcc/ipa-prop.cc
@@ -2305,6 +2305,25 @@  ipa_set_jfunc_vr (ipa_jump_func *jf, const ipa_vr &vr)
   ipa_set_jfunc_vr (jf, tmp);
 }
 
+
+/* If T is an SSA_NAME that is a result of a simple type conversion statement,
+   return the operand of that conversion, otherwise treturn T. */
+
+static tree
+skip_a_conversion_op (tree t)
+{
+  if (TREE_CODE (t) != SSA_NAME
+      || SSA_NAME_IS_DEFAULT_DEF (t))
+    return t;
+
+  gimple *def = SSA_NAME_DEF_STMT (t);
+  if (!is_gimple_assign (def)
+      || !CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def)))
+    return t;
+
+  return gimple_assign_rhs1 (def);
+}
+
 /* Compute jump function for all arguments of callsite CS and insert the
    information in the jump_functions array in the ipa_edge_args corresponding
    to this callsite.  */
@@ -2409,6 +2428,7 @@  ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
 	    gcc_assert (!jfunc->m_vr);
 	}
 
+      arg = skip_a_conversion_op (arg);
       if (is_gimple_ip_invariant (arg)
 	  || (VAR_P (arg)
 	      && is_global_var (arg)
diff --git a/gcc/testsuite/gcc.dg/ipa/vrp9.c b/gcc/testsuite/gcc.dg/ipa/vrp9.c
new file mode 100644
index 00000000000..461a2e757d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/vrp9.c
@@ -0,0 +1,48 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized"  }  */
+
+int some_f1 (int);
+int some_f2 (int);
+int some_f3 (int);
+
+void remove_this_call ();
+
+int g;
+
+static int __attribute__((noinline))
+bar (int p)
+{
+  if (p)
+    remove_this_call ();
+  return g++;
+}
+
+static int __attribute__((noinline))
+foo (int (*f)(int))
+{
+  return bar (f == (void *)0);
+}
+
+int
+baz1 (void)
+{
+  int (*f)(int);
+  if (g)
+    f = some_f1;
+  else
+    f = some_f2;
+  return foo (f);
+}
+
+int
+baz2 (void)
+{
+  int (*f)(int);
+  if (g)
+    f = some_f2;
+  else
+    f = some_f3;
+  return foo (f);
+}
+
+/* { dg-final { scan-tree-dump-not "remove_this_call"  "optimized"  } } */