tree-optimization/105142 - wrong code with maybe_fold_{and,or}_comparisons
authorRichard Biener <rguenther@suse.de>
Mon, 4 Apr 2022 10:23:28 +0000 (12:23 +0200)
committerRichard Biener <rguenther@suse.de>
Wed, 6 Apr 2022 06:14:32 +0000 (08:14 +0200)
commitfc8d9e4497032dd295aac9414042163f92250b77
treebd172e4343876777a8ce284a87187ce5d4213262
parente2a818641ba5d07ebe2c241906896c4886910d18
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.
gcc/gimple-fold.cc
gcc/gimple-fold.h
gcc/testsuite/g++.dg/torture/pr105142.C [new file with mode: 0644]
gcc/tree-ssa-ifcombine.cc