diff options
author | Richard Biener <rguenther@suse.de> | 2021-12-07 11:13:39 +0100 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2021-12-07 14:07:40 +0100 |
commit | 6e8a31275fda445fb3e8d98e53f5e1541f4727af (patch) | |
tree | 342d6984b35acf0f217c7ae5ad998a2f5c0bda78 /gcc/tree-ssa-propagate.c | |
parent | c93e704b9e0411f1db031df9716b9958307590e3 (diff) | |
download | gcc-6e8a31275fda445fb3e8d98e53f5e1541f4727af.zip gcc-6e8a31275fda445fb3e8d98e53f5e1541f4727af.tar.gz gcc-6e8a31275fda445fb3e8d98e53f5e1541f4727af.tar.bz2 |
tree-optimization/103596 - fix missed propagation into switches
may_propagate_copy unnecessarily restricts propagating non-abnormals
into places that currently contain an abnormal SSA name but are
not the PHI argument for an abnormal edge. This causes VN to
not elide a CFG path that it assumes is elided, resulting in
released SSA names in the IL.
The fix is to enhance the may_propagate_copy API to specify the
destination is _not_ a PHI argument. I chose to not update only
the relevant caller in VN and the may_propagate_copy_into_stmt API
at this point because this is a regression and needs backporting.
2021-12-07 Richard Biener <rguenther@suse.de>
PR tree-optimization/103596
* tree-ssa-sccvn.c (eliminate_dom_walker::eliminate_stmt):
Note we are not propagating into a PHI argument to may_propagate_copy.
* tree-ssa-propagate.h (may_propagate_copy): Add
argument specifying whether we propagate into a PHI arg.
* tree-ssa-propagate.c (may_propagate_copy): Likewise.
When not doing so we can replace an abnormal with
something else.
(may_propagate_into_stmt): Update may_propagate_copy calls.
(replace_exp_1): Move propagation checking code to
propagate_value and rename to ...
(replace_exp): ... this and elide previous wrapper.
(propagate_value): Perform checking with adjusted
may_propagate_copy call and dispatch to replace_exp.
* gcc.dg/torture/pr103596.c: New testcase.
Diffstat (limited to 'gcc/tree-ssa-propagate.c')
-rw-r--r-- | gcc/tree-ssa-propagate.c | 62 |
1 files changed, 24 insertions, 38 deletions
diff --git a/gcc/tree-ssa-propagate.c b/gcc/tree-ssa-propagate.c index 6d19410..1f2a17f 100644 --- a/gcc/tree-ssa-propagate.c +++ b/gcc/tree-ssa-propagate.c @@ -1042,10 +1042,12 @@ substitute_and_fold_engine::substitute_and_fold (basic_block block) } -/* Return true if we may propagate ORIG into DEST, false otherwise. */ +/* Return true if we may propagate ORIG into DEST, false otherwise. + If DEST_NOT_PHI_ARG_P is true then assume the propagation does + not happen into a PHI argument which relaxes some constraints. */ bool -may_propagate_copy (tree dest, tree orig) +may_propagate_copy (tree dest, tree orig, bool dest_not_phi_arg_p) { tree type_d = TREE_TYPE (dest); tree type_o = TREE_TYPE (orig); @@ -1065,8 +1067,10 @@ may_propagate_copy (tree dest, tree orig) && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig)) return false; /* Similarly if DEST flows in from an abnormal edge then the copy cannot be - propagated. */ - else if (TREE_CODE (dest) == SSA_NAME + propagated. If we know we do not propagate into a PHI argument this + does not apply. */ + else if (!dest_not_phi_arg_p + && TREE_CODE (dest) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (dest)) return false; @@ -1100,9 +1104,9 @@ may_propagate_copy_into_stmt (gimple *dest, tree orig) for the expression, so we delegate to may_propagate_copy. */ if (gimple_assign_single_p (dest)) - return may_propagate_copy (gimple_assign_rhs1 (dest), orig); + return may_propagate_copy (gimple_assign_rhs1 (dest), orig, true); else if (gswitch *dest_swtch = dyn_cast <gswitch *> (dest)) - return may_propagate_copy (gimple_switch_index (dest_swtch), orig); + return may_propagate_copy (gimple_switch_index (dest_swtch), orig, true); /* In other cases, the expression is not materialized, so there is no destination to pass to may_propagate_copy. On the other @@ -1140,25 +1144,19 @@ may_propagate_copy_into_asm (tree dest ATTRIBUTE_UNUSED) } -/* Common code for propagate_value and replace_exp. +/* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME). - Replace use operand OP_P with VAL. FOR_PROPAGATION indicates if the - replacement is done to propagate a value or not. */ + Use this version when not const/copy propagating values. For example, + PRE uses this version when building expressions as they would appear + in specific blocks taking into account actions of PHI nodes. -static void -replace_exp_1 (use_operand_p op_p, tree val, - bool for_propagation ATTRIBUTE_UNUSED) -{ - if (flag_checking) - { - tree op = USE_FROM_PTR (op_p); - gcc_assert (!(for_propagation - && TREE_CODE (op) == SSA_NAME - && TREE_CODE (val) == SSA_NAME - && !may_propagate_copy (op, val))); - } + The statement in which an expression has been replaced should be + folded using fold_stmt_inplace. */ - if (TREE_CODE (val) == SSA_NAME) +void +replace_exp (use_operand_p op_p, tree val) +{ + if (TREE_CODE (val) == SSA_NAME || CONSTANT_CLASS_P (val)) SET_USE (op_p, val); else SET_USE (op_p, unshare_expr (val)); @@ -1174,22 +1172,10 @@ replace_exp_1 (use_operand_p op_p, tree val, void propagate_value (use_operand_p op_p, tree val) { - replace_exp_1 (op_p, val, true); -} - -/* Replace *OP_P with value VAL (assumed to be a constant or another SSA_NAME). - - Use this version when not const/copy propagating values. For example, - PRE uses this version when building expressions as they would appear - in specific blocks taking into account actions of PHI nodes. - - The statement in which an expression has been replaced should be - folded using fold_stmt_inplace. */ - -void -replace_exp (use_operand_p op_p, tree val) -{ - replace_exp_1 (op_p, val, false); + if (flag_checking) + gcc_assert (may_propagate_copy (USE_FROM_PTR (op_p), val, + !is_a <gphi *> (USE_STMT (op_p)))); + replace_exp (op_p, val); } |