[Bug fortran/68649] [6/7 Regression] note: code may be misoptimized unless -fno-strict-aliasing is used

2016-10-18 Thread Joost.VandeVondele at mat dot ethz.ch
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

2016-10-18 Thread Richard Biener

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

2016-10-18 Thread marxin at gcc dot gnu.org
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

2016-10-18 Thread Richard Biener
On Mon, 17 Oct 2016, Andrew Pinski wrote:

> On Mon, Oct 17, 2016 at 5:26 AM, Richard Biener  wrote:
> >
> > $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

2016-10-18 Thread Richard Biener
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 ()

2016-10-18 Thread jakub at gcc dot gnu.org
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);

2016-10-18 Thread Jan Hubicka
> > 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

2016-10-18 Thread Richard Biener
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

2016-10-18 Thread Eric Botcazou
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;


<    1   2   3