g++ 13.0.0 20220529 snapshot (g:58a40e76ebadce78639644cd3d56e42b68336927) ICEs when compiling the following testcase, reduced from gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c, w/ -O2 -fstrict-enums --param case-values-threshold=1: typedef int basic_block; enum gimple_code {}; struct omp_region { omp_region *outer; basic_block cont; }; void oof (void); void build_omp_regions_1 (omp_region *parent, basic_block bb, gimple_code code) { if (code == 2) parent = parent->outer; else if (code != 0) parent->cont = bb; if (parent) oof (); } % g++-13.0.0 -O2 -fstrict-enums --param case-values-threshold=1 -c bx6eiilz.c during GIMPLE pass: threadfull bx6eiilz.c: In function 'void build_omp_regions_1(omp_region*, basic_block, gimple_code)': bx6eiilz.c:14:1: internal compiler error: in invert, at value-range.cc:1971 14 | build_omp_regions_1 (omp_region *parent, basic_block bb, gimple_code code) | ^~~~~~~~~~~~~~~~~~~ 0x88b323 irange::invert() /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/value-range.cc:1971 0x1f574f2 gimple_outgoing_range::calc_switch_ranges(gswitch*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range-edge.cc:148 0x1f57bbd gimple_outgoing_range::get_edge_range(irange&, gimple*, edge_def*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range-edge.cc:106 0x1f57ef4 gimple_outgoing_range::edge_range_p(irange&, edge_def*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range-edge.cc:212 0x1f61f7f gori_compute::outgoing_edge_range_p(irange&, edge_def*, tree_node*, range_query&) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range-gori.cc:1255 0x1f54dc9 ranger_cache::edge_range(irange&, edge_def*, tree_node*, ranger_cache::rfd_mode) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range-cache.cc:951 0x1f51ce4 gimple_ranger::range_on_edge(irange&, edge_def*, tree_node*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range.cc:240 0x1372f84 path_range_query::ssa_range_in_phi(irange&, gphi*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range-path.cc:323 0x1372a35 path_range_query::range_defined_in_block(irange&, tree_node*, basic_block_def*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range-path.cc:350 0x137318b path_range_query::compute_ranges_in_phis(basic_block_def*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range-path.cc:393 0x13733d4 path_range_query::compute_ranges_in_block(basic_block_def*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range-path.cc:442 0x13739a9 path_range_query::compute_ranges(vec<basic_block_def*, va_heap, vl_ptr> const&, bitmap_head const*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/gimple-range-path.cc:656 0x13f8e10 back_threader::find_taken_edge_cond(vec<basic_block_def*, va_heap, vl_ptr> const&, gcond*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/tree-ssa-threadbackward.cc:319 0x13f97ef back_threader::maybe_register_path() /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/tree-ssa-threadbackward.cc:232 0x13f9fac back_threader::find_paths_to_names(basic_block_def*, bitmap_head*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/tree-ssa-threadbackward.cc:419 0x13fa137 back_threader::resolve_phi(gphi*, bitmap_head*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/tree-ssa-threadbackward.cc:396 0x13fa137 back_threader::resolve_phi(gphi*, bitmap_head*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/tree-ssa-threadbackward.cc:356 0x13f9ef4 back_threader::find_paths_to_names(basic_block_def*, bitmap_head*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/tree-ssa-threadbackward.cc:444 0x13fa30a back_threader::find_paths(basic_block_def*, tree_node*) /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/tree-ssa-threadbackward.cc:493 0x13fa541 back_threader::thread_blocks() /var/tmp/portage/sys-devel/gcc-13.0.0_p20220529/work/gcc-13-20220529/gcc/tree-ssa-threadbackward.cc:901
#1 0x0000000001ced6a0 in irange::invert (this=0x7fffffff1f30) at /space/rguenther/src/gcc/gcc/value-range.cc:2166 2166 gcc_checking_assert (!undefined_p () && !varying_p ()); well, invert(undefined) = varying, invert(varying) = undefined - not sure why we assert here. (undefined is another name for 'empty') I've wondered of several places checking for undefined/varying before calling .invert () ...
Lets see try to remember.... it can be ambiguous. The inversion of undefined is not necessarily expected to be varying in all circumstances.. Likewise, inverting varying is still varying in some circumstances and data flow. It depends on how you are using it. Thus the onus is put on the caller to check for undefined or varying and do exactly what they expect it to do in their circumstance. I probably should have documented it at the time. Also you argued against undefined having a type, so there is no type to invert an undefined to varying with.
Hmmm, all three of us had a conversation on this particular topic. Initially I had coded it to so that VARYING / UNDEFINED were inverses of each other and y'all convinced me otherwise ;-). I can't find the conversation though.
Well, thats not really the problem here. We are casting [irange] gimple_code [2, 2] to a gimple_code, and getting: [irange] gimple_code VARYING Couple of issues.. one, we shouldnt bother casting anything if the types are already the same... but still.. the result is incorrect. Tracing it down, it looks like during the casting process, we call: operator_cast::inside_domain_p so see if a min == 2, max == 2, is inside the range of [irange] gimple_code VARYING. THe routine returns false because with strict enum on, we get the min and max of the domain from: wide_int domain_min = wi::to_wide (vrp_val_min (range.type ())); wide_int domain_max = wi::to_wide (vrp_val_max (range.type ()));, which boils down to TYPE_MIN_VALUE (gimple_code) and TYPE_MAX_VALUE (gimple_code) p range.type () $29 = (tree_node *) 0x7fffe9f77c78 (gdb) p print_generic_expr (stderr, $29, 0) gimple_code (gdb) p print_generic_expr (stderr, $29->type_non_common.minval, 0) 0 (gdb) p print_generic_expr (stderr, $29->type_non_common.maxval, 0) 1 So the min value for the enum is set correctly to 0, but the max is set to 1... thus the routine determines that [2, 2] is not within the range of [0, 1] and returns varying.. It seems like the max value for the enum is not being set correctly? If I check right at the point of the failure: (gdb) frame 1 #1 0x0000000001c9c4fe in irange::invert (this=0x7fffffff1570) at /home/gcc/master/gcc/gcc/value-range.cc:2185 2185 gcc_checking_assert (!undefined_p () && !varying_p ()); (gdb) p type() $42 = (tree_node *) 0x7fffe9f77c78 (gdb) p print_generic_expr (stderr, type(), 0) gimple_code (gdb) p print_generic_expr (stderr, type()->type_non_common.maxval, 0) 1
I cannot reproduce this ICE w/ the current gcc 13.0.0 20221016 snapshot (g:6366e3e8847af98d4728d55951534769d034d02a).
Fixed with r13-3085-gae56d600d223e996.
I believe it won't hurt to add a testcase to the test suite.
(In reply to Arseny Solokha from comment #7) > I believe it won't hurt to add a testcase to the test suite. Sure, Aldy can you please do that?
The master branch has been updated by Aldy Hernandez <aldyh@gcc.gnu.org>: https://gcc.gnu.org/g:01d7d459e433196b1faa4ee025a314266887fc59 commit r13-3336-g01d7d459e433196b1faa4ee025a314266887fc59 Author: Aldy Hernandez <aldyh@redhat.com> Date: Mon Oct 17 15:32:35 2022 +0200 [PR tree-optimization/105820] Add test. PR tree-optimization/105820 gcc/testsuite/ChangeLog: * g++.dg/tree-ssa/pr105820.c: New test.