@@ -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)
new file mode 100644
@@ -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" } } */