[Bug tree-optimization/91355] [8/9/10 Regression] optimized code does not call destructor while unwinding after exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91355 Jakub Jelinek changed: What|Removed |Added Target Milestone|8.4 |8.5 --- Comment #11 from Jakub Jelinek --- GCC 8.4.0 has been released, adjusting target milestone.
[Bug tree-optimization/91355] [8/9/10 Regression] optimized code does not call destructor while unwinding after exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91355 --- Comment #10 from Jakub Jelinek --- With the above changes, the bug is now latent.
[Bug tree-optimization/91355] [8/9/10 Regression] optimized code does not call destructor while unwinding after exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91355 --- Comment #9 from Jakub Jelinek --- Author: jakub Date: Thu Nov 21 17:21:46 2019 New Revision: 278587 URL: https://gcc.gnu.org/viewcvs?rev=278587&root=gcc&view=rev Log: PR tree-optimization/91355 * tree-ssa-sink.c (select_best_block): Use >= rather than > for early_bb scaled count with best_bb count comparison. * g++.dg/torture/pr91355.C: New test. Added: branches/gcc-8-branch/gcc/testsuite/g++.dg/torture/pr91355.C Modified: branches/gcc-8-branch/gcc/ChangeLog branches/gcc-8-branch/gcc/testsuite/ChangeLog branches/gcc-8-branch/gcc/tree-ssa-sink.c
[Bug tree-optimization/91355] [8/9/10 Regression] optimized code does not call destructor while unwinding after exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91355 --- Comment #8 from Jakub Jelinek --- Author: jakub Date: Thu Nov 21 13:53:57 2019 New Revision: 278551 URL: https://gcc.gnu.org/viewcvs?rev=278551&root=gcc&view=rev Log: PR tree-optimization/91355 * tree-ssa-sink.c (select_best_block): Use >= rather than > for early_bb scaled count with best_bb count comparison. * g++.dg/torture/pr91355.C: New test. Added: branches/gcc-9-branch/gcc/testsuite/g++.dg/torture/pr91355.C Modified: branches/gcc-9-branch/gcc/ChangeLog branches/gcc-9-branch/gcc/testsuite/ChangeLog branches/gcc-9-branch/gcc/tree-ssa-sink.c
[Bug tree-optimization/91355] [8/9/10 Regression] optimized code does not call destructor while unwinding after exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91355 --- Comment #7 from Jakub Jelinek --- Author: jakub Date: Thu Nov 21 10:59:27 2019 New Revision: 278548 URL: https://gcc.gnu.org/viewcvs?rev=278548&root=gcc&view=rev Log: PR tree-optimization/91355 * tree-ssa-sink.c (select_best_block): Use >= rather than > for early_bb scaled count with best_bb count comparison. * g++.dg/torture/pr91355.C: New test. Added: trunk/gcc/testsuite/g++.dg/torture/pr91355.C Modified: trunk/gcc/ChangeLog trunk/gcc/testsuite/ChangeLog trunk/gcc/tree-ssa-sink.c
[Bug tree-optimization/91355] [8/9/10 Regression] optimized code does not call destructor while unwinding after exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91355 --- Comment #6 from Jakub Jelinek --- I think we have two issues. One is that if we sink something on the edge between resx and corresponding landing pad, ehcleanup2 is upset, and the other one is that it is really not beneficial to sink the stmts there. If we fix the latter, we'd just have a latent bug though. In the testcase, both best_bb (the bb from splitting the EH edge) as well as early_bb have count of 0, because this is all EH stuff and happens only if the code throws (which is always, but we handle EH as something very rare). r254698 changed best_bb->count.to_frequency < early_bb->count.to_frequency * 82% to !(best_bb->count.apply_scale(100,1) > early_bb->count.apply_scale(82,1)) and so with zero counts the condition was false, but now it is true. Though, the comment talks about !(... >= ...) rather than !(... > ...). Honza, shouldn't that be !(... >= ...) as the comment says? At least for the case of zero counts, if early_bb has the same count as best_bb, it isn't profitable to sink it, it should be profitable only if it has 82% smaller count (or smaller). Changing the > into >= makes the wrong-code go away, though as I said, we have a latent issue and from what I understood, PRE might be inserting on such edges too, otherwise we wouldn't split it.
[Bug tree-optimization/91355] [8/9/10 Regression] optimized code does not call destructor while unwinding after exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91355 Jakub Jelinek changed: What|Removed |Added CC||ebotcazou at gcc dot gnu.org, ||rth at gcc dot gnu.org --- Comment #5 from Jakub Jelinek --- I'm afraid I don't know enough of the EH rules on what's wrong, so will just try to describe what happens: ;; basic block 3, loop depth 0 ;;pred: 2 _10 = __cxa_allocate_exception (4); MEM[(int *)_10] = 3; __cxa_throw (_10, &_ZTIi, 0B); ;;succ: 6 ;; basic block 4, loop depth 0 ;;pred: 2 d.0_14 = d; _15 = d.0_14 + 1; d = _15; _6 = __cxa_allocate_exception (4); MEM[(int *)_6] = 3; __cxa_throw (_6, &_ZTIi, 0B); ;;succ: 5 ;; basic block 5, loop depth 0 ;;pred: 4 : d.1_16 = d; _17 = d.1_16 + 4294967295; d = _17; resx 4 ;;succ: 6 ;; basic block 6, loop depth 0 ;;pred: 3 ;;5 : _20 = __builtin_eh_filter (1); if (_20 == -1) goto ; [0.00%] else goto ; [0.00%] ;;succ: 8 ;;7 Now, if not -fno-tree-sink or Honza's change is in, sink changes that to: ;; basic block 5, loop depth 0, count 0 (precise), probably never executed ;;prev block 4, next block 10, flags: (NEW, REACHABLE, VISITED) ;;pred: 4 [never] count:0 (precise) (EH,EXECUTABLE) : resx 4 ;;succ: 10 [never] count:0 (precise) (EH,EXECUTABLE) ;; basic block 10, loop depth 0, count 0 (precise), probably never executed ;;prev block 5, next block 9, flags: (NEW) ;;pred: 5 [never] count:0 (precise) (EH,EXECUTABLE) : d.1_16 = d; _17 = d.1_16 + 4294967295; d = _17; goto ; [100.00%] ;;succ: 6 [always] count:0 (precise) (FALLTHRU) ;; basic block 9, loop depth 0, count 0 (precise), probably never executed ;;prev block 10, next block 6, flags: (NEW) ;;pred: 3 [never] count:0 (precise) (EH,EXECUTABLE) : ;;succ: 6 [always] count:0 (precise) (FALLTHRU) ;; basic block 6, loop depth 0, count 0 (precise), probably never executed ;;prev block 9, next block 7, flags: (NEW, REACHABLE, VISITED) ;;pred: 9 [always] count:0 (precise) (FALLTHRU) ;;10 [always] count:0 (precise) (FALLTHRU) : _20 = __builtin_eh_filter (1); if (_20 == -1) goto ; [0.00%] else goto ; [0.00%] ;;succ: 8 [never] count:0 (precise) (TRUE_VALUE,EXECUTABLE) ;;7 [never] count:0 (precise) (FALSE_VALUE,EXECUTABLE) Before ehcleanup2 the difference is then (-fno-tree-sink -O1 vs. -ftree-sink -O1): ;; basic block 5, loop depth 0 ;;pred: 4 : - d.1_16 = d; - _17 = d.1_16 + 4294967295; - d = _17; resx 4 ;;succ: 6 ;; basic block 6, loop depth 0 +;;pred: 5 +: + d.1_16 = d; + _17 = d.1_16 + 4294967295; + d = _17; + goto ; [100.00%] +;;succ: 8 + +;; basic block 7, loop depth 0 ;;pred: 3 -;;5 +: +;;succ: 8 + +;; basic block 8, loop depth 0 +;;pred: 7 +;;6 : _20 = __builtin_eh_filter (1); Now, ehcleanup2 removes resx 4; for some reason: Before removal of unreachable regions: Eh tree: - 1 allowed_exceptions land:{1,},{3,} filter :-1 types:int + 1 allowed_exceptions land:{4,},{1,},{3,} filter :-1 types:int 4 cleanup land:{2,} Reachable regions: n_bits = 8, set = {1 4 } -Reachable landing pads: n_bits = 4, set = {1 2 } +Reachable landing pads: n_bits = 5, set = {1 2 4 } Removing unreachable landing pad 3 After removal of unreachable regions: Eh tree: - 1 allowed_exceptions land:{1,} filter :-1 types:int + 1 allowed_exceptions land:{4,},{1,} filter :-1 types:int 4 cleanup land:{2,} +Removing basic block 7 +Removing basic block 5 +Removing unreachable region 4 ... ;; basic block 5, loop depth 0 ;;pred: 4 -: +: d.1_16 = d; _17 = d.1_16 + 4294967295; d = _17; - resx 4 ;;succ: 6 and in *.optimized dump that means: ;; basic block 5, loop depth 0 ;;pred: 4 -: +: d.1_16 = d; _17 = d.1_16 + 4294967295; d = _17; - __builtin_eh_copy_values (1, 4); ;;succ: 6 change and abort.
[Bug tree-optimization/91355] [8/9/10 Regression] optimized code does not call destructor while unwinding after exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91355 --- Comment #4 from Jakub Jelinek --- bb 10 into which it is sunk has been created by split_critical_edges, although the edge from the resx 4; bb to the landing pad is not critical, there is: /* PRE inserts statements to edges and expects that since split_critical_edges was done beforehand, committing edge insertions will not split more edges. In addition to critical edges we must split edges that have multiple successors and end by control flow statements, such as RESX. Go ahead and split them too. This matches the logic in gimple_find_edge_insert_loc. */
[Bug tree-optimization/91355] [8/9/10 Regression] optimized code does not call destructor while unwinding after exception
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91355 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org Component|c++ |tree-optimization --- Comment #3 from Jakub Jelinek --- Slightly cleaned up testcase for g++.dg/torture/ // PR tree-optimization/91355 // { dg-do run { target c++14_down } } unsigned int d = 0; struct S { S () { d++; } S (const S &) { d++; } ~S () { d--; } }; void foo (int i) throw (int) // { dg-warning "dynamic exception specifications are deprecated" "" { target c++11 } } { if (i == 0) throw 3; S d; throw 3; } int main () { try { foo (1); } catch (...) {} if (d) __builtin_abort (); } The sink pass first sinks d = d - 1; statements across resx 4; into a new basic block which is made new successor of the bb containing resx 4;, so: : d.1_16 = d; _17 = d.1_16 + 4294967295; d = _17; resx 4 becomes: : resx 4 [count: 0]: : d.1_16 = d; _17 = d.1_16 + 4294967295; d = _17; goto ; [100.00%] sink_code_in_bb has: /* We can't move things across abnormal edges, so don't try. */ FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_ABNORMAL) goto earlyout; Shouldn't that be & (EDGE_ABNORMAL | EDGE_EH) ? Or are there any cases where we actually want to sink something across EH edge? Even if yes, we shouldn't put anything before landing pads IMHO.