aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-fold.h
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2022-04-04 12:23:28 +0200
committerRichard Biener <rguenther@suse.de>2022-04-06 08:14:32 +0200
commitfc8d9e4497032dd295aac9414042163f92250b77 (patch)
treebd172e4343876777a8ce284a87187ce5d4213262 /gcc/gimple-fold.h
parente2a818641ba5d07ebe2c241906896c4886910d18 (diff)
downloadgcc-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.h6
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 *);