diff options
author | Richard Biener <rguenther@suse.de> | 2022-04-04 12:23:28 +0200 |
---|---|---|
committer | Richard Biener <rguenther@suse.de> | 2022-04-06 08:14:32 +0200 |
commit | fc8d9e4497032dd295aac9414042163f92250b77 (patch) | |
tree | bd172e4343876777a8ce284a87187ce5d4213262 /gcc/gimple-fold.h | |
parent | e2a818641ba5d07ebe2c241906896c4886910d18 (diff) | |
download | gcc-fc8d9e4497032dd295aac9414042163f92250b77.zip gcc-fc8d9e4497032dd295aac9414042163f92250b77.tar.gz gcc-fc8d9e4497032dd295aac9414042163f92250b77.tar.bz2 |
tree-optimization/105142 - wrong code with maybe_fold_{and,or}_comparisons
The following avoids expanding definitions in regions conditionally
executed under the condition A when simplifying A && B or A || B.
This is done by passing down the basic-block of the outer condition
to maybe_fold_{and,or}_comparisons, through the various helpers
in gimple-fold.cc that might call back to maybe_fold_{and,or}_comparisons
and ultimatively to maybe_fold_comparisons_from_match_pd where the
fix is to provide a custom valueization hook to
gimple_match_op::resimplify that avoids looking at definitions
that do not dominate the outer block.
For the testcase this avoids combining a stmt that invokes undefined
integer overflow when the outer condition is false but it also
aovids combining stmts with range information that is derived from
the outer condition.
The new parameter to maybe_fold_{and,or}_comparisons is defaulted
to nullptr and I only adjusted the if-combine to pass down the
outer block. I think other callers like tree-if-conv have the
same issue but it's not straight-forward as to what to do there.
2022-04-05 Richard Biener <rguenther@suse.de>
PR tree-optimization/105142
* gimple-fold.h (maybe_fold_and_comparisons): Add defaulted
basic-block parameter.
(maybe_fold_or_comparisons): Likewise.
* gimple-fold.cc (follow_outer_ssa_edges): New.
(maybe_fold_comparisons_from_match_pd): Use follow_outer_ssa_edges
when an outer condition basic-block is specified.
(and_comparisons_1, and_var_with_comparison,
and_var_with_comparison_1, or_comparisons_1,
or_var_with_comparison, or_var_with_comparison_1): Receive and pass
down the outer condition basic-block.
* tree-ssa-ifcombine.cc (ifcombine_ifandif): Pass down the
basic-block of the outer condition.
* g++.dg/torture/pr105142.C: New testcase.
Diffstat (limited to 'gcc/gimple-fold.h')
-rw-r--r-- | gcc/gimple-fold.h | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h index 82631a4..3a0ef54 100644 --- a/gcc/gimple-fold.h +++ b/gcc/gimple-fold.h @@ -33,9 +33,11 @@ extern bool fold_stmt (gimple_stmt_iterator *); extern bool fold_stmt (gimple_stmt_iterator *, tree (*) (tree)); extern bool fold_stmt_inplace (gimple_stmt_iterator *); extern tree maybe_fold_and_comparisons (tree, enum tree_code, tree, tree, - enum tree_code, tree, tree); + enum tree_code, tree, tree, + basic_block = nullptr); extern tree maybe_fold_or_comparisons (tree, enum tree_code, tree, tree, - enum tree_code, tree, tree); + enum tree_code, tree, tree, + basic_block = nullptr); extern bool clear_padding_type_may_have_padding_p (tree); extern void clear_type_padding_in_mask (tree, unsigned char *); extern bool optimize_atomic_compare_exchange_p (gimple *); |