Hi, while hunting the streaming bug of ipa-bit-cp which exchanged value and mark while streaming to ltrans I noticed that this bug had almost no effect because we almost always throw away the relevant info.
This patch makes tree-ssa-ccp to use results of ipa-bit-cp so the value is actually used. It also tests ipa-param-manipulation infrastructure (implemented by Martin Jambor) for fixing the issue with aggregate propagation being ignored in many cases. Bootstrapped/regtested x86_64-linux, plan to commit it later today if there are no complains. Honza * ipa-param-manipulation.h (get_original_index): Declare. * ipa-param-manipulation.c (ipa_param_adjustments::get_original_index): New member function. * ipa-prop.c (ipcp_get_parm_bits): New function. * ipa-prop.h (ipcp_get_parm_bits): Declare. * tree-ssa-ccp.c: Include cgraph.h, alloc-pool.h, symbol-summary.h, ipa-utils.h and ipa-prop.h (get_default_value): Use ipcp_get_parm_bits. * gcc.dg/ipa/ipa-bit-cp.c: New testcase. * gcc.dg/ipa/ipa-bit-cp-1.c: New testcase. * gcc.dg/ipa/ipa-bit-cp-2.c: New testcase. Index: ipa-param-manipulation.h =================================================================== --- ipa-param-manipulation.h (revision 279467) +++ ipa-param-manipulation.h (working copy) @@ -258,6 +258,9 @@ public: void get_surviving_params (vec<bool> *surviving_params); /* Fill a vector with new indices of surviving original parameters. */ void get_updated_indices (vec<int> *new_indices); + /* Return the original index for the given new parameter index. Return a + negative number if not available. */ + int get_original_index (int newidx); void dump (FILE *f); void debug (); Index: ipa-param-manipulation.c =================================================================== --- ipa-param-manipulation.c (revision 279467) +++ ipa-param-manipulation.c (working copy) @@ -324,6 +324,18 @@ ipa_param_adjustments::get_updated_indic } } +/* Return the original index for the given new parameter index. Return a + negative number if not available. */ + +int +ipa_param_adjustments::get_original_index (int newidx) +{ + const ipa_adjusted_param *adj = &(*m_adj_params)[newidx]; + if (adj->op != IPA_PARAM_OP_COPY) + return -1; + return adj->base_index; +} + /* Return true if the first parameter (assuming there was one) survives the transformation intact and remains the first one. */ Index: ipa-prop.c =================================================================== --- ipa-prop.c (revision 279467) +++ ipa-prop.c (working copy) @@ -5480,6 +5480,43 @@ ipcp_modif_dom_walker::before_dom_childr return NULL; } +/* Return true if we have recorded VALUE and MASK about PARM. + Set VALUE and MASk accordingly. */ + +bool +ipcp_get_parm_bits (tree parm, tree *value, widest_int *mask) +{ + cgraph_node *cnode = cgraph_node::get (current_function_decl); + ipcp_transformation *ts = ipcp_get_transformation_summary (cnode); + if (!ts || vec_safe_length (ts->bits) == 0) + return false; + + int i = 0; + for (tree p = DECL_ARGUMENTS (current_function_decl); + p != parm; p = DECL_CHAIN (p)) + { + i++; + /* Ignore static chain. */ + if (!p) + return false; + } + + if (cnode->clone.param_adjustments) + { + i = cnode->clone.param_adjustments->get_original_index (i); + if (i < 0) + return false; + } + + vec<ipa_bits *, va_gc> &bits = *ts->bits; + if (!bits[i]) + return false; + *mask = bits[i]->mask; + *value = wide_int_to_tree (TREE_TYPE (parm), bits[i]->value); + return true; +} + + /* Update bits info of formal parameters as described in ipcp_transformation. */ Index: ipa-prop.h =================================================================== --- ipa-prop.h (revision 279467) +++ ipa-prop.h (working copy) @@ -1041,6 +1041,7 @@ ipa_agg_value_set ipa_agg_value_set_from void ipa_dump_param (FILE *, class ipa_node_params *info, int i); void ipa_release_body_info (struct ipa_func_body_info *); tree ipa_get_callee_param_type (struct cgraph_edge *e, int i); +bool ipcp_get_parm_bits (tree, tree *, widest_int *); /* From tree-sra.c: */ tree build_ref_for_offset (location_t, tree, poly_int64, bool, tree, Index: tree-ssa-ccp.c =================================================================== --- tree-ssa-ccp.c (revision 279467) +++ tree-ssa-ccp.c (working copy) @@ -146,6 +146,11 @@ along with GCC; see the file COPYING3. #include "stringpool.h" #include "attribs.h" #include "tree-vector-builder.h" +#include "cgraph.h" +#include "alloc-pool.h" +#include "symbol-summary.h" +#include "ipa-utils.h" +#include "ipa-prop.h" /* Possible lattice values. */ typedef enum @@ -292,11 +297,26 @@ get_default_value (tree var) if (flag_tree_bit_ccp) { wide_int nonzero_bits = get_nonzero_bits (var); - if (nonzero_bits != -1) + tree value; + widest_int mask; + + if (SSA_NAME_VAR (var) + && TREE_CODE (SSA_NAME_VAR (var)) == PARM_DECL + && ipcp_get_parm_bits (SSA_NAME_VAR (var), &value, &mask)) + { + val.lattice_val = CONSTANT; + val.value = value; + val.mask = mask; + if (nonzero_bits != -1) + val.mask &= extend_mask (nonzero_bits, + TYPE_SIGN (TREE_TYPE (var))); + } + else if (nonzero_bits != -1) { val.lattice_val = CONSTANT; val.value = build_zero_cst (TREE_TYPE (var)); - val.mask = extend_mask (nonzero_bits, TYPE_SIGN (TREE_TYPE (var))); + val.mask = extend_mask (nonzero_bits, + TYPE_SIGN (TREE_TYPE (var))); } } } Index: testsuite/gcc.dg/ipa/ipa-bit-cp-1.c =================================================================== --- testsuite/gcc.dg/ipa/ipa-bit-cp-1.c (nonexistent) +++ testsuite/gcc.dg/ipa/ipa-bit-cp-1.c (working copy) @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -w -fipa-bit-cp" } */ +static int +__attribute__ ((noinline)) +test (int a) +{ + if (!(a&2)) + link_error (); +} +main() +{ + test (2); + test (3); + test (6); + return 0; +} Index: testsuite/gcc.dg/ipa/ipa-bit-cp-2.c =================================================================== --- testsuite/gcc.dg/ipa/ipa-bit-cp-2.c (nonexistent) +++ testsuite/gcc.dg/ipa/ipa-bit-cp-2.c (working copy) @@ -0,0 +1,19 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -w -fipa-bit-cp" } */ +static int +__attribute__ ((noinline)) +test (int __attribute__((unused)) b, int a) +{ + if (!(a&2)) + link_error (); +} + +extern int __attribute__((const)) getint (); + +main() +{ + test (getint(), 2); + test (getint(), 3); + test (getint(), 6); + return 0; +} Index: testsuite/gcc.dg/ipa/ipa-bit-cp.c =================================================================== --- testsuite/gcc.dg/ipa/ipa-bit-cp.c (nonexistent) +++ testsuite/gcc.dg/ipa/ipa-bit-cp.c (working copy) @@ -0,0 +1,16 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -w -fipa-bit-cp" } */ +static int +__attribute__ ((noinline)) +test (int a) +{ + if (!(a&2)) + link_error (); +} +main() +{ + test (2); + test (3); + test (6); + return 0; +}