[Bug tree-optimization/99296] [11 Regression] ICE:in irange_set_anti_range, at value-range.cc:205 with "-Os -fno-toplevel-reorder -fno-tree-bit-ccp" since r11-5105-ga5f9c27bfc441722
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99296 Aldy Hernandez changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |aldyh at gcc dot gnu.org --- Comment #2 from Aldy Hernandez --- I'll take a look.
[Bug tree-optimization/99296] [11 Regression] ICE:in irange_set_anti_range, at value-range.cc:205 with "-Os -fno-toplevel-reorder -fno-tree-bit-ccp" since r11-5105-ga5f9c27bfc441722
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99296 --- Comment #5 from Aldy Hernandez --- Created attachment 50420 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=50420&action=edit proposed patch As Jakub has mentioned, this is a problem with signed 1-bit precision. Legacy anti-ranges has special cased this scenario, so I've adapted out some common logic both alternatives can use. Testing in progress.
[Bug tree-optimization/99296] [11 Regression] ICE:in irange_set_anti_range, at value-range.cc:205 with "-Os -fno-toplevel-reorder -fno-tree-bit-ccp" since r11-5105-ga5f9c27bfc441722
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99296 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #7 from Aldy Hernandez --- Fixed in trunk.
[Bug tree-optimization/100081] [11 Regression] Compile time hog in irange since r11-4135-ge864d395b4e862ce
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100081 --- Comment #5 from Aldy Hernandez --- (In reply to Richard Biener from comment #4) > Or > > bool > irange::symbolic_p () const > { > return (!varying_p () > && !undefined_p () > && (!is_gimple_min_invariant (min ()) > || !is_gimple_min_invariant (max (; > } > > which should be simply > > bool > irange::symbolic_p () const > { > return (m_num_ranges == 1 > && (!is_gimple_min_invariant (min ()) > || !is_gimple_min_invariant (max (; > } > > ? Or do we have symbolic anti ranges represented with two ranges? > > Likewise > > bool > irange::constant_p () const > { > return (!varying_p () > && !undefined_p () > && TREE_CODE (min ()) == INTEGER_CST > && TREE_CODE (max ()) == INTEGER_CST); > } > > err - I thought varying == constant... Those varying_p checks definitely look suspect. You should be able to just look at the min/max as you suggest. However, the undefined_p check must stay because it is really a check for num_ranges > 0, otherwise in the case of undefined_p, the is_gimple_*_invariant would dereference m_base[] which has nothing of interest. Perhaps a more obvious check would be m_num_ranges > 0, instead of the confusing undefined_p.
[Bug tree-optimization/100081] [11 Regression] Compile time hog in irange since r11-4135-ge864d395b4e862ce
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100081 --- Comment #6 from Aldy Hernandez --- BTW, we're looking as to why there are so many calls to varying_p. Something seems off.
[Bug tree-optimization/97359] [11 Regression] ice in logical_combine, at gimple-range-gori.cc:754
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97359 --- Comment #4 from Aldy Hernandez --- Created attachment 49340 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49340&action=edit untested proposed patch Untested.
[Bug tree-optimization/97359] [11 Regression] ice in logical_combine, at gimple-range-gori.cc:754
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97359 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #6 from Aldy Hernandez --- fixed
[Bug tree-optimization/97371] [11 Regression] evrp problem with gcc.target/s390/pr77822-2.c and -O3
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97371 Aldy Hernandez changed: What|Removed |Added Last reconfirmed||2020-10-12 Assignee|unassigned at gcc dot gnu.org |aldyh at gcc dot gnu.org Status|UNCONFIRMED |NEW Ever confirmed|0 |1 CC||amacleod at redhat dot com --- Comment #2 from Aldy Hernandez --- Confirmed. operator_rshift::op1_range is creating a range with swapped operand when the shift amount is >= precision: //LHS // 0111 = OP1 >> 3 // // OP1 is anything from 0011 1000 to 0011 . That is, a // range from LHS<<3 plus a mask of the 3 bits we shifted on the // right hand side (0x07). tree mask = fold_build1 (BIT_NOT_EXPR, type, fold_build2 (LSHIFT_EXPR, type, build_minus_one_cst (type), shift)); int_range_max mask_range (build_zero_cst (type), mask);
[Bug tree-optimization/97371] [11 Regression] evrp problem with gcc.target/s390/pr77822-2.c and -O3
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97371 --- Comment #3 from Aldy Hernandez --- Created attachment 49348 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49348&action=edit proposed patch untested
[Bug tree-optimization/97371] [11 Regression] evrp problem with gcc.target/s390/pr77822-2.c and -O3
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97371 Aldy Hernandez changed: What|Removed |Added Attachment #49348|0 |1 is obsolete|| --- Comment #4 from Aldy Hernandez --- Created attachment 49350 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49350&action=edit untested proposed patch
[Bug tree-optimization/97360] [11 Regression] ICE in range_on_exit
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97360 Aldy Hernandez changed: What|Removed |Added Status|NEW |WAITING --- Comment #6 from Aldy Hernandez --- It looks like the type of acc7 is __vector_quad, but the type of TYPE_{MIN,MAX}_VALUE is something entirely different: (gdb) ptg name acc7_7(D) (gdb) p name.typed.type $20 = (gdb) p debug_generic_stmt ($18.type_non_common.maxval.typed.type) uint512_t And surprisingly, these types are incompatible with each other: (gdb) p types_compatible_p ($18.type_non_common.maxval.typed.type, name.typed.type) $26 = false How can the end points of a type be (a) of a different type than the type itself (b) incompatible with the type itself. Is this a peculiarity of these quad types, or is this a target bug?
[Bug target/97312] [11 regression] aarch64/pr90838.c fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97312 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|WAITING |RESOLVED --- Comment #3 from Aldy Hernandez --- fixed in trunk
[Bug tree-optimization/97371] [11 Regression] evrp problem with gcc.target/s390/pr77822-2.c and -O3
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97371 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #6 from Aldy Hernandez --- fixed
[Bug tree-optimization/97378] [11 Regression] ICE in tree check: expected class ‘type’, have ‘exceptional’ (error_mark) in useless_type_conversion_p, at gimple-expr.c:87 since r11-3685-gfcae5121154d1c
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97378 --- Comment #2 from Aldy Hernandez --- (In reply to David Binderman from comment #1) > I have similar for the following C code: > > int a, b, c; > void d() { > e : { > long f; > long *g = &f; > if ((a != 0) - (b = 0)) > ; > else > a &= (*g %= a *= c) >= (*g || f); > goto e; > } > } > > Compiler flag -O2. For the C snippet above, we are queuing the assignment to _7 for removal: Folding statement: _7 = a.0_1 * c.3_6; EVRP:hybrid: RVRP found singleton 0 Queued stmt for removal. Folds to: 0 Yet there is still one use of _7 dangling around at the end of evrp: _17 = _7 & _29; It looks like substitute_and_fold_engine::replace_uses_in() is not propagating into the above statement because ranger can't find the range of _7 at FOR_EACH_SSA_USE_OPERAND (use, stmt, iter, SSA_OP_USE) { tree tuse = USE_FROM_PTR (use); tree val = value_of_expr (tuse, stmt); =>if (val == tuse || val == NULL_TREE) continue; (gdb) dd stmt _17 = _7 & _29; (gdb) dd tuse _7 (gdb) dd val And the reason why value_of_expr() returns NULL is because the range for _7 here is actually UNDEFINED (i.e. unreachable). It looks like we can never make it to BB 5 (where _17 = _7 & _29 lives). Because BB5 is predicated by a division by zero: : c.3_6 = c; _7 = a.0_1 * c.3_6; a = 0; _9 = (long int) _7; _10 = f_33(D) % 0; if (_10 != 0) goto ; [INV] else goto ; [INV] : ... _17 = _7 & _29; The division by zero was product of various transformations. Basically we know that a.0_1 is 0, so we _7 is 0, which means _9 is also 0, which means that final conditional can't happen: : c.3_6 = c; _7 = a.0_1 * c.3_6; a = _7; _9 = (long int) _7; _10 = f_33(D) % _9; if (_10 != 0) Andrew can take it from here, but it looks like the substitute_and_fold engine must be able to remove *ALL* references to an LHS whose definition was folded away, even if said references appear in unreachable code.
[Bug tree-optimization/97381] [11 Regression] ice error: invalid types in nop conversion
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97381 --- Comment #4 from Aldy Hernandez --- (In reply to David Binderman from comment #2) > Reduced C code is: > > int a; > void b() { > char c = 27; > for (; c <= 85; c += 1) { > a /= 148372120 * c; > if (a) > for (;;) > ; > } > } This looks similar to PR97378. There is no definition of _8 but there is still a dangling use left: c.2_6 = (unsigned char) _8;
[Bug tree-optimization/97381] [11 Regression] ice error: invalid types in nop conversion
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97381 Bug 97381 depends on bug 97378, which changed state. Bug 97378 Summary: [11 Regression] ICE in tree check: expected class ‘type’, have ‘exceptional’ (error_mark) in useless_type_conversion_p, at gimple-expr.c:87 since r11-3685-gfcae5121154d1c33 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97378 What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED
[Bug tree-optimization/97378] [11 Regression] ICE in tree check: expected class ‘type’, have ‘exceptional’ (error_mark) in useless_type_conversion_p, at gimple-expr.c:87 since r11-3685-gfcae5121154d1c
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97378 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #5 from Aldy Hernandez --- fixed
[Bug tree-optimization/97381] [11 Regression] ice error: invalid types in nop conversion
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97381 --- Comment #5 from Aldy Hernandez --- Created attachment 49354 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49354&action=edit propsed patch in testing
[Bug tree-optimization/97381] [11 Regression] ice error: invalid types in nop conversion
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97381 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #7 from Aldy Hernandez --- fixed
[Bug tree-optimization/97396] [11 Regression] ICE: Segmentation fault (in bounds_of_var_in_loop)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97396 Aldy Hernandez changed: What|Removed |Added Last reconfirmed||2020-10-13 Ever confirmed|0 |1 Assignee|unassigned at gcc dot gnu.org |aldyh at gcc dot gnu.org Status|UNCONFIRMED |NEW --- Comment #1 from Aldy Hernandez --- confirmed
[Bug tree-optimization/97396] [11 Regression] ICE: Segmentation fault (in bounds_of_var_in_loop)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97396 Aldy Hernandez changed: What|Removed |Added CC||amacleod at redhat dot com --- Comment #2 from Aldy Hernandez --- In bounds_of_var_in_loop, evolution_part_in_loop_num is returning NULL: step = evolution_part_in_loop_num (chrec, loop->num); and we ICE while trying to calculate the range for STEP. This is for: (gdb) dd stmt qx.0_3 = PHI (gdb) dd var qx.0_3 I'm not familiar with the SCEV code. It looks like NULL is a perfectly valid response from evolution_part_in_loop_num. Should we just bail if NULL? diff --git a/gcc/vr-values.c b/gcc/vr-values.c index da0b249278b..16f6c629f29 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -1827,6 +1827,8 @@ bounds_of_var_in_loop (tree *min, tree *max, range_query *query, init = initial_condition_in_loop_num (chrec, loop->num); step = evolution_part_in_loop_num (chrec, loop->num); + if (step == NULL_TREE) +return false; /* If INIT is an SSA with a singleton range, set INIT to said singleton, otherwise leave INIT alone. */
[Bug tree-optimization/97379] [11 Regression] Invalid read of size 8 at outgoing_range::calc_switch_ranges(gswitch*) (gimple-range-edge.cc:140) since r11-3685-gfcae5121154d1c33
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97379 --- Comment #2 from Aldy Hernandez --- There's a read of a freed block while accessing the default_slot in calc_switch_ranges. default_slot->intersect (def_range); It seems the default_slot got swiped from under us, and the valgrind dump indicates the free came from the get_or_insert in the same function: irange *&slot = m_edge_table->get_or_insert (e, &existed); So it looks like the get_or_insert is actually freeing the value of the previously allocated default_slot. Looking down the chain from get_or_insert, we see it calls hash_table<>::expand, which actually does a free while doing a resize of sorts: if (!m_ggc) Allocator ::data_free (oentries); else ggc_free (oentries); Not keeping a pointer to the default slot across multiple calls to get_or_insert fixes the problem, though I do see other seemingly unrelated valgrind errors: ==967361== Conditional jump or move depends on uninitialised value(s) ==967361==at 0x22BAB24: sparseset_bit_p(sparseset_def*, unsigned long) (sparseset.h:147) ==967361==by 0x22BABB7: sparseset_set_bit(sparseset_def*, unsigned long) (sparseset.h:166) ==967361==by 0x22BCCCA: register_active_defs(df_ref_d*) (fwprop.c:943) ==967361==by 0x22BCD88: update_df_init(rtx_insn*, rtx_insn*) (fwprop.c:961) ==967361==by 0x22BCFF5: try_fwprop_subst(df_ref_d*, rtx_def**, rtx_def*, rtx_insn*, bool) (fwprop.c:1028) ==967361==by 0x22BE0DE: forward_propagate_and_simplify(df_ref_d*, rtx_insn*, rtx_def*) (fwprop.c:1427) ==967361==by 0x22BE349: forward_propagate_into(df_ref_d*, bool) (fwprop.c:1490) ==967361==by 0x22BE65E: fwprop(bool) (fwprop.c:1580) ==967361==by 0x22BE6F3: (anonymous namespace)::pass_rtl_fwprop::execute(function*) (fwprop.c:1615) ==967361==by 0x11A304E: execute_one_pass(opt_pass*) (passes.c:2509) ==967361==by 0x11A3373: execute_pass_list_1(opt_pass*) (passes.c:2597) ==967361==by 0x11A33A4: execute_pass_list_1(opt_pass*) (passes.c:2598) ==967361== ==967361== Use of uninitialised value of size 8 ==967361==at 0x22BAB38: sparseset_bit_p(sparseset_def*, unsigned long) (sparseset.h:147) ==967361==by 0x22BABB7: sparseset_set_bit(sparseset_def*, unsigned long) (sparseset.h:166) ==967361==by 0x22BCCCA: register_active_defs(df_ref_d*) (fwprop.c:943) ==967361==by 0x22BCD88: update_df_init(rtx_insn*, rtx_insn*) (fwprop.c:961) ==967361==by 0x22BCFF5: try_fwprop_subst(df_ref_d*, rtx_def**, rtx_def*, rtx_insn*, bool) (fwprop.c:1028) ==967361==by 0x22BE0DE: forward_propagate_and_simplify(df_ref_d*, rtx_insn*, rtx_def*) (fwprop.c:1427) ==967361==by 0x22BE349: forward_propagate_into(df_ref_d*, bool) (fwprop.c:1490) ==967361==by 0x22BE65E: fwprop(bool) (fwprop.c:1580) ==967361==by 0x22BE6F3: (anonymous namespace)::pass_rtl_fwprop::execute(function*) (fwprop.c:1615) ==967361==by 0x11A304E: execute_one_pass(opt_pass*) (passes.c:2509) ==967361==by 0x11A3373: execute_pass_list_1(opt_pass*) (passes.c:2597) ==967361==by 0x11A33A4: execute_pass_list_1(opt_pass*) (passes.c:2598) ==967361== ==967361== Conditional jump or move depends on uninitialised value(s) ==967361==at 0x101A415: sparseset_bit_p(sparseset_def*, unsigned long) (sparseset.h:147) ==967361==by 0x101AEE9: mark_pseudo_regno_live(int) (ira-lives.c:326) ==967361==by 0x101B187: mark_pseudo_reg_live(rtx_def*, unsigned int) (ira-lives.c:410) ==967361==by 0x101B1F5: mark_ref_live(df_ref_d*) (ira-lives.c:424) ==967361==by 0x101DCB6: process_bb_node_lives(ira_loop_tree_node*) (ira-lives.c:1425) ==967361==by 0xFE97D9: ira_traverse_loop_tree(bool, ira_loop_tree_node*, void (*)(ira_loop_tree_node*), void (*)(ira_loop_tree_node*)) (ira-build.c:1801) ==967361==by 0x101E9E4: ira_create_allocno_live_ranges() (ira-lives.c:1725) ==967361==by 0xFEDC33: ira_build() (ira-build.c:3428) ==967361==by 0xFE229F: ira(_IO_FILE*) (ira.c:5359) ==967361==by 0xFE2B20: (anonymous namespace)::pass_ira::execute(function*) (ira.c:5672) ==967361==by 0x11A304E: execute_one_pass(opt_pass*) (passes.c:2509) ==967361==by 0x11A3373: execute_pass_list_1(opt_pass*) (passes.c:2597)
[Bug tree-optimization/97379] [11 Regression] Invalid read of size 8 at outgoing_range::calc_switch_ranges(gswitch*) (gimple-range-edge.cc:140) since r11-3685-gfcae5121154d1c33
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97379 --- Comment #3 from Aldy Hernandez --- Created attachment 49361 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49361&action=edit proposed patch in testing
[Bug tree-optimization/97379] [11 Regression] Invalid read of size 8 at outgoing_range::calc_switch_ranges(gswitch*) (gimple-range-edge.cc:140) since r11-3685-gfcae5121154d1c33
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97379 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #5 from Aldy Hernandez --- fixed
[Bug other/63426] [meta-bug] Issues found with -fsanitize=undefined
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63426 Bug 63426 depends on bug 97379, which changed state. Bug 97379 Summary: [11 Regression] Invalid read of size 8 at outgoing_range::calc_switch_ranges(gswitch*) (gimple-range-edge.cc:140) since r11-3685-gfcae5121154d1c33 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97379 What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED
[Bug tree-optimization/97396] [11 Regression] ICE: Segmentation fault (in bounds_of_var_in_loop)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97396 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #4 from Aldy Hernandez --- fixed
[Bug tree-optimization/96822] [11 regression] Starting with r11-2883 ICE in decompose, at wide-int.h:984
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96822 Bug 96822 depends on bug 96818, which changed state. Bug 96818 Summary: [11 Regression] ICE: in decompose, at wide-int.h:984 at -O since r11-2883 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96818 What|Removed |Added Status|WAITING |RESOLVED Resolution|--- |FIXED
[Bug tree-optimization/96818] [11 Regression] ICE: in decompose, at wide-int.h:984 at -O since r11-2883
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96818 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|WAITING |RESOLVED --- Comment #12 from Aldy Hernandez --- fixed
[Bug bootstrap/96813] [11 Regression] Broken bootstrap-lto-lean profiled bootstrap since r11-2883-gbf19cbc9cea6161f3deb63040601090828c44c53
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96813 Bug 96813 depends on bug 96818, which changed state. Bug 96818 Summary: [11 Regression] ICE: in decompose, at wide-int.h:984 at -O since r11-2883 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96818 What|Removed |Added Status|WAITING |RESOLVED Resolution|--- |FIXED
[Bug tree-optimization/97467] [11 Regression] ICE in verify_range, at value-range.cc:369 (-Os and above) since r11-3685-gfcae5121154d1c33
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97467 --- Comment #2 from Aldy Hernandez --- Ranger can figure out that the RHS operand of a shift is a zero and feeds it to operator_lshift::op1_range, which then uses it to create a swapped [1,0] range. Testing the following patch: diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 0efa00186e8..30d2a4d3987 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -1579,6 +1579,11 @@ operator_lshift::op1_range (irange &r, wide_int shift = wi::to_wide (shift_amount); if (wi::lt_p (shift, 0, SIGNED)) return false; + if (shift == 0) + { + r = lhs; + return true; + } // Work completely in unsigned mode to start. tree utype = type;
[Bug tree-optimization/97467] [11 Regression] ICE in verify_range, at value-range.cc:369 (-Os and above) since r11-3685-gfcae5121154d1c33
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97467 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #4 from Aldy Hernandez --- Fixed.
[Bug tree-optimization/97488] [11 Regression] ICE: Segmentation fault (in wi::set_bit_large)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97488 Aldy Hernandez changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2020-10-19 Ever confirmed|0 |1 --- Comment #1 from Aldy Hernandez --- Confirmed. The shift amount in operator_lshift::op1_range is > than the precision of the type so the low_bits wrap around. Testing the following: diff --git a/gcc/range-op.cc b/gcc/range-op.cc index 30d2a4d3987..13a0ee37feb 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -1608,8 +1608,10 @@ operator_lshift::op1_range (irange &r, // This would be [0x42, 0xFC] aka [0110, 1100]. // Ideally we do this for each subrange, but just lump them all for now. - unsigned low_bits = TYPE_PRECISION (utype) - - TREE_INT_CST_LOW (shift_amount); + unsigned saturated_shift_amount = TREE_INT_CST_LOW (shift_amount); + if (saturated_shift_amount > TYPE_PRECISION (utype)) + saturated_shift_amount = TYPE_PRECISION (utype); + unsigned low_bits = TYPE_PRECISION (utype) - saturated_shift_amount; wide_int up_mask = wi::mask (low_bits, true, TYPE_PRECISION (utype)); wide_int new_ub = wi::bit_or (up_mask, r.upper_bound ()); wide_int new_lb = wi::set_bit (r.lower_bound (), low_bits);
[Bug tree-optimization/97488] [11 Regression] ICE: Segmentation fault (in wi::set_bit_large)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97488 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #3 from Aldy Hernandez --- fixed
[Bug tree-optimization/97501] [11 Regression] ICE in verify_range, at value-range.cc:369, -O2 on dead overflowing nested loops since r11-3685-gfcae5121154d1c33
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97501 Aldy Hernandez changed: What|Removed |Added Status|UNCONFIRMED |NEW Ever confirmed|0 |1 --- Comment #2 from Aldy Hernandez --- bounds_of_var_in_loop is returning an overflowed int, which is causing us to create a range for which we can't compare the bounds causing an ICE in verify_range. Overflowed bounds cause compare_values() to return -2, which we don't handle in verify_range. We don't represent overflowed ranges in irange, so this patch just saturates any overflowed end-points to MIN or MAX. Testing the following patch: gcc/ChangeLog: PR 97501/tree-optimization * gimple-range.cc (gimple_ranger::range_of_ssa_name_with_loop_info): Saturate overflows returned from SCEV. gcc/testsuite/ChangeLog: * gcc.dg/pr97501.c: New test. diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index 999d631c5ee..6ce9e52c691 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -1140,9 +1140,9 @@ gimple_ranger::range_of_ssa_name_with_loop_info (irange &r, tree name, // ?? We could do better here. Since MIN/MAX can only be an // SSA, SSA +- INTEGER_CST, or INTEGER_CST, we could easily call // the ranger and solve anything not an integer. - if (TREE_CODE (min) != INTEGER_CST) + if (TREE_CODE (min) != INTEGER_CST || TREE_OVERFLOW (min)) min = vrp_val_min (type); - if (TREE_CODE (max) != INTEGER_CST) + if (TREE_CODE (max) != INTEGER_CST || TREE_OVERFLOW (max)) max = vrp_val_max (type); r.set (min, max); } diff --git a/gcc/testsuite/gcc.dg/pr97501.c b/gcc/testsuite/gcc.dg/pr97501.c new file mode 100644 index 000..aedac83962d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr97501.c @@ -0,0 +1,14 @@ +// { dg-do compile } +// { dg-options "-O2" } + +static int c = 0; + +int main() { + int b = 0; + if (c) { + for (;; b--) +do + b++; +while (b); + } +}
[Bug tree-optimization/97501] [11 Regression] ICE in verify_range, at value-range.cc:369, -O2 on dead overflowing nested loops since r11-3685-gfcae5121154d1c33
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97501 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #4 from Aldy Hernandez --- fixed
[Bug tree-optimization/97505] [11 Regression] ICE in extract_range_basic, at vr-values.c:1439 since r11-4130-g16e4f1ad44e3c00b8b73c9e4ade3d236ea7044a8
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97505 --- Comment #1 from Aldy Hernandez --- We are calculating ranges for the following: (gdb) dd stmt _18 = .UBSAN_CHECK_SUB (_58, _57); which gets turned into a MINUS_EXPR. Then we call extract_range_from_binary_expr on the MINUS_EXPR: /* Pretend the arithmetics is wrapping. If there is any overflow, we'll complain, but will actually do wrapping operation. */ flag_wrapv = 1; extract_range_from_binary_expr (vr, subcode, type, gimple_call_arg (stmt, 0), gimple_call_arg (stmt, 1)); flag_wrapv = saved_flag_wrapv; In extract_range_from_binary_expr, we calculate the range for _58 and _57 respectively as: (gdb) dd vr0 integer(kind=8) [-INF, _57 - 1] (gdb) dd vr1 integer(kind=8) [_58 + 1, +INF] Which extract_range_from_binary_expr can then use to reduce the MINUS_EXPR to ~[0,0]: /* If we didn't derive a range for MINUS_EXPR, and op1's range is ~[op0,op0] or vice-versa, then we can derive a non-null range. This happens often for pointer subtraction. */ if (vr->varying_p () && (code == MINUS_EXPR || code == POINTER_DIFF_EXPR) && TREE_CODE (op0) == SSA_NAME && ((vr0.kind () == VR_ANTI_RANGE && vr0.min () == op1 && vr0.min () == vr0.max ()) || (vr1.kind () == VR_ANTI_RANGE && vr1.min () == op0 && vr1.min () == vr1.max ( { vr->set_nonzero (expr_type); vr->equiv_clear (); } The ranger version is not handling these symbolics.
[Bug tree-optimization/97505] [11 Regression] ICE in extract_range_basic, at vr-values.c:1439 since r11-4130-g16e4f1ad44e3c00b8b73c9e4ade3d236ea7044a8
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97505 --- Comment #2 from Aldy Hernandez --- Created attachment 49411 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49411&action=edit proposed patch We should disable the assert while this PR is fixed, so it doesn't hold anyone else up. Patch needs a testcase.
[Bug tree-optimization/97505] [11 Regression] ICE in extract_range_basic, at vr-values.c:1439 since r11-4130-g16e4f1ad44e3c00b8b73c9e4ade3d236ea7044a8
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97505 --- Comment #4 from Aldy Hernandez --- Looking at vr_values::extract_range_builtin(), I see that every single place where we use ask for a range, we bail on non-integers (symbolics, etc). That is, with the exception of the UBSAN builtins. The UBSAN builtins degrade into PLUS/MINUS/MULT and call extract_range_from_binary_expr, which as I've shown, can special case some symbolics which the ranger doesn't currently handle. Since this is a UBSAN issue, we could still go with the original plan of removing the duplicity in ranger vs vr-values, but we'd still have to leave in the UBSAN builtin handling, perhaps as vr_values::extract_ubsan_builtin(). This isn't ideal, as we'd like to remove all the common code, but I'd be willing to put up with UBSAN duplication for the time being. A possible solution for this PR would be to disable the assert on the UBSAN builtins: diff --git a/gcc/vr-values.c b/gcc/vr-values.c index 67c88006f13..3021f619319 100644 --- a/gcc/vr-values.c +++ b/gcc/vr-values.c @@ -1432,14 +1432,17 @@ vr_values::extract_range_basic (value_range_equiv *vr, gimple *stmt) if (is_gimple_call (stmt) && extract_range_builtin (vr, stmt)) { + combined_fn cfn = gimple_call_combined_fn (stmt); + if (cfn == CFN_UBSAN_CHECK_ADD + || cfn == CFN_UBSAN_CHECK_SUB + || cfn == CFN_UBSAN_CHECK_MUL) + return; + value_range_equiv tmp; And then, as a follow-up, remove all the builtin code from extract_range_builtin, with the exception of the UBSAN stuff (renaming it to extract_ubsan_builtin). Now... the question is, whether this is worth it, since the plan for next stage1 is to overhaul evrp and vrp, causing vr_values and friends to be entirely removed. If we leave the duplicate code in, we'll have to remember to update the vr_values and ranger versions of this code in sync for the next year. I'm guessing this code doesn't change much?? If we do decide to remove it starting with the proposed patch above, we'd have to do more extensive testing to make sure shit doesn't break. Perhaps testing on {-m32,-m64,-fsanitize=signed-integer-overflow} on x86, ppc64, and possibly other slowpokes such as aarch64. I'm torn. It may be a lot of testing and possible breakage in return for removing 90% of code that will hopefully be entirely removed during the next cycle. Thoughts?
[Bug tree-optimization/97538] [11 Regression] ICE in during GIMPLE pass: wrestrict since r11-4135-ge864d395b4e862ce
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97538 --- Comment #3 from Aldy Hernandez --- Created attachment 49434 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=49434&action=edit proposed patch in testing Ranger was returning undefined, which caused get_size_range() to use an uninitialized wide_int. I am testing the attached patch. These bug reports have been incredibly useful. Thanks for reporting them.
[Bug tree-optimization/97538] [11 Regression] ICE in during GIMPLE pass: wrestrict since r11-4135-ge864d395b4e862ce
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97538 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #5 from Aldy Hernandez --- fixed
[Bug tree-optimization/97560] [11 Regression] ICE: tree check: expected tree that contains 'decl common' structure, have 'component_ref' in tree_could_trap_p, at tree-eh.c:2708 since r11-3685
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97560 --- Comment #2 from Aldy Hernandez --- $ ./cc1plus a.c -O2 -fno-tree-forwprop -fnon-call-exc eptions -quiet $ Is this still an issue? I can't reproduce on trunk, and I see the PR was reported against a snapshot from 18-oct. A lot has changed in trunk in a week.
[Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97555 Aldy Hernandez changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |aldyh at gcc dot gnu.org --- Comment #3 from Aldy Hernandez --- Mine. Thanks for the analysis.
[Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97555 --- Comment #4 from Aldy Hernandez --- The problem here is we're trying to add 1 to a -1 in a signed 1-bit field. Signed 1-bits are annoying because you can't really add or subtract one, because the one is unrepresentable. For invert() we have a special subtract_one() function that handles 1-bit signed fields. We need a corresponding add_one() here. The untested patch below should do it. diff --git a/gcc/range-op.cc b/gcc/range-op.cc index ee62f103598..74ab2e57fde 100644 --- a/gcc/range-op.cc +++ b/gcc/range-op.cc @@ -3680,15 +3680,28 @@ range_tests () // Test 1-bit signed integer union. // [-1,-1] U [0,0] = VARYING. tree one_bit_type = build_nonstandard_integer_type (1, 0); + tree one_bit_min = vrp_val_min (one_bit_type); + tree one_bit_max = vrp_val_max (one_bit_type); { -tree one_bit_min = vrp_val_min (one_bit_type); -tree one_bit_max = vrp_val_max (one_bit_type); int_range<2> min (one_bit_min, one_bit_min); int_range<2> max (one_bit_max, one_bit_max); max.union_ (min); ASSERT_TRUE (max.varying_p ()); } + // Test inversion of 1-bit signed integers. + { +int_range<2> min (one_bit_min, one_bit_min); +int_range<2> max (one_bit_max, one_bit_max); +int_range<2> t; +t = min; +t.invert (); +ASSERT_TRUE (t == max); +t = max; +t.invert (); +ASSERT_TRUE (t == min); + } + // Test that NOT(255) is [0..254] in 8-bit land. int_range<1> not_255 (UCHAR (255), UCHAR (255), VR_ANTI_RANGE); ASSERT_TRUE (not_255 == int_range<1> (UCHAR (0), UCHAR (254))); diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 7847104050c..f45a342605a 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -1772,18 +1772,29 @@ irange::irange_intersect (const irange &r) verify_range (); } +// Signed 1-bits are strange. You can't subtract 1, because you can't +// represent the number 1. This works around that for the invert routine. + static wide_int inline subtract_one (const wide_int &x, tree type, wi::overflow_type &overflow) { - // A signed 1-bit bit-field, has a range of [-1,0] so subtracting +1 - // overflows, since +1 is unrepresentable. This is why we have an - // addition of -1 here. if (TYPE_SIGN (type) == SIGNED) -return wi::add (x, -1 , SIGNED, &overflow); +return wi::add (x, -1, SIGNED, &overflow); else return wi::sub (x, 1, UNSIGNED, &overflow); } +// The analogous function for adding 1. + +static wide_int inline +add_one (const wide_int &x, tree type, wi::overflow_type &overflow) +{ + if (TYPE_SIGN (type) == SIGNED) +return wi::sub (x, -1, SIGNED, &overflow); + else +return wi::add (x, 1, TYPE_SIGN (type), &overflow); +} + /* Return the inverse of a range. */ void @@ -1881,7 +1892,7 @@ irange::invert () // set the overflow bit. if (type_max != wi::to_wide (orig_range.m_base[i])) { - tmp = wi::add (wi::to_wide (orig_range.m_base[i]), 1, sign, &ovf); + tmp = add_one (wi::to_wide (orig_range.m_base[i]), ttype, ovf); m_base[nitems++] = wide_int_to_tree (ttype, tmp); m_base[nitems++] = wide_int_to_tree (ttype, type_max); if (ovf)
[Bug tree-optimization/97555] [11 Regression] wrong code at -Os and above on x86_64-pc-linux-gnu since r11-3685
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97555 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #6 from Aldy Hernandez --- fixed
[Bug tree-optimization/97560] [11 Regression] ICE: tree check: expected tree that contains 'decl common' structure, have 'component_ref' in tree_could_trap_p, at tree-eh.c:2708 since r11-3685
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97560 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #4 from Aldy Hernandez --- fixed in trunk
[Bug tree-optimization/97609] [11 Regression] ICE: tree check: expected tree that contains 'decl common' structure, have 'component_ref' in tree_could_trap_p, at tree-eh.c:2708
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97609 Aldy Hernandez changed: What|Removed |Added Ever confirmed|0 |1 Status|UNCONFIRMED |NEW Last reconfirmed||2020-10-28 CC||amacleod at redhat dot com --- Comment #1 from Aldy Hernandez --- confirmed
[Bug tree-optimization/97609] [11 Regression] ICE: tree check: expected tree that contains 'decl common' structure, have 'component_ref' in tree_could_trap_p, at tree-eh.c:2708
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97609 --- Comment #2 from Aldy Hernandez --- tl;dr: substitute_and_fold_engine::replace_uses_in() creates invalid gimple, so when its loop goes on to request a range (value_of_expr), the ranger may see invalid IL and die an ungraceful death. The long story: We are calling substitute_and_fold_engine::replace_uses_in() on the following statement: : SR.2_9 = &__to_destroy._M_head; SR.1_10 = SR.2_9; __pos$_M_node_6 = SR.1_10; _11 = __pos$_M_node_6; _11->_M_next = __keep_12(D); <-- HERE HERE For _11, the call to value_of_expr() in replace_uses_in() returns: &__to_destroy._M_head; which is propagated with propagate_value() and creates invalid gimple in the process: __to_destroy._M_head._M_next = __keep_12(D); The next time in the loop in replace_uses_in, we ask for value_of_expr(__keep_12(D)), which dies deep in the call chain, because the IL borked.
[Bug tree-optimization/97609] [11 Regression] ICE: tree check: expected tree that contains 'decl common' structure, have 'component_ref' in tree_could_trap_p, at tree-eh.c:2708
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97609 --- Comment #3 from Aldy Hernandez --- And the reason this was working before is two-fold. First, value_of_expr() in legacy evrp won't look at broken gimple, so the request for __keep_12(D) in the following statement actually succeeds: __to_destroy._M_head._M_next = __keep_12(D); Well... returns NULL. Second, after replace_uses_in() succeeds, the gimple folder fixes the crappy IL by transforming: __to_destroy._M_head._M_next = __keep_12(D); into: MEM[(struct _Fwd_list_node_base *)&__to_destroy]._M_next = __keep_12(D); So basically this worked before because even though substitute_and_fold_engine::replace_uses_in() created invalid gimple, it depended on the gimple folder to clean-up the nonsense after the fact. How stupid is that? :)
[Bug tree-optimization/97505] [11 Regression] ICE in extract_range_basic, at vr-values.c:1439 since r11-4130-g16e4f1ad44e3c00b8b73c9e4ade3d236ea7044a8
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97505 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #6 from Aldy Hernandez --- fixed
[Bug tree-optimization/97721] [11 Regression] ICE in verify_range, at value-range.cc:361
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97721 Aldy Hernandez changed: What|Removed |Added CC||rguenth at gcc dot gnu.org --- Comment #2 from Aldy Hernandez --- The ranger is analyzing a statement with an integer overflow, and creating a non-legacy range that is invalid: (gdb) p debug(stmt) if (_1 != -1(OVF)) (gdb) p debug(op2_range) int [-1(OVF), -1(OVF)] (gdb) p op2_range.legacy_mode_p() $8 = false Legacy ranges allow TREE_OVERFLOW to creep in, as the verifier allows symbolics and other end points that are not comparable at compile time (cmp == -2 below): case VR_ANTI_RANGE: case VR_RANGE: { gcc_assert (m_num_ranges == 1); int cmp = compare_values (tree_lower_bound (0), tree_upper_bound (0)); gcc_assert (cmp == 0 || cmp == -1 || cmp == -2); return; } However, we're a bit more strict in irange. We don't allow un-comparable endpoints and TREE_OVERFLOW integers are such. I'm not sure where to fix this. Is the original statement valid gimple? Richard has mentioned that any time there's a TREE_OVERFLOW in the IL, it's a sign of a bug. If the IL is wrong, we should tackle the source problem. If the IL is ocrrect, then perhaps we could drop OVF at range creation.
[Bug tree-optimization/97721] [11 Regression] ICE in verify_range, at value-range.cc:361
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97721 --- Comment #6 from Aldy Hernandez --- (In reply to Richard Biener from comment #5) > (In reply to Aldy Hernandez from comment #2) > Yes, the IL is "correct", just inefficent and possibly confusing to passes. > > The OVF flag on INTEGER_CST have _no_ semantic meaning in the IL so making > them "invalid" in ranger doesn't make sense. The ranger treating them invalid was a precaution since the conversion to trees brought the use of compare_values_warnv(), which claims overflowed values cannot be compared. But if in fact they can be compared, then perhaps compare_values_warnv is wrong in claiming the opposite: /* We cannot say anything more for non-constants. */ if (!cst1 || !cst2) return -2; if (!POINTER_TYPE_P (TREE_TYPE (val1))) { /* We cannot compare overflowed values. */ if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2)) return -2; What do you think? It would seem to me that removing this restriction would work, especially since tree_int_cst_compare, which this function uses, just degrades to wide ints, which don't care about TREE_OVERFLOW. [untested] diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index e00c034fee3..8702ad1ae8d 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -609,10 +609,6 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p) if (!POINTER_TYPE_P (TREE_TYPE (val1))) { - /* We cannot compare overflowed values. */ - if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2)) - return -2; - if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST) return tree_int_cst_compare (val1, val2); @@ -635,13 +631,7 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p) else { if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST) - { - /* We cannot compare overflowed values. */ - if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2)) - return -2; - - return tree_int_cst_compare (val1, val2); - } + return tree_int_cst_compare (val1, val2); /* First see if VAL1 and VAL2 are not the same. */ if (operand_equal_p (val1, val2, 0))
[Bug tree-optimization/97721] [11 Regression] ICE in verify_range, at value-range.cc:361
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97721 --- Comment #8 from Aldy Hernandez --- (In reply to Jakub Jelinek from comment #7) > But TREE_OVERFLOW is meaningful during evaluation, e.g. inside of VRP or > when folding some expression. It just doesn't belong into the GIMPLE IL. > So I'd say it would be better for ranger when it sees TREE_OVERFLOW constant > somewhere in the IL not to set the range to that constant, but to > drop_tree_overflow of it. That's certainly the easiest path for us. We could drop_overflow in get_tree_range while creating said ranges, and then no other changes to the ranger are needed. However, I wonder if compare_values_warnv is being unnecessarily restrictive. For example, here, we bail on overflow, even though tree_int_cst_compare, through its use of wi::cmps, is perfectly capable of comparing these integers: if (!POINTER_TYPE_P (TREE_TYPE (val1))) { /* We cannot compare overflowed values. */ if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2)) return -2; if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST) return tree_int_cst_compare (val1, val2); as well as here: if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST) { /* We cannot compare overflowed values. */ if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2)) return -2; return tree_int_cst_compare (val1, val2); }
[Bug tree-optimization/97721] [11 Regression] ICE in verify_range, at value-range.cc:361
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97721 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #12 from Aldy Hernandez --- fixed
[Bug tree-optimization/97767] [11 Regression] ICE in extract_range_basic, at vr-values.c:1445 since r11-4532-g054d7b9f6f6816a8
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97767 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #3 from Aldy Hernandez --- fixed
[Bug tree-optimization/97315] [11 Regression] ICE in choose_value, at gimple-ssa-evrp.c:282 since r11-3690-gebc77ce3a4c70730b4e38d68f88693eadbdc8712
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97315 --- Comment #2 from Aldy Hernandez --- evrp and ranger disagree on the singleton range for _3 in the following stmt: : if (_3 != 1) (gdb) ptg evrp_ret 0 (gdb) ptg ranger_ret 1 Which is interesting because BB5 is actually unreachable: add_type_duplicate () { struct tree_node * D.2384; struct tree_node * add_type_duplicate_type.2_1; short unsigned int _2; int _3; tree_code_class _4; : add_type_duplicate_type.2_1 = add_type_duplicate_type; _2 = add_type_duplicate_type.2_1->base.code; _3 = (int) _2; _4 = tree_code_type[_3]; if (_4 != 0) goto ; [INV] else goto ; [INV] : if (_2 == 0) goto ; [INV] else goto ; [INV] : if (0 != 0) goto ; [66.00%] else goto ; [34.00%] : goto ; [100.00%] : if (_3 != 1) goto ; [0.04%] else goto ; [99.96%] : goto ; [100.00%] : tree_check_failed (); : : : if (0 != 0) goto ; [66.00%] else goto ; [34.00%] : if (1 != 0) goto ; [0.04%] else goto ; [99.96%] : tree_check_failed (); : if (1 != 0) goto ; [INV] else goto ; [INV] : return; } I'm guessing evrp
[Bug tree-optimization/97315] [11 Regression] ICE in choose_value, at gimple-ssa-evrp.c:282 since r11-3690-gebc77ce3a4c70730b4e38d68f88693eadbdc8712
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97315 --- Comment #3 from Aldy Hernandez --- (In reply to Alex Coplan from comment #1) > Seeing a similar ICE with the following simple C testcase: > > int a; > int b(signed char c, int d) { return c < 0 ? 0 : c >> d; } > void e(void) > { > for (int i = 0; i <= 0; i++) > while (a) > b(-(i != 1), i); > } > > $ aarch64-elf-gcc -O2 test.c evrp and ranger disagree on the singleton for i_6. (gdb) ptg ranger_val 1 (gdb) ptg evrp_val 0 (gdb) ptgs stmt iftmp.0_13 = _12 >> i_6; This is the same issue. stmt is in BB4, which is unreachable.
[Bug tree-optimization/97317] [11 Regression] ICE in verify_range, at value-range.cc:369
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97317 --- Comment #2 from Aldy Hernandez --- operator_cast::op1_range() is creating a range with swapped operands here: // And union this with the entire outer types negative range. int_range_max neg (type, wi::min_value (TYPE_PRECISION (type), SIGNED), lim - 1); (gdb) ptg type (gdb) dd wmin [0x], precision = 17 (gdb) dd wmax [0x], precision = 17 This is an unsigned bit field, which I can never get right. Andrew, should we be creating a min in SIGNED precision here?
[Bug target/97312] [11 regression] aarch64/pr90838.c fails
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97312 Aldy Hernandez changed: What|Removed |Added Last reconfirmed||2020-10-07 Ever confirmed|0 |1 Status|UNCONFIRMED |WAITING --- Comment #1 from Aldy Hernandez --- Confirmed. This test is checking the final assembly for a specific sequence. I don't speak aarch64 assembly, but the IL is different coming out of evrp. The first culprit is this difference in the mergephi1 dump: _9 = .CTZ (x_6(D)); - _10 = _9 & 31; + _10 = _9; These are unsigned ints, so assuming they are 32 bits on aarch64, __builtin_ctz is always less than 32. This is because a CTZ of 0 is undefined according to the GCC manual: Built-in Function: int __builtin_ctz (unsigned int x) Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined. So a bitwise AND of anything less than 32 with 0x1f (31) is a no-op. Are aarch64 int's 32-bits? Here are the full IL differences: --- legacy-evrp/pr90838.c.038t.mergephi12020-10-07 08:44:12.152358885 -0400 +++ ranger/pr90838.c.038t.mergephi1 2020-10-07 08:39:12.339296502 -0400 @@ -1,41 +1,41 @@ ;; Function ctz1 (ctz1, funcdef_no=0, decl_uid=3587, cgraph_uid=1, symbol_order=0) ctz1 (unsigned int x) { static const char table[32] = "\x00\x01\x1c\x02\x1d\x0e\x18\x03\x1e\x16\x14\x0f\x19\x11\x04\b\x1f\x1b\r\x17\x15\x13\x10\x07\x1a\f\x12\x06\v\x05\n\t"; unsigned int _1; unsigned int _2; unsigned int _3; unsigned int _4; char _5; int _9; int _10; : _1 = -x_6(D); _2 = _1 & x_6(D); _3 = _2 * 125613361; _4 = _3 >> 27; _9 = .CTZ (x_6(D)); - _10 = _9 & 31; + _10 = _9; _5 = (char) _10; return _10; } ;; Function ctz2 (ctz2, funcdef_no=1, decl_uid=3591, cgraph_uid=2, symbol_order=1) ctz2 (unsigned int x) { static short int table[64] = {32, 0, 1, 12, 2, 6, 0, 13, 3, 0, 7, 0, 0, 0, 0, 14, 10, 4, 0, 0, 8, 0, 0, 25, 0, 0, 0, 0, 0, 21, 27, 15, 31, 11, 5, 0, 0, 0, 0, 0, 9, 0, 0, 24, 0, 0, 20, 26, 30, 0, 0, 0, 0, 23, 0, 19, 29, 0, 22, 18, 28, 17, 16, 0}; unsigned int _1; unsigned int _2; unsigned int _3; short int _4; int _8; : _1 = -x_5(D); @@ -87,27 +87,27 @@ ;; Function ctz4 (ctz4, funcdef_no=3, decl_uid=3601, cgraph_uid=4, symbol_order=5) ctz4 (long unsigned int x) { long unsigned int lsb; long unsigned int _1; long long unsigned int _2; long long unsigned int _3; char _4; int _9; int _10; : _1 = -x_5(D); lsb_6 = _1 & x_5(D); _2 = lsb_6 * 283881067100198605; _3 = _2 >> 58; _9 = .CTZ (x_5(D)); - _10 = _9 & 63; + _10 = _9; _4 = (char) _10; return _10; } The difference in assembly matches. We have 2 less AND's in the final output: $ diff -u legacy.s ranger.s --- legacy.s2020-10-07 09:06:13.420446783 -0400 +++ ranger.s2020-10-07 09:06:42.646646949 -0400 @@ -8,7 +8,6 @@ ctz1: rbitw0, w0 clz w0, w0 - and w0, w0, 31 ret .size ctz1, .-ctz1 .align 2 @@ -36,7 +35,6 @@ ctz4: rbitx0, x0 clz x0, x0 - and w0, w0, 63 ret .size ctz4, .-ctz4 If my analysis is correct, someone aarch64 savvy should adjust this: /* { dg-final { scan-assembler-times "and\t" 2 } } */
[Bug tree-optimization/97315] [11 Regression] ICE in choose_value, at gimple-ssa-evrp.c:282 since r11-3690-gebc77ce3a4c70730b4e38d68f88693eadbdc8712
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97315 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #13 from Aldy Hernandez --- Fixed.
[Bug tree-optimization/97325] [11 Regression] wrong code with __builtin_ffs() at -O2
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97325 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #6 from Aldy Hernandez --- Fixed.
[Bug testsuite/97337] new test case gcc.dg/pr97315-1.c fails with excess errors
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97337 Aldy Hernandez changed: What|Removed |Added Assignee|unassigned at gcc dot gnu.org |aldyh at gcc dot gnu.org Status|UNCONFIRMED |NEW Last reconfirmed||2020-10-09 Ever confirmed|0 |1 --- Comment #1 from Aldy Hernandez --- Confirmed. Test should've gone in g++.dg/ not gcc.dg/.
[Bug testsuite/97337] new test case gcc.dg/pr97315-1.c fails with excess errors
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97337 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #4 from Aldy Hernandez --- fixed in trunk
[Bug tree-optimization/97317] [11 Regression] ICE in verify_range, at value-range.cc:369
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=97317 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #8 from Aldy Hernandez --- fixed
[Bug tree-optimization/100349] [11/12 Regression] ICE Segmentation fault during GIMPLE pass: evrp (under -O2 to -Os)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100349 --- Comment #2 from Aldy Hernandez --- evolution_part_in_loop_num() is returning NULL when evrp asks about the PHI result here: (gdb) p debug(stmt) c.1_4 = PHI Is this expected? If it is, we could easily return false if step is null and everything should just work.
[Bug tree-optimization/100512] [12 Regression] ICE during GIMPLE pass: cddce in mark_operand_necessary, at tree-ssa-dce.c:173 (under -O2 to -Os) since r12-623-g1416a1434c43de0b
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100512 --- Comment #4 from Aldy Hernandez --- After the mentioned commit, e_27(D) is considered undefined, and since _3 is [0,0], e_26 folds to [0,0] and the PHI is marked for removal: # e_26 = PHI However, when propagating to the uses of e_26 (replace_uses_in) here: if (e_26 != 0) ...value_of_expr() returns NULL, because get_non_stale_global_range() considers the value of e_26 stale: if (m_globals.get_global_range (r, name)) { if (m_temporal->current_p (name)) return true; } The dependencies for e_26 are e_27 and _3, per the PHI, but _3 has a later time stamp. The full IL follows. Notice the interdependence between e_26 and _3. void b () { int16_t i; uint64_t * f; uint64_t e; uint16_t d; int16_t * c; long unsigned int _3; long int d.3_5; short int _7; int a.5_8; int iftmp.4_11; : d = 2; // predicted unlikely by goto predictor. goto ; [INV] : # e_25 = PHI _3 = e_25 + 1; if (_3 != 0) goto ; [INV] else goto ; [INV] : goto ; [INV] : d.3_5 = (long int) &d; i_19 = (int16_t) d.3_5; if (i_19 != 0) goto ; [INV] else goto ; [INV] : if (e_26 != 0) goto ; [INV] else goto ; [INV] : : # iftmp.4_11 = PHI <1(6), 0(7)> _7 = (short int) iftmp.4_11; *c_22(D) = _7; goto ; [INV] : # e_26 = PHI g: : a.5_8 = a; if (a.5_8 != 0) goto ; [INV] else goto ; [INV] }
[Bug c/100521] [12 Regression] ICE at -O2 and above: in verify_range, at value-range.cc:384 since r12-127-g694c956b6b877e48
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100521 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #3 from Aldy Hernandez --- Fixed in trunk.
[Bug tree-optimization/100578] [12 Regression] ICE Segmentation fault during GIMPLE pass: fre (under -g -O2/O3/Os)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100578 Aldy Hernandez changed: What|Removed |Added Resolution|--- |DUPLICATE Status|NEW |RESOLVED --- Comment #2 from Aldy Hernandez --- The definition for_4 has been removed by the time we examine this: b_9 = _3 | _4; *** This bug has been marked as a duplicate of bug 100512 ***
[Bug tree-optimization/100512] [12 Regression] ICE during GIMPLE pass: cddce in mark_operand_necessary, at tree-ssa-dce.c:173 (under -O2 to -Os) since r12-623-g1416a1434c43de0b
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100512 --- Comment #5 from Aldy Hernandez --- *** Bug 100578 has been marked as a duplicate of this bug. ***
[Bug tree-optimization/100349] [11/12 Regression] ICE Segmentation fault during GIMPLE pass: evrp (under -O2 to -Os)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100349 --- Comment #4 from Aldy Hernandez --- Yes, it's a duplicate. There's a patch awaiting review here: https://gcc.gnu.org/pipermail/gcc-patches/2021-May/570301.html
[Bug tree-optimization/100494] [11/12 Regression] Unterminated recursion in gimple-range.cc (x86_64-w64-mingw32)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100494 --- Comment #2 from Aldy Hernandez --- I cannot reproduce on a cross configured with: ~/src/gcc/configure --target=x86_64-w64-mingw32 --enable-languages=c --disable-bootstrap I tried: ./cc1 sha1.i -quiet -mtune=generic -march=x86-64 -g -O2 -Wextra -Wall -Wwrite-strings -Wc++-compat -Wstrict-prototypes -Wshadow=local -Wpedantic -w It works in both the GCC 11 branch and trunk.
[Bug tree-optimization/100636] ICE at -Os and above: tree check: expected class ‘type’, have ‘exceptional’ (error_mark) in useless_type_conversion_p, at gimple-expr.c:88
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100636 Aldy Hernandez changed: What|Removed |Added Resolution|--- |DUPLICATE Status|UNCONFIRMED |RESOLVED --- Comment #1 from Aldy Hernandez --- Duplicate. The variable c is undefined and is an input to a PHI. *** This bug has been marked as a duplicate of bug 100512 ***
[Bug tree-optimization/100512] [12 Regression] ICE during GIMPLE pass: cddce in mark_operand_necessary, at tree-ssa-dce.c:173 (under -O2 to -Os) since r12-623-g1416a1434c43de0b
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100512 Aldy Hernandez changed: What|Removed |Added CC||zhendong.su at inf dot ethz.ch --- Comment #6 from Aldy Hernandez --- *** Bug 100636 has been marked as a duplicate of this bug. ***
[Bug tree-optimization/100499] Different results with -fpeel-loops -ftree-loop-vectorize options
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100499 --- Comment #23 from Aldy Hernandez --- I have an upcoming patchset that implements a range evaluator for tree expressions (similar to determine_value_range), as well as a gimple_ranger that evaluates expressions in a higher precision. This combination looks like it could provide a way for determining overflow: // Return TRUE if evaluating EXPR in its type can produce an overflow. // Overflow is determined by calculating the possible range for EXPR // in its natural type and in a wider type. If the results differ, // evaluating EXPR may have overflowed. bool may_overflow_p (const_tree expr) { gimple_ranger ranger; gimple_ranger_wider wranger (TREE_TYPE (expr)); int_range_max r, w; if (!ranger.range_of_expr (r, const_cast (expr)) || !wranger.range_of_expr (w, const_cast (expr))) return true; return r != w; } Of course, we'd need to adapt the above to re-use any active ranger instead of instantiating a new one every time. The above yields overflow for the 16-bit expression in question: (gdb) p debug(top) g_2823_lsm.5_6 * 7854 + 57682 (gdb) p may_overflow_p (top) $6 = true This is because the range of the above expression in unsigned 16-bit yields VARYING (R), whereas in 32-bit unsigned yields [57682, 514769572] (W). Plugging in the above into multiple_of_p: diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 4a4358362e1..ea8ec3bbeec 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -13987,6 +13987,9 @@ multiple_of_p (tree type, const_tree top, const_tree bottom) if (TREE_CODE (type) != INTEGER_TYPE) return 0; + if (may_overflow_p (top)) +return false; + switch (TREE_CODE (top)) { case BIT_AND_EXPR: ...yields what I think is the correct result: (base) abulafia:~/bld/t/gcc$ ./xgcc -B./ a.c -O1 -w (base) abulafia:~/bld/t/gcc$ ./a.out start g_2823 = 60533 end g_2823 = 32768 (base) abulafia:~/bld/t/gcc$ ./xgcc -B./ a.c -O1 -fpeel-loops -ftree-loop-vectorize -w (base) abulafia:~/bld/t/gcc$ ./a.out start g_2823 = 60533 end g_2823 = 32768 Does this seem right?
[Bug tree-optimization/100499] Different results with -fpeel-loops -ftree-loop-vectorize options
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100499 --- Comment #24 from Aldy Hernandez --- (In reply to Aldy Hernandez from comment #23) > The above yields overflow for the 16-bit expression in question: > > (gdb) p debug(top) > g_2823_lsm.5_6 * 7854 + 57682 > > (gdb) p may_overflow_p (top) > $6 = true > > This is because the range of the above expression in unsigned 16-bit yields > VARYING (R), whereas in 32-bit unsigned yields [57682, 514769572] (W). Which, I will note, matches Andrew's hand calculation of: >so the original expression is in 16 bit math, and if it was evaluated as > [0, 65535] * [7854, 7854] + [57682, 57682] > in 32 bit precision, it would come back with the answer [57682, 514769572].
[Bug tree-optimization/100781] [12 Regression] Emitted binary code changes when -g is enabled at -O2
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100781 Aldy Hernandez changed: What|Removed |Added CC||aldyh at gcc dot gnu.org, ||amacleod at redhat dot com --- Comment #5 from Aldy Hernandez --- Started with: c21644704160710a17d1ea6c1cd212e079cd5e36 commit c21644704160710a17d1ea6c1cd212e079cd5e36 (HEAD) Author: Andrew MacLeod Date: Tue May 25 14:15:50 2021 -0400 Add imports and strengthen the export definition in range_def and gori_map. All add up to 2 direct dependencies for each ssa-name. Add gori import/export iterators.
[Bug tree-optimization/100787] [12 Regression] Bootstrap failure caused by r12-1077
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100787 Aldy Hernandez changed: What|Removed |Added CC||aldyh at gcc dot gnu.org --- Comment #2 from Aldy Hernandez --- I'm doing the following on an x86-64 Linux box, as I don't have access to an i686 system: ~/src/clean/configure --enable-clocale=gnu --with-system-zlib --with-demangler-in-ld --with-fpmath=sse --enable-languages=c,c++ --enable-cet i686-linux --enable-bootstrap --with-fpmath=sse --disable-libcc1 --disable-libcilkrts --disable-libsanitizer make -jN /usr/bin/ld: /home/aldyh/bld/t/./gcc/liblto_plugin.so: error loading plugin: /home/aldyh/bld/t/./gcc/liblto_plugin.so: wrong ELF class: ELFCLASS32 collect2: error: ld returned 1 exit status make[3]: *** [Makefile:995: libgcc_s.so] Error 1 make[3]: Leaving directory '/opt/notnfs/aldyh/bld/t/i686-linux/libgcc' make[2]: *** [Makefile:19008: all-stage2-target-libgcc] Error 2 make[2]: Leaving directory '/opt/notnfs/aldyh/bld/t' make[1]: *** [Makefile:23280: stage2-bubble] Error 2 Is there a way to reproduce this on an x86-64 system?
[Bug tree-optimization/100787] [12 Regression] Bootstrap failure caused by r12-1077
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100787 Aldy Hernandez changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2021-05-27 Ever confirmed|0 |1 --- Comment #4 from Aldy Hernandez --- (In reply to Jakub Jelinek from comment #3) > I'm using > mkdir ~/hbin > cat > ~/hbin/as <<\END > #!/bin/sh > exec /usr/bin/as --32 "$@" > END > cat > ~/hbin/g++ <<\END > #!/bin/sh > exec /usr/bin/g++ -m32 "$@" > END > cat > ~/hbin/gcc <<\END > #!/bin/sh > exec /usr/bin/gcc -m32 "$@" > END > cat > ~/hbin/ld <<\END > #!/bin/sh > case "$*" in > --version) cat <<\EOF > GNU ld version 2.20.52.0.1-10.fc17 20100131 > Copyright 2012 Free Software Foundation, Inc. > This program is free software; you may redistribute it under the terms of > the GNU General Public License version 3 or (at your option) a later version. > This program has absolutely no warranty. > EOF > exit 0;; > esac > exec /usr/bin/ld -m elf_i386 -L /usr/lib/ "$@" > END > chmod 755 ~/hbin/{as,g++,gcc,ld} > > and then use > PATH=~/hbin:$PATH i386 .../configure ... > PATH=~/hbin:$PATH i386 make ... > etc. That is DIS-GUST-ING! ...and also works, thanks :). Confirmed.
[Bug c/100790] ICE with -O2: in verify_range, at value-range.cc:385
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100790 --- Comment #2 from Aldy Hernandez --- There's a patch pending review that fixes this: https://gcc.gnu.org/pipermail/gcc-patches/2021-May/570289.html
[Bug tree-optimization/100787] [12 Regression] Bootstrap failure caused by r12-1077
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100787 --- Comment #9 from Aldy Hernandez --- This temporary fix resolves the bootstrap comparison on i686. Does it also fix it on sparc-32? diff --git a/gcc/gimple-ssa-evrp.c b/gcc/gimple-ssa-evrp.c index 118d10365a0..b40649b6a10 100644 --- a/gcc/gimple-ssa-evrp.c +++ b/gcc/gimple-ssa-evrp.c @@ -127,7 +127,7 @@ public: if (dump_file && (dump_flags & TDF_DETAILS)) m_ranger->dump (dump_file); -m_ranger->export_global_ranges (); +//m_ranger->export_global_ranges (); disable_ranger (cfun); } @@ -193,7 +193,7 @@ public: if (dump_file && (dump_flags & TDF_DETAILS)) m_ranger->dump (dump_file); -m_ranger->export_global_ranges (); +//m_ranger->export_global_ranges (); disable_ranger (cfun); }
[Bug tree-optimization/100787] [12 Regression] Bootstrap failure caused by r12-1077
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100787 --- Comment #11 from Aldy Hernandez --- Note, this is still broken so I am leaving the PR open. I will address this next week.
[Bug tree-optimization/100787] [12 Regression] Bootstrap failure caused by r12-1077
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100787 Aldy Hernandez changed: What|Removed |Added Status|NEW |RESOLVED Resolution|--- |FIXED --- Comment #13 from Aldy Hernandez --- Fixed in trunk by: https://gcc.gnu.org/pipermail/gcc-patches/2021-June/571597.html
[Bug tree-optimization/100984] gimple-ssa-evrp.c: mismatched new and delete
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100984 Aldy Hernandez changed: What|Removed |Added Status|UNCONFIRMED |NEW Ever confirmed|0 |1 Last reconfirmed||2021-06-10 Component|c |tree-optimization
[Bug tree-optimization/100790] ICE with -O2: in verify_range, at value-range.cc:385
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100790 --- Comment #4 from Aldy Hernandez --- fixed in trunk.
[Bug tree-optimization/100790] ICE with -O2: in verify_range, at value-range.cc:385
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100790 Aldy Hernandez changed: What|Removed |Added Resolution|--- |FIXED Status|NEW |RESOLVED --- Comment #5 from Aldy Hernandez --- ...and closed.
[Bug tree-optimization/101014] [12 Regression] Big compile time hog with -O3 since r12-1268-g9858cd1a6827ee7a
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101014 --- Comment #12 from Aldy Hernandez --- (In reply to Hongtao.liu from comment #11) > I'm not sure if it's related but compilation of 527.cam4_r still hangs with > > gcc version 12.0.0 20210621 (experimental) (GCC) Can you verify after which patch upstream it started hanging? It may or may not be related to this bug. Or perhaps, can you check where it hangs? Is it hanging in the ranger code or elsewhere? Thanks.
[Bug tree-optimization/101186] predictable comparison of integer variables not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101186 Aldy Hernandez changed: What|Removed |Added CC||aldyh at gcc dot gnu.org, ||jeffreyalaw at gmail dot com --- Comment #4 from Aldy Hernandez --- To give a little more context, the IL at thread1 looks like this: [local count: 59055800]: goto ; [100.00%] [local count: 955630225]: if (a_5(D) != 0) goto ; [67.00%] else goto ; [33.00%] [local count: 640272253]: if (x_8(D) < c_12) goto ; [33.00%] else goto ; [67.00%] [local count: 211289842]: unreachable (); goto ; [100.00%] [local count: 315357972]: blah (); [local count: 955630227]: b_11 = b_1 + 1; goto ; [100.00%] [local count: 118111600]: # c_12 = PHI [local count: 1073741824]: # b_1 = PHI if (b_1 <= 999) goto ; [89.00%] else goto ; [11.00%] The path from 3->9->10->4->5 could *theoretically* resolve the conditional in BB5. If this were a permissible jump threading path, the threader would replace the conditional in BB5 into a jump to BB8, thus eliding the unreachable. However, BB9->BB10 would cross loop boundaries which is not permitted in the backwards threader. Specifically, the threading candidate conditional is BB5, which is in a loop: ;; Loop 1 ;; header 10, latch 8 ;; depth 1, outer 0 ;; nodes: 10 8 6 7 5 4 (<-- note BB5 & BB10 in here) And BB9 is outside said loop. See path_crosses_loops in tree-ssa-threadbackward.c as well as handle_phi() where we specifically skip PHI edges pointing outside the current loop. Note that even though my upcoming rewrite of the backward threader does not use the relational oracle, Andrew says it would be trivial to do so. In which case, we *could* resolve the above path, but would still fail to thread it because it crosses a loop boundary. Perhaps Jeff can opine on whether the path duplicator in the threader back-end, could be taught to thread through loops.
[Bug tree-optimization/101186] predictable comparison of integer variables not folded
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101186 --- Comment #5 from Aldy Hernandez --- Sorry for the slightly different IL. I had altered g() to avoid depending on stdio.h: void g (int a, int b, int x, int y) { int c = y; if (a != 0) c = x; while (b < 1000) // without this loop, jump thread & VRP can remove dead code { if (a != 0) { if (c > x) unreachable(); } else blah(); b++; } }
[Bug tree-optimization/101223] [11/12 Regression] evrp produces wrong code since r11-3685-gfcae5121154d1c33
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101223 --- Comment #4 from Aldy Hernandez --- d is used before being defined. Isn't this entire test bogus?
[Bug tree-optimization/101223] [11/12 Regression] evrp produces wrong code since r11-3685-gfcae5121154d1c33
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=101223 --- Comment #6 from Aldy Hernandez --- (In reply to Jakub Jelinek from comment #5) > d is not an automatic variable, so is zero initialized. Whoops. Sorry for the noise.
[Bug tree-optimization/107608] [13 Regression] Failure on fold-overflow-1.c and pr95115.c
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107608 --- Comment #12 from Aldy Hernandez --- (In reply to Richard Biener from comment #6) > (In reply to Jakub Jelinek from comment #0) > > ... but then > > comes dom2 and happily replaces > > _1 = 3.4028234663852885981170418348451692544e+38 * 2.0e+0; > > return _1; > > with > > _1 = 3.4028234663852885981170418348451692544e+38 * 2.0e+0; > > return Inf; > > (I think this is still correct) > > Note this is also a pessimization code-generation wise since if we > preserve the multiplication the result is readily available in a > register but as optimized we have another constant pool entry and load. > > So we might want to consider not propagating constants generated by > operations > we cannot eliminate. If the only consumer is a compare-and-branch we > can of course still end up with a seemingly dead stmt, so this would be only > for the missed optimization. [Sorry for the delayed response. I've been on PTO.] For the original testcase, the propagation happens in DOM: [local count: 1073741824]: _1 = 3.4028234663852885981170418348451692544e+38 * 2.0e+0; return _1; range_of_expr gets called on the return's _1 and correctly returns Inf, which allows cprop_operand to do the replacement. If I understand correctly you're suggesting not propagating constants that were generated by an operation we can't eliminate. In this case, it'd be easy to chase the DEF back to the offending _1 definition (from cprop_operand and every other places where we do propagations based on range_of_expr's result), but ranger doesn't keep track of how it got to an answer, so we'd have to chase all operands used to generate _1?? That'd get hairy pretty fast, unless I'm misunderstanding something. It really looks like the problem here is DCE (and the gimplifier as you point out in comment #2), which is removing a needed statement. Can't this be fixed there?
[Bug tree-optimization/108341] argument to `__builtin_ctz` should be assumed non-zero
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108341 --- Comment #2 from Aldy Hernandez --- (In reply to Martin Liška from comment #1) > May be an opportunity for Ranger? Hmmm... I don't think so: : value.0_1 = (unsigned int) value_4(D); _2 = __builtin_ctz (value.0_1); r = _2; _3 = value_4(D) != 0; _7 = (int) _3; return _7; We could add an op1_range operator to class cfn_clz to return nonzero for op1, but that would only work if we knew _2 to be anything...and have no info on _2.
[Bug tree-optimization/108281] float value range estimation missing (vs. integer)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108281 --- Comment #3 from Aldy Hernandez --- (In reply to Richard Biener from comment #2) > GCC 13 got float range tracking but the description isn't clear as what > transform you are looking after? It seems you are looking for ranges > of standard math functions - I think those are not yet implemented? Correct. We don't track libm functions.
[Bug tree-optimization/108281] float value range estimation missing (vs. integer)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108281 --- Comment #5 from Aldy Hernandez --- (In reply to Jakub Jelinek from comment #4) > (In reply to Aldy Hernandez from comment #3) > > (In reply to Richard Biener from comment #2) > > > GCC 13 got float range tracking but the description isn't clear as what > > > transform you are looking after? It seems you are looking for ranges > > > of standard math functions - I think those are not yet implemented? > > > > Correct. We don't track libm functions. > > Yet. I hope we do that for GCC 14. Yeah. That'd be very nice. It's on our radar for the next releaseat least provide any missing framework and provide a few sample ones.
[Bug tree-optimization/108341] argument to `__builtin_ctz` should be assumed non-zero when CTZ_DEFINED_VALUE_AT_ZERO says it is undefined
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108341 Aldy Hernandez changed: What|Removed |Added Severity|normal |enhancement --- Comment #6 from Aldy Hernandez --- Huh. Didn't know you could do that. Thanks. FWIW, the function is actually: gimple_infer_range::gimple_infer_range (gimple *s)
[Bug tree-optimization/107608] [13 Regression] Failure on fold-overflow-1.c and pr95115.c
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107608 --- Comment #15 from Aldy Hernandez --- (In reply to Richard Biener from comment #13) > Note that the constant folding routines generally refrain from folding > when that loses exceptions, it's just ranger when producing singleton > ranges and propagating from them that doesn't adhere to that implicit rule. We already have similar restrictions to avoid folding relational operators when NANs are present. I suppose we could add the same restriction to the generic frange folder (range_operator_float::fold_range) as the const_binop snippet you quoted down-thread. Thanks for the explanation and the const_binop example. This makes it much clearer.
[Bug tree-optimization/107608] [13 Regression] Failure on fold-overflow-1.c and pr95115.c
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107608 --- Comment #16 from Aldy Hernandez --- Created attachment 54224 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54224&action=edit untested patch Perhaps this would work. It solves the testcase, though I think we should probably audit the operators that don't use the generic range_operator_float::fold_range to make sure they're not doing anything silly. Note that we could add similar code whenever we drop to a NAN like const_binop does: /* Don't constant fold this floating point operation if both operands are not NaN but the result is NaN, and flag_trapping_math. Such operations should raise an invalid operation exception. */ if (flag_trapping_math && MODE_HAS_NANS (mode) && REAL_VALUE_ISNAN (result) && !REAL_VALUE_ISNAN (d1) && !REAL_VALUE_ISNAN (d2)) return NULL_TREE; I avoided doing so because an frange of NAN does not count as a singleton so it should never be propagated. If this is a problem, I could add a similar tweak. What do y'all think?
[Bug tree-optimization/107608] [13 Regression] Failure on fold-overflow-1.c and pr95115.c
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107608 --- Comment #22 from Aldy Hernandez --- (In reply to Jakub Jelinek from comment #20) > (In reply to Aldy Hernandez from comment #16) > > Created attachment 54224 [details] > > untested patch > > > > Perhaps this would work. It solves the testcase, though I think we should > > probably audit the operators that don't use the generic > > range_operator_float::fold_range to make sure they're not doing anything > > silly. > > Even as a workaround this seems to be quite a big hammer. > If we want to preserve overflow traps, all we need to arrange is that if > non-inf operands result in singleton inf we don't treat that result as > singleton. > Now, what result one gets in different rounding modes depends on the > rounding mode, > in round to nearest it should be +-inf, in round to zero +-max, in round to > +inf +inf or -max and in round to -inf -inf or +max. But right now GCC > doesn't handle the separate rounding modes, it just differentiates between > -fno-rounding-math where we assume round to nearest and -frounding-math > where we should consider any rounding mode. Note that we currently can't represent +-inf or +-max, as we only have two endpoints. So that would just be represented as VARYING. > I think for -frounding-math we already don't treat such results as > singletons, as we > end up with ranges like [+max, +inf] or [-inf, -max]. > So, one possible way for -fno-rounding-math -ftrapping-math could be instead > of making > the result VARYING just extend the range by one ulp towards 0, i.e. instead > of singleton > [+inf, +inf] use [+max, +inf] etc. This seems reasonable. So instead of set_varying(), we could do [+max, +inf], etc. > Another would be to add some bool flag to frange which would say this is > never a singleton and just take that flag into account, though perhaps it is > too risky right now. That seems easy to get wrong, especially this late in the cycle. > > As for invalid exceptions, that implies result maybe or known NAN, but we > don't treat > maybe or known NAN as singletons, do we? After all, there isn't just a > single NAN and we don't know which one the result is. That doesn't mean we > handle all cases right, say > if a result of something is only used in __builtin_isnan or similar, we can > still happily optimized it away. NANs are never singletons, and maybe_nans either. See frange::singleton_p: if (m_kind == VR_RANGE && real_identical (&m_min, &m_max)) { // Return false for any singleton that may be a NAN. if (HONOR_NANS (m_type) && maybe_isnan ()) return false; ... } Also, all the conditional operators in frange fail to fold if maybe_isnan. The only things we fold for sure are: a) One operand is a known NAN. b) None of the operands can ever be a NAN *and* we know the answer to the conditional. For example, foperator_gt::fold_range: ... ... if (op1.known_isnan () || op2.known_isnan ()) r = range_false (type); else if (!maybe_isnan (op1, op2)) { if (real_compare (LE_EXPR, &op1.upper_bound (), &op2.lower_bound ())) r = range_true (type); else if (!real_compare (LE_EXPR, &op1.lower_bound (), &op2.upper_bound ())) r = range_false (type); else r = range_true_and_false (type); } so... we're pretty careful about NOT folding relationals that have the possibility of a NAN, and a singleton is only for a known range without a NAN.
[Bug tree-optimization/107608] [13 Regression] Failure on fold-overflow-1.c and pr95115.c
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107608 --- Comment #24 from Aldy Hernandez --- (In reply to Andrew Macleod from comment #21) > (In reply to Richard Biener from comment #13) > > > Yes, the fact that ranger doesn't operate as a usual propagator with a > > lattice > > makes things very difficult here. Note that my comment referred to code > > optimality, not correctness. > > > > > It really looks like the problem here is DCE (and the gimplifier as you > > > point out in comment #2), which is removing a needed statement. Can't > > > this > > > be fixed there? > > > > Sure it can, but the expense is that we'd do constant folding all the way > > down and not remove dead code which will result in _tons_ of unnecessary > > constant pool entries and loads. > > > > I think I'm missing something, or not understanding what you are saying. > > Why is the propagation or lack of lattice a problem? Its DCE that is > removing that potentially trapping stmt because its no longer used in the > IL? THe change would be to not kill off dead statements that may trap? I > guess this may leave a bunch of feeding statements that are not dead.. but I > fail to see how thats different than not propagating and then not being able > to delete those stmts either? > > > > The issue is also that -ftrapping-math is default on so we'd have to > > do this by default. Ugh. > > > > Note that the constant folding routines generally refrain from folding > > when that loses exceptions, it's just ranger when producing singleton > > ranges and propagating from them that doesn't adhere to that implicit rule. > > I'm also not sure what this means. I don't think ranger itself propagates > singleton constants.. VRP is still using the substitute_and_fold engine, so > any folding/propagation is still going through the same mechanisms we always > did when a singleton result is produced. We just produce more of them now, > especially with floats. I don't think ranger is doing anything different > than VRP ever did regarding propagation. Its possible GCCs infrastructure > for dealing with float propagation isn't mature enough perhaps? Right, ranger isn't propagating anything. It's the substitute_and_fold engine, as it always has, but only if value_of_expr() is non-NULL. Currently this function will only return non-NULL for singletons: tree range_query::value_of_expr (tree expr, gimple *stmt) { tree t; if (!Value_Range::supports_type_p (TREE_TYPE (expr))) return NULL_TREE; Value_Range r (TREE_TYPE (expr)); if (range_of_expr (r, expr, stmt)) { // A constant used in an unreachable block oftens returns as UNDEFINED. // If the result is undefined, check the global value for a constant. if (r.undefined_p ()) range_of_expr (r, expr); if (r.singleton_p (&t)) return t; } return NULL_TREE; }
[Bug tree-optimization/107608] [13 Regression] Failure on fold-overflow-1.c and pr95115.c
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107608 Aldy Hernandez changed: What|Removed |Added Attachment #54224|0 |1 is obsolete|| --- Comment #26 from Aldy Hernandez --- Created attachment 54253 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54253&action=edit proposed patch So where are we on this? Do we want to do something like this for this release, or something else entirely? This is a variation of the previous patch that instead of setting varying, avoids the singleton by returning: [INF, INF] => [+MAX, +INF] [-INF, -INF] => [-INF, -MIN]
[Bug tree-optimization/107608] [13 Regression] Failure on fold-overflow-1.c and pr95115.c
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107608 --- Comment #29 from Aldy Hernandez --- (In reply to Jakub Jelinek from comment #27) > "elide an overflow" should be probably "elide an overflow or division by > zero" I think, > because finite / 0.0 returns infinity and raises FE_DIVBYZERO rather than > FE_OVERFLOW, > even when it returns infinity from finite operands. > Seems for infinity / 0.0 no exception is raised, so the finite operands > infinite result condition seems to be sufficient. Fixed. > > For GCC 13, I think it is important that we e.g. don't miscompile glibc > libm, so > the libm testsuite should be clean. PR107967 fixed some of the failures, > and some were claimed to be dups of this PR. So, would be nice to test GCC > with your patch on glibc + libm testsuite. > Just > CC=/path/to/patched-gcc-trunk/gcc CXX=/path/to/patched-gcc-trunk/g++ > ../configure --prefix=/usr > CC=/path/to/patched-gcc-trunk/gcc CXX=/path/to/patched-gcc-trunk/g++ make -jN > CC=/path/to/patched-gcc-trunk/gcc CXX=/path/to/patched-gcc-trunk/g++ make > -jN check > should be enough in latest glibc (and perhaps compare that to GCC 12). I ran tests on glibc from git sources and compared the tests.sum files left behind from a "make check -k -jN". There don't seem to be any regressions. For that matter, it looks like a handful of tests get fixed by the proposed patch: -FAIL: math/test-double-lgamma -FAIL: math/test-double-log1p -FAIL: math/test-float-lgamma -FAIL: math/test-float-log1p -FAIL: math/test-float128-catan -FAIL: math/test-float128-catanh -FAIL: math/test-float128-lgamma -FAIL: math/test-float128-log -FAIL: math/test-float128-log1p -FAIL: math/test-float128-y0 -FAIL: math/test-float128-y1 -FAIL: math/test-float32-lgamma -FAIL: math/test-float32-log1p -FAIL: math/test-float32x-lgamma -FAIL: math/test-float32x-log1p -FAIL: math/test-float64-lgamma -FAIL: math/test-float64-log1p -FAIL: math/test-float64x-lgamma -FAIL: math/test-ldouble-lgamma