[Bug fortran/68649] [6/7 Regression] note: code may be misoptimized unless -fno-strict-aliasing is used
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68649 --- Comment #18 from Joost VandeVondele --- since this PR, and the related PR77278 can presumably only be fixed by changing libgfortran abi (at least if I understand Richard's suggestion for fixing this). The announced major version bump of libgfortran (https://gcc.gnu.org/ml/gcc-patches/2016-10/msg01376.html) could be a good opportunity for this change. It is the major thing holding back the use of LTO with Fortran projects, I think.
[PATCH] Fix BB_VISITED clearing in IRA, remove substitue-and-fold dce flag
This fixes the BB_VISITED bug in IRA I ran into earlier this year, removing the superfluous clearing in VRP and the SSA propagator as well as removing the now always true do_dce flag from substitute-and-fold. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2016-10-18 Richard Biener* tree-ssa-propagate.h (substitute_and_fold): Adjust prototype. * tree-ssa-propagate.c (ssa_prop_fini): Remove final BB_VISITED clearing. (substitute_and_fold_dom_walker): Adjust constructor. (substitute_and_fold_dom_walker::before_dom_children): Remove do_dce flag and handling (always true). (substitute_and_fold): Likewise. * tree-vrp.c (vrp_finalize): Adjust. (execute_early_vrp): Remove final BB_VISITED clearing. * tree-ssa-ccp.c (ccp_finalize): Adjust. * tree-ssa-copy.c (fini_copy_prop): Likewise. * ira.c (ira): Call clear_bb_flags. Index: gcc/tree-vrp.c === --- gcc/tree-vrp.c (revision 241294) +++ gcc/tree-vrp.c (working copy) @@ -10622,8 +10622,7 @@ vrp_finalize (bool warn_array_bounds_p) vr_value[i]->max); } - substitute_and_fold (op_with_constant_singleton_value_range, - vrp_fold_stmt, true); + substitute_and_fold (op_with_constant_singleton_value_range, vrp_fold_stmt); if (warn_array_bounds && warn_array_bounds_p) check_all_array_refs (); @@ -10954,8 +10953,6 @@ execute_early_vrp () vrp_free_lattice (); scev_finalize (); loop_optimizer_finalize (); - FOR_EACH_BB_FN (bb, cfun) -bb->flags &= ~BB_VISITED; return 0; } Index: gcc/tree-ssa-ccp.c === --- gcc/tree-ssa-ccp.c (revision 241294) +++ gcc/tree-ssa-ccp.c (working copy) @@ -953,8 +953,7 @@ ccp_finalize (bool nonzero_p) } /* Perform substitutions based on the known constant values. */ - something_changed = substitute_and_fold (get_constant_value, - ccp_fold_stmt, true); + something_changed = substitute_and_fold (get_constant_value, ccp_fold_stmt); free (const_val); const_val = NULL; Index: gcc/tree-ssa-propagate.c === --- gcc/tree-ssa-propagate.c(revision 241294) +++ gcc/tree-ssa-propagate.c(working copy) @@ -479,9 +479,6 @@ ssa_prop_fini (void) free (cfg_order_to_bb); BITMAP_FREE (ssa_edge_worklist); uid_to_stmt.release (); - basic_block bb; - FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, next_bb) -bb->flags &= ~BB_VISITED; } @@ -972,10 +969,9 @@ class substitute_and_fold_dom_walker : p public: substitute_and_fold_dom_walker (cdi_direction direction, ssa_prop_get_value_fn get_value_fn_, - ssa_prop_fold_stmt_fn fold_fn_, - bool do_dce_) + ssa_prop_fold_stmt_fn fold_fn_) : dom_walker (direction), get_value_fn (get_value_fn_), - fold_fn (fold_fn_), do_dce (do_dce_), something_changed (false) + fold_fn (fold_fn_), something_changed (false) { stmts_to_remove.create (0); stmts_to_fixup.create (0); @@ -993,7 +989,6 @@ public: ssa_prop_get_value_fn get_value_fn; ssa_prop_fold_stmt_fn fold_fn; -bool do_dce; bool something_changed; vec stmts_to_remove; vec stmts_to_fixup; @@ -1012,8 +1007,7 @@ substitute_and_fold_dom_walker::before_d tree res = gimple_phi_result (phi); if (virtual_operand_p (res)) continue; - if (do_dce - && res && TREE_CODE (res) == SSA_NAME) + if (res && TREE_CODE (res) == SSA_NAME) { tree sprime = get_value_fn (res); if (sprime @@ -1039,8 +1033,7 @@ substitute_and_fold_dom_walker::before_d /* No point propagating into a stmt we have a value for we can propagate into all uses. Mark it for removal instead. */ tree lhs = gimple_get_lhs (stmt); - if (do_dce - && lhs && TREE_CODE (lhs) == SSA_NAME) + if (lhs && TREE_CODE (lhs) == SSA_NAME) { tree sprime = get_value_fn (lhs); if (sprime @@ -1180,8 +1173,7 @@ substitute_and_fold_dom_walker::before_d bool substitute_and_fold (ssa_prop_get_value_fn get_value_fn, -ssa_prop_fold_stmt_fn fold_fn, -bool do_dce) +ssa_prop_fold_stmt_fn fold_fn) { gcc_assert (get_value_fn); @@ -1192,7 +1184,7 @@ substitute_and_fold (ssa_prop_get_value_ calculate_dominance_info (CDI_DOMINATORS); substitute_and_fold_dom_walker walker(CDI_DOMINATORS, - get_value_fn, fold_fn, do_dce); + get_value_fn, fold_fn);
[Bug tree-optimization/77943] [5/6 Regression] Optimization incorrectly commons noexcept calls with non-noexcept calls
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77943 --- Comment #13 from Martin Liška --- The replacement you described fully makes sense for me! As I mentioned earlier, I'm not c++ expert, I can't come up with more possible counter examples that worth for testing. However, we'll fix further issues ;)
Re: [PATCH] Clear BB_VISITED in bb-reorder
On Mon, 17 Oct 2016, Andrew Pinski wrote: > On Mon, Oct 17, 2016 at 5:26 AM, Richard Bienerwrote: > > > > $subject, applied as obvious. > > I think you should do the same for the vectorizer too. I noticed that > when testing the patch for loop splitting. Can't see where BB_VISITED is used by the vectorizer - can you point me to that? Thanks, Richard. > Thanks, > Andrew > > > > > Richard. > > > > 2016-10-17 Richard Biener > > > > * bb-reorder.c (reorder_basic_blocks_simple): Clear BB_VISITED > > before using it. > > > > Index: gcc/bb-reorder.c > > === > > --- gcc/bb-reorder.c(revision 241228) > > +++ gcc/bb-reorder.c(working copy) > > @@ -2355,7 +2355,10 @@ reorder_basic_blocks_simple (void) > > To start with, everything points to itself, nothing is assigned yet. > > */ > > > >FOR_ALL_BB_FN (bb, cfun) > > -bb->aux = bb; > > +{ > > + bb->aux = bb; > > + bb->flags &= ~BB_VISITED; > > +} > > > >EXIT_BLOCK_PTR_FOR_FN (cfun)->aux = 0; > >
Re: [PATCH] Simplify conditions in EVRP, handle taken edge
On Mon, 17 Oct 2016, Richard Biener wrote: > > This refactors propagation vs. substitution and handles condition > simplification properly as well as passing a known taken edge down > to the DOM walker (avoiding useless work and properly handling PHIs). > > If we do all the work it's stupid to not fold away dead code... > > Bootstrap and regtest pending on x86_64-unknown-linux-gnu. The following is what I applied, also fixing a spelling mistake noticed by Bernhard. Richard. 2016-10-18 Richard Biener* tree-vrp.c (evrp_dom_walker::before_dom_children): Handle not visited but non-executable predecessors. Return taken edge. Simplify conditions and refactor propagation vs. folding step. * gcc.dg/tree-ssa/pr20318.c: Disable EVRP. * gcc.dg/tree-ssa/pr21001.c: Likewise. * gcc.dg/tree-ssa/pr21090.c: Likewise. * gcc.dg/tree-ssa/pr21294.c: Likewise. * gcc.dg/tree-ssa/pr21563.c: Likewise. * gcc.dg/tree-ssa/pr23744.c: Likewise. * gcc.dg/tree-ssa/pr25382.c: Likewise. * gcc.dg/tree-ssa/pr68431.c: Likewise. * gcc.dg/tree-ssa/vrp03.c: Likewise. * gcc.dg/tree-ssa/vrp06.c: Likewise. * gcc.dg/tree-ssa/vrp07.c: Likewise. * gcc.dg/tree-ssa/vrp09.c: Likewise. * gcc.dg/tree-ssa/vrp19.c: Likewise. * gcc.dg/tree-ssa/vrp20.c: Likewise. * gcc.dg/tree-ssa/vrp92.c: Likewise. * gcc.dg/pr68217.c: Likewise. * gcc.dg/predict-9.c: Likewise. * gcc.dg/tree-prof/val-prof-5.c: Adjust. * gcc.dg/predict-1.c: Likewise. Index: gcc/tree-vrp.c === --- gcc/tree-vrp.c (revision 241242) +++ gcc/tree-vrp.c (working copy) @@ -10741,12 +10741,13 @@ evrp_dom_walker::before_dom_children (ba gimple_stmt_iterator gsi; edge e; edge_iterator ei; - bool has_unvisived_preds = false; + bool has_unvisited_preds = false; FOR_EACH_EDGE (e, ei, bb->preds) -if (!(e->src->flags & BB_VISITED)) +if (e->flags & EDGE_EXECUTABLE + && !(e->src->flags & BB_VISITED)) { - has_unvisived_preds = true; + has_unvisited_preds = true; break; } @@ -10756,7 +10757,7 @@ evrp_dom_walker::before_dom_children (ba gphi *phi = gpi.phi (); tree lhs = PHI_RESULT (phi); value_range vr_result = VR_INITIALIZER; - if (!has_unvisived_preds + if (!has_unvisited_preds && stmt_interesting_for_vrp (phi)) extract_range_from_phi_node (phi, _result); else @@ -10764,81 +10765,90 @@ evrp_dom_walker::before_dom_children (ba update_value_range (lhs, _result); } + edge taken_edge = NULL; + /* Visit all other stmts and discover any new VRs possible. */ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next ()) { gimple *stmt = gsi_stmt (gsi); - edge taken_edge; tree output = NULL_TREE; gimple *old_stmt = stmt; bool was_noreturn = (is_gimple_call (stmt) && gimple_call_noreturn_p (stmt)); - /* TODO, if found taken_edge, we should visit (return it) and travel -again to improve VR as done in DOM/SCCVN optimizations. It should -be done carefully as stmts might prematurely leave a BB like -in EH. */ - if (stmt_interesting_for_vrp (stmt)) + if (gcond *cond = dyn_cast (stmt)) + { + vrp_visit_cond_stmt (cond, _edge); + if (taken_edge) + { + if (taken_edge->flags & EDGE_TRUE_VALUE) + gimple_cond_make_true (cond); + else if (taken_edge->flags & EDGE_FALSE_VALUE) + gimple_cond_make_false (cond); + else + gcc_unreachable (); + } + } + else if (stmt_interesting_for_vrp (stmt)) { + edge taken_edge; value_range vr = VR_INITIALIZER; extract_range_from_stmt (stmt, _edge, , ); if (output && (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)) - update_value_range (output, ); - else - set_defs_to_varying (stmt); - - /* Try folding stmts with the VR discovered. */ - bool did_replace - = replace_uses_in (stmt, - op_with_constant_singleton_value_range); - if (fold_stmt (, follow_single_use_edges) - || did_replace) - update_stmt (gsi_stmt (gsi)); - - if (did_replace) { - /* If we cleaned up EH information from the statement, -remove EH edges. */ - if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt)) - bitmap_set_bit (need_eh_cleanup, bb->index); - - /* If we turned a not noreturn call into a noreturn one -schedule it for fixup. */ - if (!was_noreturn - && is_gimple_call (stmt) -
[Bug libstdc++/78015] New: pthread_cancel while some exception is pending results in std::terminate ()
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78015 Bug ID: 78015 Summary: pthread_cancel while some exception is pending results in std::terminate () Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: jakub at gcc dot gnu.org Target Milestone: --- #include #include namespace __cxxabiv1 { class __forced_unwind { virtual ~__forced_unwind() throw(); virtual void __pure_dummy() = 0; }; } int a; extern "C" void * fun (void *) { #ifdef WORKAROUND try { throw 1; } catch (int &) #endif { try { char buf[10]; for (;;) read (4, buf, 0); } catch (__cxxabiv1::__forced_unwind &) { a = 5; throw; } } return NULL; } int main () { pthread_t thread; pthread_create (, NULL, fun, NULL); pthread_cancel (thread); pthread_join (thread, NULL); } fails with std::terminate (), while works with -DWORKAROUND. The problem is in __cxa_begin_catch: 51// Note that this use of "header" is a lie. It's fine so long as we only 52// examine header->unwindHeader though. 53if (!__is_gxx_exception_class(header->unwindHeader.exception_class)) 54 { 55if (prev != 0) 56 std::terminate (); With -DWORKAROUND, prev is NULL and thus we handle it fine as forced unwinding exception. But without that, prev is non-NULL here. I don't know what exactly should we do instead if prev is non-NULL, whether to somehow destruct the previous exception, or just continue normally and destruct it when the forced unwinding finishes, or when.
Re: [PATCH] (PR 65950) Improve predicate for exit(0);
> > Ah, so you have > > > > foo () { loop } > > main() > > { > > if () > >{ > > foo (); > > exit (0); > >} > > ... > > return 0; > > } > > > > and foo is marked cold because its only call is on the path to exit (0)? > > > Actually the case I have here is just: > foo () { loop } > int main(void) > { > . > foo(); > ... > exit (0); > } > > Just an exit at the end of main. > Basically if we treat exit(0) as a normal function, main becomes hot again. Yep, it is old noreturn predicate lazynes. Path is OK Honza > > Thanks, > Andrew > > > > > noreturn prediction is quite aggressive but it works also quite well. Given > > you can only detect a very minor fraction of cases (consider exit (0) being > > in foo itself) I'm not sure that your fix is good progress. IMHO we might > > want to switch from 'noreturn' to 'noreturn' + likely error which needs > > another attribute / auto-discovery and IPA propagation to handle this case > > better. > > > > Anyway, I'll leave the patch to Honza. > > > > Richard. > > > >> Thanks, > >> Andrew > >> > >>> > >>> Richard. > >>> > OK? Bootstrapped and tested on aarch64-linux-gnu with no regressions. > Also tested it with SPEC CPU 2006 with no performance regressions. > > Thanks, > Andrew Pinski > > ChangeLog: > * predict.c (is_exit_with_zero_arg): New function. > (tree_bb_level_predictions): Don't consider paths leading to exit(0) > as nottaken.
Re: [PATCH] Fix cond-expr handling in genmatch
On Mon, 17 Oct 2016, Richard Biener wrote: > > This fixes matching of toplevel (cond (lt @1 @2) ...) as reported by > Bin to me privately. > > Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. This is what I applied. Richard. 2016-10-18 Richard Biener* genmatch.c (dt_operand::gen_gimple_expr): Use get_name to get at the operand to look at with TREE_OPERAND for generic sub-nodes. Index: gcc/genmatch.c === --- gcc/genmatch.c (revision 241228) +++ gcc/genmatch.c (working copy) @@ -2644,9 +2644,19 @@ dt_operand::gen_gimple_expr (FILE *f, in /* ??? If this is a memory operation we can't (and should not) match this. The only sensible operand types are SSA names and invariants. */ - fprintf_indent (f, indent, - "tree %s = TREE_OPERAND (gimple_assign_rhs1 (def), %i);\n", - child_opname, i); + if (e->is_generic) + { + char opname[20]; + get_name (opname); + fprintf_indent (f, indent, + "tree %s = TREE_OPERAND (%s, %i);\n", + child_opname, opname, i); + } + else + fprintf_indent (f, indent, + "tree %s = TREE_OPERAND " + "(gimple_assign_rhs1 (def), %i);\n", + child_opname, i); fprintf_indent (f, indent, "if ((TREE_CODE (%s) == SSA_NAME\n", child_opname);
[patch] Fix PHI optimization issue with boolean types
Hi, this is a regression present on the mainline and 6 branch: the compiler now generates wrong code for the attached testcase at -O because of an internal conflict about boolean types. The sequence is as follows. In .mergephi3: boolean _22; p__enum res; : if (_22 != 0) goto ; else goto ; : : # res_17 = PHI <2(8), 0(9), 1(10)> is turned into: COND_EXPR in block 9 and PHI in block 11 converted to straightline code. PHI res_17 changed to factor conversion out from COND_EXPR. New stmt with CAST that defines res_17. boolean _33; : # _33 = PHI <2(8), _22(9)> res_17 = (p__enum) _33; [...] : if (res_17 != 0) goto ; else goto ; : _12 = res_17 == 2; _13 = (integer) _12 in .phiopt1. So boolean _33 can have value 2. Later forwprop3 propagates _33 into the uses of res_17: : if (_33 != 0) goto ; else goto ; : _12 = _33 == 2; _13 = (integer) _12; and DOM3 deduces: : _12 = 0; _13 = 0; because it computes that _33 has value 1 in BB 13 since it's a boolean. The problem was introduced by the new factor_out_conditional_conversion: /* If arg1 is an INTEGER_CST, fold it to new type. */ if (INTEGRAL_TYPE_P (TREE_TYPE (new_arg0)) && int_fits_type_p (arg1, TREE_TYPE (new_arg0))) { if (gimple_assign_cast_p (arg0_def_stmt)) new_arg1 = fold_convert (TREE_TYPE (new_arg0), arg1); else return NULL; } else return NULL int_fits_type_p is documented as taking only INTEGER_TYPE, but is invoked on constant 2 and a BOOLEAN_TYPE and returns true. BOOLEAN_TYPE is special in Ada: it has precision 8 and range [0;255] so the outcome of int_fits_type_p is not unreasonable. But this goes against the various transformations applied to boolean types in the compiler, which all assume that they can only take values 0 or 1. Hence the attached fix (which should be a no-op except for Ada), tested on x86_64-suse-linux, OK for mainline and 6 branch? 2016-10-18 Eric Botcazou* tree.c (int_fits_type_p): Accept only 0 and 1 for boolean types. 2016-10-18 Eric Botcazou * gnat.dg/opt59.adb: New test. * gnat.dg/opt59_pkg.ad[sb]: New helper. -- Eric BotcazouIndex: tree.c === --- tree.c (revision 241294) +++ tree.c (working copy) @@ -9065,8 +9065,8 @@ get_narrower (tree op, int *unsignedp_pt return win; } -/* Returns true if integer constant C has a value that is permissible - for type TYPE (an INTEGER_TYPE). */ +/* Return true if integer constant C has a value that is permissible + for TYPE, an integral type. */ bool int_fits_type_p (const_tree c, const_tree type) @@ -9075,6 +9075,11 @@ int_fits_type_p (const_tree c, const_tre bool ok_for_low_bound, ok_for_high_bound; signop sgn_c = TYPE_SIGN (TREE_TYPE (c)); + /* Short-circuit boolean types since various transformations assume that + they can only take values 0 and 1. */ + if (TREE_CODE (type) == BOOLEAN_TYPE) +return integer_zerop (c) || integer_onep (c); + retry: type_low_bound = TYPE_MIN_VALUE (type); type_high_bound = TYPE_MAX_VALUE (type); -- { dg-do run } -- { dg-options "-O" } with Opt59_Pkg; use Opt59_Pkg; procedure Opt59 is type Enum is (Zero, One, Two); function Has_True (V : Boolean_Vector) return Boolean is begin for I in V'Range loop if V (I) then return True; end if; end loop; return False; end; Data1 : constant Boolean_Vector := Get_BV1; Data2 : constant Boolean_Vector := Get_BV2; Result : Boolean_Vector; function F return Enum is Res : Enum := Zero; Set1 : constant Boolean := Has_True (Data1); Set2 : constant Boolean := Has_True (Data2); begin if Set1 then Res := Two; elsif Set2 then Res := One; end if; return Res; end; Val : constant Enum := F; begin for I in Result'Range loop Result (I) := Data1 (I) or Data2 (I); end loop; if Val /= Zero then Test (Val = Two); end if; end; package body Opt59_Pkg is function Get_BV1 return Boolean_Vector is begin return (others => True); end; function Get_BV2 return Boolean_Vector is begin return (others => False); end; procedure Test (B : Boolean) is begin if not B then raise Program_Error; end if; end; end Opt59_Pkg; package Opt59_Pkg is type Boolean_Vector is array (1 .. 8) of Boolean; function Get_BV1 return Boolean_Vector; function Get_BV2 return Boolean_Vector; procedure Test (B : Boolean); end Opt59_Pkg;