range-op-float: Fix up ICE in lower_bound [PR107975]
Checks
Commit Message
Hi!
According to https://gcc.gnu.org/pipermail/gcc-regression/2022-December/077258.html
my patch caused some ICEs, e.g. the following testcase ICEs.
The problem is that lower_bound and upper_bound methods on a france assert
that the range isn't VR_NAN or VR_UNDEFINED.
All the op1_range/op2_range methods already return early if lhs.undefined_p,
but the other cases (when lhs is VR_NAN or the other opN is VR_NAN or
VR_UNDEFINED) aren't. float_binary_op_range_finish will DTRT for those
cases already.
Ok for trunk if this passes bootstrap/regtest?
2022-12-05 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/107975
* range-op-float.cc (foperator_mult::op1_range,
foperator_div::op1_range, foperator_div::op2_range): Just
return float_binary_op_range_finish result if lhs is known
NAN, or the other operand is known NAN or UNDEFINED.
* gcc.dg/pr107975.c: New test.
Jakub
Comments
On Mon, 5 Dec 2022, Jakub Jelinek wrote:
> Hi!
>
> According to https://gcc.gnu.org/pipermail/gcc-regression/2022-December/077258.html
> my patch caused some ICEs, e.g. the following testcase ICEs.
> The problem is that lower_bound and upper_bound methods on a france assert
> that the range isn't VR_NAN or VR_UNDEFINED.
> All the op1_range/op2_range methods already return early if lhs.undefined_p,
> but the other cases (when lhs is VR_NAN or the other opN is VR_NAN or
> VR_UNDEFINED) aren't. float_binary_op_range_finish will DTRT for those
> cases already.
>
> Ok for trunk if this passes bootstrap/regtest?
OK.
Richard.
> 2022-12-05 Jakub Jelinek <jakub@redhat.com>
>
> PR tree-optimization/107975
> * range-op-float.cc (foperator_mult::op1_range,
> foperator_div::op1_range, foperator_div::op2_range): Just
> return float_binary_op_range_finish result if lhs is known
> NAN, or the other operand is known NAN or UNDEFINED.
>
> * gcc.dg/pr107975.c: New test.
>
> --- gcc/range-op-float.cc.jj 2022-12-05 11:17:34.900573272 +0100
> +++ gcc/range-op-float.cc 2022-12-05 17:58:38.059754128 +0100
> @@ -2146,6 +2146,8 @@ public:
> bool ret = rdiv.fold_range (r, type, lhs, op2);
> if (ret == false)
> return false;
> + if (lhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
> + return float_binary_op_range_finish (ret, r, type, lhs);
> const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
> const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
> const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
> @@ -2296,6 +2298,8 @@ public:
> bool ret = fop_mult.fold_range (r, type, lhs, op2);
> if (!ret)
> return ret;
> + if (lhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
> + return float_binary_op_range_finish (ret, r, type, lhs);
> const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
> const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
> const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
> @@ -2325,6 +2329,8 @@ public:
> bool ret = fold_range (r, type, op1, lhs);
> if (!ret)
> return ret;
> + if (lhs.known_isnan () || op1.known_isnan () || op1.undefined_p ())
> + return float_binary_op_range_finish (ret, r, type, lhs);
> const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
> const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
> const REAL_VALUE_TYPE &op1_lb = op1.lower_bound ();
> --- gcc/testsuite/gcc.dg/pr107975.c.jj 2022-12-05 19:15:56.518851401 +0100
> +++ gcc/testsuite/gcc.dg/pr107975.c 2022-12-05 19:15:04.014620281 +0100
> @@ -0,0 +1,15 @@
> +/* PR tree-optimization/107975 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +/* { dg-add-options ieee } */
> +
> +double
> +foo (double x, double y)
> +{
> + if (x == 42.0)
> + return 1.0;
> + double r = x * y;
> + if (!__builtin_isnan (r))
> + __builtin_unreachable ();
> + return r;
> +}
>
> Jakub
>
>
On 12/5/22 19:35, Jakub Jelinek via Gcc-patches wrote:
> Hi!
>
> According to https://gcc.gnu.org/pipermail/gcc-regression/2022-December/077258.html
Seen in the wild too - compiling one of the two weather forecasting
programs I use:
during GIMPLE pass: dom
/home/toon/scratch/hm_home/my_CY46h1/lib/src/surfex/ASSIM/assim_nature_isba_ekf.F90:5:32:
5 | SUBROUTINE ASSIM_NATURE_ISBA_EKF (KMYPROC, IO, S, K, NP, NPE,
HPROGRAM, KI, PT2M, PHU2M, HTEST)
| ^
internal compiler error: in lower_bound, at value-range.h:350
[ 72%] Building Fortran object
surfex/CMakeFiles/surfex-core-static.dir/OFFLIN/open_close_bin_asc_forc.F90.o
[ 72%] Building Fortran object
surfex/CMakeFiles/surfex-core-static.dir/OFFLIN/open_filein_ol.F90.o
[ 72%] Building Fortran object
surfex/CMakeFiles/surfex-core-static.dir/OFFLIN/sfx_oasis_def_ol.F90.o
[ 72%] Building Fortran object
surfex/CMakeFiles/surfex-core-static.dir/SURFEX/abor1_sfx.F90.o
[ 72%] Building Fortran object
surfex/CMakeFiles/surfex-core-static.dir/SURFEX/albedo.F90.o
[ 72%] Building Fortran object
surfex/CMakeFiles/surfex-core-static.dir/SURFEX/allocate_physio.F90.o
[ 72%] Building Fortran object
surfex/CMakeFiles/surfex-core-static.dir/SURFEX/allocate_teb_veg.F90.o
0x7db1c4 frange::lower_bound() const [clone .part.0] [clone .lto_priv.0]
[clone .lto_priv.0]
/home/toon/compilers/gcc/gcc/value-range.h:350
[ 72%] Building Fortran object
surfex/CMakeFiles/surfex-core-static.dir/SURFEX/allocate_teb_veg_pgd.F90.o
[ 72%] Building Fortran object
surfex/CMakeFiles/surfex-core-static.dir/SURFEX/average2_cover.F90.o
0x83f204 frange::lower_bound() const
/home/toon/compilers/gcc/gcc/value-range.h:1127
0x83f204 foperator_mult::op1_range(frange&, tree_node*, frange const&,
frange const&, relation_trio) const
/home/toon/compilers/gcc/gcc/range-op-float.cc:2149
[ 72%] Building Fortran object
surfex/CMakeFiles/surfex-core-static.dir/SURFEX/average2_mesh.F90.o
0x1ab62f8 gori_compute::compute_operand1_range(vrange&,
gimple_range_op_handler&, vrange const&, tree_node*, fur_source&,
value_relation*)
/home/toon/compilers/gcc/gcc/gimple-range-gori.cc:1095
0x1ab4f93 gori_compute::compute_operand_range(vrange&, gimple*, vrange
const&, tree_node*, fur_source&, value_relation*)
/home/toon/compilers/gcc/gcc/gimple-range-gori.cc:692
0x1ab6378 gori_compute::compute_operand1_range(vrange&,
gimple_range_op_handler&, vrange const&, tree_node*, fur_source&,
value_relation*)
/home/toon/compilers/gcc/gcc/gimple-range-gori.cc:1150
0x1ab4f93 gori_compute::compute_operand_range(vrange&, gimple*, vrange
const&, tree_node*, fur_source&, value_relation*)
/home/toon/compilers/gcc/gcc/gimple-range-gori.cc:692
0x1ac5861 gori_compute::outgoing_edge_range_p(vrange&, edge_def*,
tree_node*, range_query&)
/home/toon/compilers/gcc/gcc/gimple-range-gori.cc:1373
0x1ac668e ranger_cache::edge_range(vrange&, edge_def*, tree_node*,
ranger_cache::rfd_mode)
/home/toon/compilers/gcc/gcc/gimple-range-cache.cc:964
0x1acef14 gimple_ranger::range_on_edge(vrange&, edge_def*, tree_node*)
/home/toon/compilers/gcc/gcc/gimple-range.cc:241
0x1ab9902 fold_using_range::range_of_phi(vrange&, gphi*, fur_source&)
/home/toon/compilers/gcc/gcc/gimple-range-fold.cc:759
0x1ac5240 fold_using_range::fold_stmt(vrange&, gimple*, fur_source&,
tree_node*)
/home/toon/compilers/gcc/gcc/gimple-range-fold.cc:491
0x1ac813e gimple_ranger::fold_range_internal(vrange&, gimple*, tree_node*)
/home/toon/compilers/gcc/gcc/gimple-range.cc:257
0x1ac813e gimple_ranger::prefill_stmt_dependencies(tree_node*)
/home/toon/compilers/gcc/gcc/gimple-range.cc:392
0x1ac88ba gimple_ranger::range_of_stmt(vrange&, gimple*, tree_node*)
/home/toon/compilers/gcc/gcc/gimple-range.cc:314
0x1ace076 gimple_ranger::range_on_entry(vrange&, basic_block_def*,
tree_node*)
/home/toon/compilers/gcc/gcc/gimple-range.cc:153
0x115d524 path_range_query::internal_range_of_expr(vrange&, tree_node*,
gimple*)
/home/toon/compilers/gcc/gcc/gimple-range-path.cc:176
0x115d6b0 path_range_query::range_of_expr(vrange&, tree_node*, gimple*)
/home/toon/compilers/gcc/gcc/gimple-range-path.cc:202
0x1ac3f4a fold_using_range::range_of_range_op(vrange&,
gimple_range_op_handler&, fur_source&)
/home/toon/compilers/gcc/gcc/gimple-range-fold.cc:558
0x1ac50ba fold_using_range::fold_stmt(vrange&, gimple*, fur_source&,
tree_node*)
/home/toon/compilers/gcc/gcc/gimple-range-fold.cc:489
Please submit a full bug report, with preprocessed source (by using
-freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
@@ -2146,6 +2146,8 @@ public:
bool ret = rdiv.fold_range (r, type, lhs, op2);
if (ret == false)
return false;
+ if (lhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
+ return float_binary_op_range_finish (ret, r, type, lhs);
const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
@@ -2296,6 +2298,8 @@ public:
bool ret = fop_mult.fold_range (r, type, lhs, op2);
if (!ret)
return ret;
+ if (lhs.known_isnan () || op2.known_isnan () || op2.undefined_p ())
+ return float_binary_op_range_finish (ret, r, type, lhs);
const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
const REAL_VALUE_TYPE &op2_lb = op2.lower_bound ();
@@ -2325,6 +2329,8 @@ public:
bool ret = fold_range (r, type, op1, lhs);
if (!ret)
return ret;
+ if (lhs.known_isnan () || op1.known_isnan () || op1.undefined_p ())
+ return float_binary_op_range_finish (ret, r, type, lhs);
const REAL_VALUE_TYPE &lhs_lb = lhs.lower_bound ();
const REAL_VALUE_TYPE &lhs_ub = lhs.upper_bound ();
const REAL_VALUE_TYPE &op1_lb = op1.lower_bound ();
@@ -0,0 +1,15 @@
+/* PR tree-optimization/107975 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-add-options ieee } */
+
+double
+foo (double x, double y)
+{
+ if (x == 42.0)
+ return 1.0;
+ double r = x * y;
+ if (!__builtin_isnan (r))
+ __builtin_unreachable ();
+ return r;
+}