Re: types for VR_VARYING

2019-08-24 Thread Martin Sebor

On 8/24/19 4:55 AM, Aldy Hernandez wrote:



On 8/23/19 4:27 PM, Martin Sebor wrote:

On 8/15/19 10:06 AM, Aldy Hernandez wrote:




Hey Aldy,

After enabling EVRP for the strlen pass (as part of the sprintf
integration) I get a SEGV in the return statement in the function
below.  Backing out this change gets rid of the ICE and lets my
tests pass, but I have no idea what the root cause of the SEGV
might be.  The only mildly suspicious thing is the assertion in
the function:

@@ -355,9 +369,7 @@ value_range_base::singleton_p (tree *result) const
  tree
  value_range_base::type () const
  {
-  /* Types are only valid for VR_RANGE and VR_ANTI_RANGE, which are
- known to have non-zero min/max.  */
-  gcc_assert (min ());
+  gcc_assert (m_min || undefined_p ());
    return TREE_TYPE (min ());
  }


type() should really be:

tree
value_range_base::type () const
{
   gcc_assert (m_min);
   return TREE_TYPE (min ());
}

I should post a patch to fix this.  However, UNDEF should never have a 
type, so the assert will fail anyhow.


The code asking for the type of an UNDEF is wrong.



*this looks like so:

   (gdb) p *this
   $55 = {m_kind = VR_UNDEFINED, m_min = 0x0, m_max = 0x0}

so the assertion passes but the dererefence in TREE_TYPE fails.

The test case is trivial:

   void g (const char *a, const char *b)
   {
 if (__builtin_memcmp (a, b, 8))
   __builtin_abort ();
   }

The ICE happens when updating the range for the second statement
below:

   _1 = __builtin_memcmp (a_3(D), b_4(D), 8);
   _1 = (int) _8;

Any ideas?

Martin


during GIMPLE pass: strlen
u.c: In function ‘g’:
u.c:1:6: internal compiler error: Segmentation fault
 1 | void g (const char *a, const char *b)
   |  ^
0x11c4d08 crash_signal
 /src/gcc/svn/gcc/toplev.c:326
0x815519 contains_struct_check(tree_node*, tree_node_structure_enum, 
char const*, int, char const*)

 /src/gcc/svn/gcc/tree.h:3376
0x15e9391 value_range_base::type() const
 /src/gcc/svn/gcc/tree-vrp.c:373
0x16bdad6 vr_values::update_value_range(tree_node const*, value_range*)
 /src/gcc/svn/gcc/vr-values.c:237


According to your backtrace, it looks like the call to type comes from 
here:


   /* Do not allow transitions up the lattice.  The following
  is slightly more awkward than just new_vr->type < old_vr->type
  because VR_RANGE and VR_ANTI_RANGE need to be considered
  the same.  We may not have is_new when transitioning to
  UNDEFINED.  If old_vr->type is VARYING, we shouldn't be
  called, if we are anyway, keep it VARYING.  */
   if (old_vr->varying_p ())
     {
   new_vr->set_varying (new_vr->type ());
   is_new = false;
     }

So new_vr is UNDEFINED and we're asking for it's type.  That should 
probably be:


new_vr->set_varying (TREE_TYPE (var));

Would you mind testing the attached patch?

If it passes, feel free to commit it as obvious.

Thanks for catching this.


Thanks for the quick fix!  It cleared up the ICE for me.

Martin


Re: types for VR_VARYING

2019-08-24 Thread Aldy Hernandez



On 8/23/19 4:27 PM, Martin Sebor wrote:

On 8/15/19 10:06 AM, Aldy Hernandez wrote:




Hey Aldy,

After enabling EVRP for the strlen pass (as part of the sprintf
integration) I get a SEGV in the return statement in the function
below.  Backing out this change gets rid of the ICE and lets my
tests pass, but I have no idea what the root cause of the SEGV
might be.  The only mildly suspicious thing is the assertion in
the function:

@@ -355,9 +369,7 @@ value_range_base::singleton_p (tree *result) const
  tree
  value_range_base::type () const
  {
-  /* Types are only valid for VR_RANGE and VR_ANTI_RANGE, which are
- known to have non-zero min/max.  */
-  gcc_assert (min ());
+  gcc_assert (m_min || undefined_p ());
    return TREE_TYPE (min ());
  }


type() should really be:

tree
value_range_base::type () const
{
  gcc_assert (m_min);
  return TREE_TYPE (min ());
}

I should post a patch to fix this.  However, UNDEF should never have a 
type, so the assert will fail anyhow.


The code asking for the type of an UNDEF is wrong.



*this looks like so:

   (gdb) p *this
   $55 = {m_kind = VR_UNDEFINED, m_min = 0x0, m_max = 0x0}

so the assertion passes but the dererefence in TREE_TYPE fails.

The test case is trivial:

   void g (const char *a, const char *b)
   {
     if (__builtin_memcmp (a, b, 8))
   __builtin_abort ();
   }

The ICE happens when updating the range for the second statement
below:

   _1 = __builtin_memcmp (a_3(D), b_4(D), 8);
   _1 = (int) _8;

Any ideas?

Martin


during GIMPLE pass: strlen
u.c: In function ‘g’:
u.c:1:6: internal compiler error: Segmentation fault
     1 | void g (const char *a, const char *b)
   |  ^
0x11c4d08 crash_signal
 /src/gcc/svn/gcc/toplev.c:326
0x815519 contains_struct_check(tree_node*, tree_node_structure_enum, 
char const*, int, char const*)

 /src/gcc/svn/gcc/tree.h:3376
0x15e9391 value_range_base::type() const
 /src/gcc/svn/gcc/tree-vrp.c:373
0x16bdad6 vr_values::update_value_range(tree_node const*, value_range*)
 /src/gcc/svn/gcc/vr-values.c:237


According to your backtrace, it looks like the call to type comes from here:

  /* Do not allow transitions up the lattice.  The following
 is slightly more awkward than just new_vr->type < old_vr->type
 because VR_RANGE and VR_ANTI_RANGE need to be considered
 the same.  We may not have is_new when transitioning to
 UNDEFINED.  If old_vr->type is VARYING, we shouldn't be
 called, if we are anyway, keep it VARYING.  */
  if (old_vr->varying_p ())
{
  new_vr->set_varying (new_vr->type ());
  is_new = false;
}

So new_vr is UNDEFINED and we're asking for it's type.  That should 
probably be:


new_vr->set_varying (TREE_TYPE (var));

Would you mind testing the attached patch?

If it passes, feel free to commit it as obvious.

Thanks for catching this.

Aldy
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 8067f8560cd..97a82e6ee24 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -369,7 +369,7 @@ value_range_base::singleton_p (tree *result) const
 tree
 value_range_base::type () const
 {
-  gcc_assert (m_min || undefined_p ());
+  gcc_assert (m_min);
   return TREE_TYPE (min ());
 }
 
diff --git a/gcc/vr-values.c b/gcc/vr-values.c
index 6f9a3612931..96c764c987b 100644
--- a/gcc/vr-values.c
+++ b/gcc/vr-values.c
@@ -234,7 +234,7 @@ vr_values::update_value_range (const_tree var, value_range *new_vr)
 	 called, if we are anyway, keep it VARYING.  */
   if (old_vr->varying_p ())
 	{
-	  new_vr->set_varying (new_vr->type ());
+	  new_vr->set_varying (TREE_TYPE (var));
 	  is_new = false;
 	}
   else if (new_vr->undefined_p ())


Re: types for VR_VARYING

2019-08-23 Thread Martin Sebor

On 8/15/19 10:06 AM, Aldy Hernandez wrote:




Hey Aldy,

After enabling EVRP for the strlen pass (as part of the sprintf
integration) I get a SEGV in the return statement in the function
below.  Backing out this change gets rid of the ICE and lets my
tests pass, but I have no idea what the root cause of the SEGV
might be.  The only mildly suspicious thing is the assertion in
the function:

@@ -355,9 +369,7 @@ value_range_base::singleton_p (tree *result) const
 tree
 value_range_base::type () const
 {
-  /* Types are only valid for VR_RANGE and VR_ANTI_RANGE, which are
- known to have non-zero min/max.  */
-  gcc_assert (min ());
+  gcc_assert (m_min || undefined_p ());
   return TREE_TYPE (min ());
 }

*this looks like so:

  (gdb) p *this
  $55 = {m_kind = VR_UNDEFINED, m_min = 0x0, m_max = 0x0}

so the assertion passes but the dererefence in TREE_TYPE fails.

The test case is trivial:

  void g (const char *a, const char *b)
  {
if (__builtin_memcmp (a, b, 8))
  __builtin_abort ();
  }

The ICE happens when updating the range for the second statement
below:

  _1 = __builtin_memcmp (a_3(D), b_4(D), 8);
  _1 = (int) _8;

Any ideas?

Martin


during GIMPLE pass: strlen
u.c: In function ‘g’:
u.c:1:6: internal compiler error: Segmentation fault
1 | void g (const char *a, const char *b)
  |  ^
0x11c4d08 crash_signal
/src/gcc/svn/gcc/toplev.c:326
0x815519 contains_struct_check(tree_node*, tree_node_structure_enum, 
char const*, int, char const*)

/src/gcc/svn/gcc/tree.h:3376
0x15e9391 value_range_base::type() const
/src/gcc/svn/gcc/tree-vrp.c:373
0x16bdad6 vr_values::update_value_range(tree_node const*, value_range*)
/src/gcc/svn/gcc/vr-values.c:237
0x200f9a9 evrp_range_analyzer::record_ranges_from_stmt(gimple*, bool)
/src/gcc/svn/gcc/gimple-ssa-evrp-analyze.c:325
0x14c9062 strlen_dom_walker::before_dom_children(basic_block_def*)
/src/gcc/svn/gcc/tree-ssa-strlen.c:4800
0x1fbdf8a dom_walker::walk(basic_block_def*)
/src/gcc/svn/gcc/domwalk.c:309
0x14c9362 printf_strlen_execute
/src/gcc/svn/gcc/tree-ssa-strlen.c:4866
0x14c95f8 execute
/src/gcc/svn/gcc/tree-ssa-strlen.c:4968
Please submit a full bug report,


Re: types for VR_VARYING

2019-08-16 Thread Jeff Law
On 8/15/19 10:06 AM, Aldy Hernandez wrote:
> 
> 
> On 8/15/19 7:23 AM, Richard Biener wrote:
>> On Thu, Aug 15, 2019 at 12:40 PM Aldy Hernandez  wrote:
>>>
>>> On 8/14/19 1:37 PM, Jeff Law wrote:
 On 8/13/19 6:39 PM, Aldy Hernandez wrote:
>
>
> On 8/12/19 7:46 PM, Jeff Law wrote:
>> On 8/12/19 12:43 PM, Aldy Hernandez wrote:
>>> This is a fresh re-post of:
>>>
>>> https://gcc.gnu.org/ml/gcc-patches/2019-07/msg6.html
>>>
>>> Andrew gave me some feedback a week ago, and I obviously don't
>>> remember
>>> what it was because I was about to leave on PTO.  However, I do
>>> remember
>>> I addressed his concerns before getting drunk on rum in tropical
>>> islands.
>>>
>> FWIW found a great coffee infused rum while in Kauai last week. 
>> I'm not
>> a coffee fan, but it was wonderful.  The one bottle we brought back
>> isn't going to last until Cauldron and I don't think I can get a
>> special
>> order filled before I leave :(
>
> You must bring some to Cauldron before we believe you. :)
 That's the problem.  The nearest place I can get it is in Vegas and
 there's no distributor in Montreal.   I can special order it in our
 state run stores, but it won't be here in time.

 Of course, I don't mind if you don't believe me.  More for me in that
 case...


>> Is the supports_type_p stuff there to placate the calls from
>> ipa-cp?  I
>> can live with it in the short term, but it really feels like there
>> should be something in the ipa-cp client that avoids this silliness.
>
> I am not happy with this either, but there are various places where
> statements that are !stmt_interesting_for_vrp() are still setting a
> range of VARYING, which is then being ignored at a later time.
>
> For example, vrp_initialize:
>
>     if (!stmt_interesting_for_vrp (phi))
>   {
>     tree lhs = PHI_RESULT (phi);
>     set_def_to_varying (lhs);
>     prop_set_simulate_again (phi, false);
>   }
>
> Also in evrp_range_analyzer::record_ranges_from_stmt(), where we if
> the
> statement is interesting for VRP but extract_range_from_stmt() does
> not
> produce a useful range, we also set a varying for a range we will
> never
> use.  Similarly for a statement that is not interesting in this hunk.
 Ugh.  One could perhaps argue that setting any kind of range in these
 circumstances is silly.   But I suspect it's necessary due to the
 optimistic handling of VR_UNDEFINED in value_range_base::union_helper.
 It's all coming back to me now...


>
> Then there is vrp_prop::visit_stmt() where we also set VARYING for
> types
> that VRP will never handle:
>
>     case IFN_ADD_OVERFLOW:
>     case IFN_SUB_OVERFLOW:
>     case IFN_MUL_OVERFLOW:
>     case IFN_ATOMIC_COMPARE_EXCHANGE:
>   /* These internal calls return _Complex integer type,
>  which VRP does not track, but the immediate uses
>  thereof might be interesting.  */
>   if (lhs && TREE_CODE (lhs) == SSA_NAME)
>     {
>   imm_use_iterator iter;
>   use_operand_p use_p;
>   enum ssa_prop_result res = SSA_PROP_VARYING;
>
>   set_def_to_varying (lhs);
>
> I've adjusted the patch so that set_def_to_varying will set the
> range to
> VR_UNDEFINED if !supports_type_p.  This is a fail safe, as we can't
> really do anything with a nonsensical range.  I just don't want to
> leave
> the range in an indeterminate state.
>
 I think VR_UNDEFINED is unsafe due to value_range_base::union_helper.
 And that's a more general than this patch.  VR_UNDEFINED is _not_ a
 safe
 range to set something to if we can't handle it.  We have to use
 VR_VARYING.

 Why?  See the beginning of value_range_base::union_helper:

  /* VR0 has the resulting range if VR1 is undefined or VR0 is
 varying.  */
  if (vr1->undefined_p ()
  || vr0->varying_p ())
    return *vr0;

  /* VR1 has the resulting range if VR0 is undefined or VR1 is
 varying.  */
  if (vr0->undefined_p ()
  || vr1->varying_p ())
    return *vr1;
 This can get called for something like

     a =  ? name1 : name2;

 If name1 was set to VR_UNDEFINED thinking that VR_UNDEFINED was a safe
 value for something we can't handle, then we'll incorrectly return the
 range for name2.
>>>
>>> I think that if name1 was !supports_type_p, we will have never called
>>> union/intersect.  We will have bailed at some point earlier.  However, I
>>> do see your point about being consistent.
>>>

 VR_UNDEFINED can only be used for the ranges of objects we haven't
>>

Re: types for VR_VARYING

2019-08-15 Thread Aldy Hernandez

On 8/15/19 12:06 PM, Aldy Hernandez wrote:



On 8/15/19 7:23 AM, Richard Biener wrote:

On Thu, Aug 15, 2019 at 12:40 PM Aldy Hernandez  wrote:


On 8/14/19 1:37 PM, Jeff Law wrote:

On 8/13/19 6:39 PM, Aldy Hernandez wrote:



On 8/12/19 7:46 PM, Jeff Law wrote:

On 8/12/19 12:43 PM, Aldy Hernandez wrote:

This is a fresh re-post of:

https://gcc.gnu.org/ml/gcc-patches/2019-07/msg6.html

Andrew gave me some feedback a week ago, and I obviously don't 
remember
what it was because I was about to leave on PTO.  However, I do 
remember
I addressed his concerns before getting drunk on rum in tropical 
islands.


FWIW found a great coffee infused rum while in Kauai last week.  
I'm not

a coffee fan, but it was wonderful.  The one bottle we brought back
isn't going to last until Cauldron and I don't think I can get a 
special

order filled before I leave :(


You must bring some to Cauldron before we believe you. :)

That's the problem.  The nearest place I can get it is in Vegas and
there's no distributor in Montreal.   I can special order it in our
state run stores, but it won't be here in time.

Of course, I don't mind if you don't believe me.  More for me in that
case...


Is the supports_type_p stuff there to placate the calls from 
ipa-cp?  I

can live with it in the short term, but it really feels like there
should be something in the ipa-cp client that avoids this silliness.


I am not happy with this either, but there are various places where
statements that are !stmt_interesting_for_vrp() are still setting a
range of VARYING, which is then being ignored at a later time.

For example, vrp_initialize:

    if (!stmt_interesting_for_vrp (phi))
  {
    tree lhs = PHI_RESULT (phi);
    set_def_to_varying (lhs);
    prop_set_simulate_again (phi, false);
  }

Also in evrp_range_analyzer::record_ranges_from_stmt(), where we if 
the
statement is interesting for VRP but extract_range_from_stmt() does 
not
produce a useful range, we also set a varying for a range we will 
never

use.  Similarly for a statement that is not interesting in this hunk.

Ugh.  One could perhaps argue that setting any kind of range in these
circumstances is silly.   But I suspect it's necessary due to the
optimistic handling of VR_UNDEFINED in value_range_base::union_helper.
It's all coming back to me now...




Then there is vrp_prop::visit_stmt() where we also set VARYING for 
types

that VRP will never handle:

    case IFN_ADD_OVERFLOW:
    case IFN_SUB_OVERFLOW:
    case IFN_MUL_OVERFLOW:
    case IFN_ATOMIC_COMPARE_EXCHANGE:
  /* These internal calls return _Complex integer type,
 which VRP does not track, but the immediate uses
 thereof might be interesting.  */
  if (lhs && TREE_CODE (lhs) == SSA_NAME)
    {
  imm_use_iterator iter;
  use_operand_p use_p;
  enum ssa_prop_result res = SSA_PROP_VARYING;

  set_def_to_varying (lhs);

I've adjusted the patch so that set_def_to_varying will set the 
range to

VR_UNDEFINED if !supports_type_p.  This is a fail safe, as we can't
really do anything with a nonsensical range.  I just don't want to 
leave

the range in an indeterminate state.


I think VR_UNDEFINED is unsafe due to value_range_base::union_helper.
And that's a more general than this patch.  VR_UNDEFINED is _not_ a 
safe
range to set something to if we can't handle it.  We have to use 
VR_VARYING.


Why?  See the beginning of value_range_base::union_helper:

 /* VR0 has the resulting range if VR1 is undefined or VR0 is 
varying.  */

 if (vr1->undefined_p ()
 || vr0->varying_p ())
   return *vr0;

 /* VR1 has the resulting range if VR0 is undefined or VR1 is 
varying.  */

 if (vr0->undefined_p ()
 || vr1->varying_p ())
   return *vr1;
This can get called for something like

    a =  ? name1 : name2;

If name1 was set to VR_UNDEFINED thinking that VR_UNDEFINED was a safe
value for something we can't handle, then we'll incorrectly return the
range for name2.


I think that if name1 was !supports_type_p, we will have never called
union/intersect.  We will have bailed at some point earlier.  However, I
do see your point about being consistent.



VR_UNDEFINED can only be used for the ranges of objects we haven't
processed.  If we can't produce a range for an object because the
statement is something we don't handle or just doesn't produce anythign
useful, then the right result is VR_VARYING.

This may be worth commenting at the definition site for VR_*.



I also noticed that Andrew's patch was setting num_vr_values to
num_ssa_names + num_ssa_names / 10.  I think he meant num_vr_values +
num_vr_values / 10.  Please verify the current incantation makes 
sense.
Going to assume this will be adjusted per the other messages in this 
thread.


Done.





diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 39ea22f0554..663dd6e2398 100644
--- a/gcc/tre

Re: types for VR_VARYING

2019-08-15 Thread Aldy Hernandez



On 8/15/19 7:23 AM, Richard Biener wrote:

On Thu, Aug 15, 2019 at 12:40 PM Aldy Hernandez  wrote:


On 8/14/19 1:37 PM, Jeff Law wrote:

On 8/13/19 6:39 PM, Aldy Hernandez wrote:



On 8/12/19 7:46 PM, Jeff Law wrote:

On 8/12/19 12:43 PM, Aldy Hernandez wrote:

This is a fresh re-post of:

https://gcc.gnu.org/ml/gcc-patches/2019-07/msg6.html

Andrew gave me some feedback a week ago, and I obviously don't remember
what it was because I was about to leave on PTO.  However, I do remember
I addressed his concerns before getting drunk on rum in tropical islands.


FWIW found a great coffee infused rum while in Kauai last week.  I'm not
a coffee fan, but it was wonderful.  The one bottle we brought back
isn't going to last until Cauldron and I don't think I can get a special
order filled before I leave :(


You must bring some to Cauldron before we believe you. :)

That's the problem.  The nearest place I can get it is in Vegas and
there's no distributor in Montreal.   I can special order it in our
state run stores, but it won't be here in time.

Of course, I don't mind if you don't believe me.  More for me in that
case...



Is the supports_type_p stuff there to placate the calls from ipa-cp?  I
can live with it in the short term, but it really feels like there
should be something in the ipa-cp client that avoids this silliness.


I am not happy with this either, but there are various places where
statements that are !stmt_interesting_for_vrp() are still setting a
range of VARYING, which is then being ignored at a later time.

For example, vrp_initialize:

if (!stmt_interesting_for_vrp (phi))
  {
tree lhs = PHI_RESULT (phi);
set_def_to_varying (lhs);
prop_set_simulate_again (phi, false);
  }

Also in evrp_range_analyzer::record_ranges_from_stmt(), where we if the
statement is interesting for VRP but extract_range_from_stmt() does not
produce a useful range, we also set a varying for a range we will never
use.  Similarly for a statement that is not interesting in this hunk.

Ugh.  One could perhaps argue that setting any kind of range in these
circumstances is silly.   But I suspect it's necessary due to the
optimistic handling of VR_UNDEFINED in value_range_base::union_helper.
It's all coming back to me now...




Then there is vrp_prop::visit_stmt() where we also set VARYING for types
that VRP will never handle:

case IFN_ADD_OVERFLOW:
case IFN_SUB_OVERFLOW:
case IFN_MUL_OVERFLOW:
case IFN_ATOMIC_COMPARE_EXCHANGE:
  /* These internal calls return _Complex integer type,
 which VRP does not track, but the immediate uses
 thereof might be interesting.  */
  if (lhs && TREE_CODE (lhs) == SSA_NAME)
{
  imm_use_iterator iter;
  use_operand_p use_p;
  enum ssa_prop_result res = SSA_PROP_VARYING;

  set_def_to_varying (lhs);

I've adjusted the patch so that set_def_to_varying will set the range to
VR_UNDEFINED if !supports_type_p.  This is a fail safe, as we can't
really do anything with a nonsensical range.  I just don't want to leave
the range in an indeterminate state.


I think VR_UNDEFINED is unsafe due to value_range_base::union_helper.
And that's a more general than this patch.  VR_UNDEFINED is _not_ a safe
range to set something to if we can't handle it.  We have to use VR_VARYING.

Why?  See the beginning of value_range_base::union_helper:

 /* VR0 has the resulting range if VR1 is undefined or VR0 is varying.  */
 if (vr1->undefined_p ()
 || vr0->varying_p ())
   return *vr0;

 /* VR1 has the resulting range if VR0 is undefined or VR1 is varying.  */
 if (vr0->undefined_p ()
 || vr1->varying_p ())
   return *vr1;
This can get called for something like

a =  ? name1 : name2;

If name1 was set to VR_UNDEFINED thinking that VR_UNDEFINED was a safe
value for something we can't handle, then we'll incorrectly return the
range for name2.


I think that if name1 was !supports_type_p, we will have never called
union/intersect.  We will have bailed at some point earlier.  However, I
do see your point about being consistent.



VR_UNDEFINED can only be used for the ranges of objects we haven't
processed.  If we can't produce a range for an object because the
statement is something we don't handle or just doesn't produce anythign
useful, then the right result is VR_VARYING.

This may be worth commenting at the definition site for VR_*.



I also noticed that Andrew's patch was setting num_vr_values to
num_ssa_names + num_ssa_names / 10.  I think he meant num_vr_values +
num_vr_values / 10.  Please verify the current incantation makes sense.

Going to assume this will be adjusted per the other messages in this thread.


Done.





diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 39ea22f0554..663dd6e2398 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -182,8 +182,10 @

Re: types for VR_VARYING

2019-08-15 Thread Aldy Hernandez




On 8/15/19 7:23 AM, Richard Biener wrote:

On Thu, Aug 15, 2019 at 12:40 PM Aldy Hernandez  wrote:


On 8/14/19 1:37 PM, Jeff Law wrote:

On 8/13/19 6:39 PM, Aldy Hernandez wrote:



On 8/12/19 7:46 PM, Jeff Law wrote:

On 8/12/19 12:43 PM, Aldy Hernandez wrote:

This is a fresh re-post of:

https://gcc.gnu.org/ml/gcc-patches/2019-07/msg6.html

Andrew gave me some feedback a week ago, and I obviously don't remember
what it was because I was about to leave on PTO.  However, I do remember
I addressed his concerns before getting drunk on rum in tropical islands.


FWIW found a great coffee infused rum while in Kauai last week.  I'm not
a coffee fan, but it was wonderful.  The one bottle we brought back
isn't going to last until Cauldron and I don't think I can get a special
order filled before I leave :(


You must bring some to Cauldron before we believe you. :)

That's the problem.  The nearest place I can get it is in Vegas and
there's no distributor in Montreal.   I can special order it in our
state run stores, but it won't be here in time.

Of course, I don't mind if you don't believe me.  More for me in that
case...



Is the supports_type_p stuff there to placate the calls from ipa-cp?  I
can live with it in the short term, but it really feels like there
should be something in the ipa-cp client that avoids this silliness.


I am not happy with this either, but there are various places where
statements that are !stmt_interesting_for_vrp() are still setting a
range of VARYING, which is then being ignored at a later time.

For example, vrp_initialize:

if (!stmt_interesting_for_vrp (phi))
  {
tree lhs = PHI_RESULT (phi);
set_def_to_varying (lhs);
prop_set_simulate_again (phi, false);
  }

Also in evrp_range_analyzer::record_ranges_from_stmt(), where we if the
statement is interesting for VRP but extract_range_from_stmt() does not
produce a useful range, we also set a varying for a range we will never
use.  Similarly for a statement that is not interesting in this hunk.

Ugh.  One could perhaps argue that setting any kind of range in these
circumstances is silly.   But I suspect it's necessary due to the
optimistic handling of VR_UNDEFINED in value_range_base::union_helper.
It's all coming back to me now...




Then there is vrp_prop::visit_stmt() where we also set VARYING for types
that VRP will never handle:

case IFN_ADD_OVERFLOW:
case IFN_SUB_OVERFLOW:
case IFN_MUL_OVERFLOW:
case IFN_ATOMIC_COMPARE_EXCHANGE:
  /* These internal calls return _Complex integer type,
 which VRP does not track, but the immediate uses
 thereof might be interesting.  */
  if (lhs && TREE_CODE (lhs) == SSA_NAME)
{
  imm_use_iterator iter;
  use_operand_p use_p;
  enum ssa_prop_result res = SSA_PROP_VARYING;

  set_def_to_varying (lhs);

I've adjusted the patch so that set_def_to_varying will set the range to
VR_UNDEFINED if !supports_type_p.  This is a fail safe, as we can't
really do anything with a nonsensical range.  I just don't want to leave
the range in an indeterminate state.


I think VR_UNDEFINED is unsafe due to value_range_base::union_helper.
And that's a more general than this patch.  VR_UNDEFINED is _not_ a safe
range to set something to if we can't handle it.  We have to use VR_VARYING.

Why?  See the beginning of value_range_base::union_helper:

 /* VR0 has the resulting range if VR1 is undefined or VR0 is varying.  */
 if (vr1->undefined_p ()
 || vr0->varying_p ())
   return *vr0;

 /* VR1 has the resulting range if VR0 is undefined or VR1 is varying.  */
 if (vr0->undefined_p ()
 || vr1->varying_p ())
   return *vr1;
This can get called for something like

a =  ? name1 : name2;

If name1 was set to VR_UNDEFINED thinking that VR_UNDEFINED was a safe
value for something we can't handle, then we'll incorrectly return the
range for name2.


I think that if name1 was !supports_type_p, we will have never called
union/intersect.  We will have bailed at some point earlier.  However, I
do see your point about being consistent.



VR_UNDEFINED can only be used for the ranges of objects we haven't
processed.  If we can't produce a range for an object because the
statement is something we don't handle or just doesn't produce anythign
useful, then the right result is VR_VARYING.

This may be worth commenting at the definition site for VR_*.



I also noticed that Andrew's patch was setting num_vr_values to
num_ssa_names + num_ssa_names / 10.  I think he meant num_vr_values +
num_vr_values / 10.  Please verify the current incantation makes sense.

Going to assume this will be adjusted per the other messages in this thread.


Done.





diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 39ea22f0554..663dd6e2398 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -182,8 +182,10 

Re: types for VR_VARYING

2019-08-15 Thread Richard Biener
On Thu, Aug 15, 2019 at 12:40 PM Aldy Hernandez  wrote:
>
> On 8/14/19 1:37 PM, Jeff Law wrote:
> > On 8/13/19 6:39 PM, Aldy Hernandez wrote:
> >>
> >>
> >> On 8/12/19 7:46 PM, Jeff Law wrote:
> >>> On 8/12/19 12:43 PM, Aldy Hernandez wrote:
>  This is a fresh re-post of:
> 
>  https://gcc.gnu.org/ml/gcc-patches/2019-07/msg6.html
> 
>  Andrew gave me some feedback a week ago, and I obviously don't remember
>  what it was because I was about to leave on PTO.  However, I do remember
>  I addressed his concerns before getting drunk on rum in tropical islands.
> 
> >>> FWIW found a great coffee infused rum while in Kauai last week.  I'm not
> >>> a coffee fan, but it was wonderful.  The one bottle we brought back
> >>> isn't going to last until Cauldron and I don't think I can get a special
> >>> order filled before I leave :(
> >>
> >> You must bring some to Cauldron before we believe you. :)
> > That's the problem.  The nearest place I can get it is in Vegas and
> > there's no distributor in Montreal.   I can special order it in our
> > state run stores, but it won't be here in time.
> >
> > Of course, I don't mind if you don't believe me.  More for me in that
> > case...
> >
> >
> >>> Is the supports_type_p stuff there to placate the calls from ipa-cp?  I
> >>> can live with it in the short term, but it really feels like there
> >>> should be something in the ipa-cp client that avoids this silliness.
> >>
> >> I am not happy with this either, but there are various places where
> >> statements that are !stmt_interesting_for_vrp() are still setting a
> >> range of VARYING, which is then being ignored at a later time.
> >>
> >> For example, vrp_initialize:
> >>
> >>if (!stmt_interesting_for_vrp (phi))
> >>  {
> >>tree lhs = PHI_RESULT (phi);
> >>set_def_to_varying (lhs);
> >>prop_set_simulate_again (phi, false);
> >>  }
> >>
> >> Also in evrp_range_analyzer::record_ranges_from_stmt(), where we if the
> >> statement is interesting for VRP but extract_range_from_stmt() does not
> >> produce a useful range, we also set a varying for a range we will never
> >> use.  Similarly for a statement that is not interesting in this hunk.
> > Ugh.  One could perhaps argue that setting any kind of range in these
> > circumstances is silly.   But I suspect it's necessary due to the
> > optimistic handling of VR_UNDEFINED in value_range_base::union_helper.
> > It's all coming back to me now...
> >
> >
> >>
> >> Then there is vrp_prop::visit_stmt() where we also set VARYING for types
> >> that VRP will never handle:
> >>
> >>case IFN_ADD_OVERFLOW:
> >>case IFN_SUB_OVERFLOW:
> >>case IFN_MUL_OVERFLOW:
> >>case IFN_ATOMIC_COMPARE_EXCHANGE:
> >>  /* These internal calls return _Complex integer type,
> >> which VRP does not track, but the immediate uses
> >> thereof might be interesting.  */
> >>  if (lhs && TREE_CODE (lhs) == SSA_NAME)
> >>{
> >>  imm_use_iterator iter;
> >>  use_operand_p use_p;
> >>  enum ssa_prop_result res = SSA_PROP_VARYING;
> >>
> >>  set_def_to_varying (lhs);
> >>
> >> I've adjusted the patch so that set_def_to_varying will set the range to
> >> VR_UNDEFINED if !supports_type_p.  This is a fail safe, as we can't
> >> really do anything with a nonsensical range.  I just don't want to leave
> >> the range in an indeterminate state.
> >>
> > I think VR_UNDEFINED is unsafe due to value_range_base::union_helper.
> > And that's a more general than this patch.  VR_UNDEFINED is _not_ a safe
> > range to set something to if we can't handle it.  We have to use VR_VARYING.
> >
> > Why?  See the beginning of value_range_base::union_helper:
> >
> > /* VR0 has the resulting range if VR1 is undefined or VR0 is varying.  
> > */
> > if (vr1->undefined_p ()
> > || vr0->varying_p ())
> >   return *vr0;
> >
> > /* VR1 has the resulting range if VR0 is undefined or VR1 is varying.  
> > */
> > if (vr0->undefined_p ()
> > || vr1->varying_p ())
> >   return *vr1;
> > This can get called for something like
> >
> >a =  ? name1 : name2;
> >
> > If name1 was set to VR_UNDEFINED thinking that VR_UNDEFINED was a safe
> > value for something we can't handle, then we'll incorrectly return the
> > range for name2.
>
> I think that if name1 was !supports_type_p, we will have never called
> union/intersect.  We will have bailed at some point earlier.  However, I
> do see your point about being consistent.
>
> >
> > VR_UNDEFINED can only be used for the ranges of objects we haven't
> > processed.  If we can't produce a range for an object because the
> > statement is something we don't handle or just doesn't produce anythign
> > useful, then the right result is VR_VARYING.
> >
> > This may be worth commenting at the definition site for VR_*.
> >
> >>
> >> I also noticed that Andrew's patch was setting num_vr_

Re: types for VR_VARYING

2019-08-15 Thread Aldy Hernandez

On 8/14/19 1:37 PM, Jeff Law wrote:

On 8/13/19 6:39 PM, Aldy Hernandez wrote:



On 8/12/19 7:46 PM, Jeff Law wrote:

On 8/12/19 12:43 PM, Aldy Hernandez wrote:

This is a fresh re-post of:

https://gcc.gnu.org/ml/gcc-patches/2019-07/msg6.html

Andrew gave me some feedback a week ago, and I obviously don't remember
what it was because I was about to leave on PTO.  However, I do remember
I addressed his concerns before getting drunk on rum in tropical islands.


FWIW found a great coffee infused rum while in Kauai last week.  I'm not
a coffee fan, but it was wonderful.  The one bottle we brought back
isn't going to last until Cauldron and I don't think I can get a special
order filled before I leave :(


You must bring some to Cauldron before we believe you. :)

That's the problem.  The nearest place I can get it is in Vegas and
there's no distributor in Montreal.   I can special order it in our
state run stores, but it won't be here in time.

Of course, I don't mind if you don't believe me.  More for me in that
case...



Is the supports_type_p stuff there to placate the calls from ipa-cp?  I
can live with it in the short term, but it really feels like there
should be something in the ipa-cp client that avoids this silliness.


I am not happy with this either, but there are various places where
statements that are !stmt_interesting_for_vrp() are still setting a
range of VARYING, which is then being ignored at a later time.

For example, vrp_initialize:

   if (!stmt_interesting_for_vrp (phi))
 {
   tree lhs = PHI_RESULT (phi);
   set_def_to_varying (lhs);
   prop_set_simulate_again (phi, false);
 }

Also in evrp_range_analyzer::record_ranges_from_stmt(), where we if the
statement is interesting for VRP but extract_range_from_stmt() does not
produce a useful range, we also set a varying for a range we will never
use.  Similarly for a statement that is not interesting in this hunk.

Ugh.  One could perhaps argue that setting any kind of range in these
circumstances is silly.   But I suspect it's necessary due to the
optimistic handling of VR_UNDEFINED in value_range_base::union_helper.
It's all coming back to me now...




Then there is vrp_prop::visit_stmt() where we also set VARYING for types
that VRP will never handle:

   case IFN_ADD_OVERFLOW:
   case IFN_SUB_OVERFLOW:
   case IFN_MUL_OVERFLOW:
   case IFN_ATOMIC_COMPARE_EXCHANGE:
 /* These internal calls return _Complex integer type,
    which VRP does not track, but the immediate uses
    thereof might be interesting.  */
 if (lhs && TREE_CODE (lhs) == SSA_NAME)
   {
 imm_use_iterator iter;
 use_operand_p use_p;
 enum ssa_prop_result res = SSA_PROP_VARYING;

 set_def_to_varying (lhs);

I've adjusted the patch so that set_def_to_varying will set the range to
VR_UNDEFINED if !supports_type_p.  This is a fail safe, as we can't
really do anything with a nonsensical range.  I just don't want to leave
the range in an indeterminate state.


I think VR_UNDEFINED is unsafe due to value_range_base::union_helper.
And that's a more general than this patch.  VR_UNDEFINED is _not_ a safe
range to set something to if we can't handle it.  We have to use VR_VARYING.

Why?  See the beginning of value_range_base::union_helper:

/* VR0 has the resulting range if VR1 is undefined or VR0 is varying.  */
if (vr1->undefined_p ()
|| vr0->varying_p ())
  return *vr0;

/* VR1 has the resulting range if VR0 is undefined or VR1 is varying.  */
if (vr0->undefined_p ()
|| vr1->varying_p ())
  return *vr1;
This can get called for something like

   a =  ? name1 : name2;

If name1 was set to VR_UNDEFINED thinking that VR_UNDEFINED was a safe
value for something we can't handle, then we'll incorrectly return the
range for name2.


I think that if name1 was !supports_type_p, we will have never called 
union/intersect.  We will have bailed at some point earlier.  However, I 
do see your point about being consistent.




VR_UNDEFINED can only be used for the ranges of objects we haven't
processed.  If we can't produce a range for an object because the
statement is something we don't handle or just doesn't produce anythign
useful, then the right result is VR_VARYING.

This may be worth commenting at the definition site for VR_*.



I also noticed that Andrew's patch was setting num_vr_values to
num_ssa_names + num_ssa_names / 10.  I think he meant num_vr_values +
num_vr_values / 10.  Please verify the current incantation makes sense.

Going to assume this will be adjusted per the other messages in this thread.


Done.





diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 39ea22f0554..663dd6e2398 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -182,8 +182,10 @@ record_temporary_equivalences_from_phis (edge e,
new_vr->deep_copy (vr_values->get_value_range (src));
  e

Re: types for VR_VARYING

2019-08-14 Thread Jeff Law
On 8/13/19 6:39 PM, Aldy Hernandez wrote:
> 
> 
> On 8/12/19 7:46 PM, Jeff Law wrote:
>> On 8/12/19 12:43 PM, Aldy Hernandez wrote:
>>> This is a fresh re-post of:
>>>
>>> https://gcc.gnu.org/ml/gcc-patches/2019-07/msg6.html
>>>
>>> Andrew gave me some feedback a week ago, and I obviously don't remember
>>> what it was because I was about to leave on PTO.  However, I do remember
>>> I addressed his concerns before getting drunk on rum in tropical islands.
>>>
>> FWIW found a great coffee infused rum while in Kauai last week.  I'm not
>> a coffee fan, but it was wonderful.  The one bottle we brought back
>> isn't going to last until Cauldron and I don't think I can get a special
>> order filled before I leave :(
> 
> You must bring some to Cauldron before we believe you. :)
That's the problem.  The nearest place I can get it is in Vegas and
there's no distributor in Montreal.   I can special order it in our
state run stores, but it won't be here in time.

Of course, I don't mind if you don't believe me.  More for me in that
case...


>> Is the supports_type_p stuff there to placate the calls from ipa-cp?  I
>> can live with it in the short term, but it really feels like there
>> should be something in the ipa-cp client that avoids this silliness.
> 
> I am not happy with this either, but there are various places where
> statements that are !stmt_interesting_for_vrp() are still setting a
> range of VARYING, which is then being ignored at a later time.
> 
> For example, vrp_initialize:
> 
>   if (!stmt_interesting_for_vrp (phi))
> {
>   tree lhs = PHI_RESULT (phi);
>   set_def_to_varying (lhs);
>   prop_set_simulate_again (phi, false);
> }
> 
> Also in evrp_range_analyzer::record_ranges_from_stmt(), where we if the
> statement is interesting for VRP but extract_range_from_stmt() does not
> produce a useful range, we also set a varying for a range we will never
> use.  Similarly for a statement that is not interesting in this hunk.
Ugh.  One could perhaps argue that setting any kind of range in these
circumstances is silly.   But I suspect it's necessary due to the
optimistic handling of VR_UNDEFINED in value_range_base::union_helper.
It's all coming back to me now...


> 
> Then there is vrp_prop::visit_stmt() where we also set VARYING for types
> that VRP will never handle:
> 
>   case IFN_ADD_OVERFLOW:
>   case IFN_SUB_OVERFLOW:
>   case IFN_MUL_OVERFLOW:
>   case IFN_ATOMIC_COMPARE_EXCHANGE:
> /* These internal calls return _Complex integer type,
>    which VRP does not track, but the immediate uses
>    thereof might be interesting.  */
> if (lhs && TREE_CODE (lhs) == SSA_NAME)
>   {
> imm_use_iterator iter;
> use_operand_p use_p;
> enum ssa_prop_result res = SSA_PROP_VARYING;
> 
> set_def_to_varying (lhs);
> 
> I've adjusted the patch so that set_def_to_varying will set the range to
> VR_UNDEFINED if !supports_type_p.  This is a fail safe, as we can't
> really do anything with a nonsensical range.  I just don't want to leave
> the range in an indeterminate state.
> 
I think VR_UNDEFINED is unsafe due to value_range_base::union_helper.
And that's a more general than this patch.  VR_UNDEFINED is _not_ a safe
range to set something to if we can't handle it.  We have to use VR_VARYING.

Why?  See the beginning of value_range_base::union_helper:

   /* VR0 has the resulting range if VR1 is undefined or VR0 is varying.  */
   if (vr1->undefined_p ()
   || vr0->varying_p ())
 return *vr0;

   /* VR1 has the resulting range if VR0 is undefined or VR1 is varying.  */
   if (vr0->undefined_p ()
   || vr1->varying_p ())
 return *vr1;
This can get called for something like

  a =  ? name1 : name2;

If name1 was set to VR_UNDEFINED thinking that VR_UNDEFINED was a safe
value for something we can't handle, then we'll incorrectly return the
range for name2.

VR_UNDEFINED can only be used for the ranges of objects we haven't
processed.  If we can't produce a range for an object because the
statement is something we don't handle or just doesn't produce anythign
useful, then the right result is VR_VARYING.

This may be worth commenting at the definition site for VR_*.

> 
> I also noticed that Andrew's patch was setting num_vr_values to
> num_ssa_names + num_ssa_names / 10.  I think he meant num_vr_values +
> num_vr_values / 10.  Please verify the current incantation makes sense.
Going to assume this will be adjusted per the other messages in this thread.


> diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
> index 39ea22f0554..663dd6e2398 100644
> --- a/gcc/tree-ssa-threadedge.c
> +++ b/gcc/tree-ssa-threadedge.c
> @@ -182,8 +182,10 @@ record_temporary_equivalences_from_phis (edge e,
>   new_vr->deep_copy (vr_values->get_value_range (src));
> else if (TREE_CODE (src) == INTEGER_CST)
>   new_vr->set (src);
> +   else if (value_range_base::supports_

Re: types for VR_VARYING

2019-08-14 Thread Jeff Law
On 8/14/19 8:15 AM, Aldy Hernandez wrote:
> 
> 
> On 8/14/19 9:50 AM, Andrew MacLeod wrote:
>> On 8/13/19 8:39 PM, Aldy Hernandez wrote:
>>>
>>>
>>> Yes, it was 2X.
>>>
>>> I noticed that Richi made some changes to the lattice handling for
>>> VARYING while the discussion was on-going.  I missed these, and had
>>> failed to adapt the patch for it.  I would appreciate a final review
>>> of the attached patch, especially the vr-values.c changes, which I
>>> have modified to play nice with current trunk.
>>>
>>> I also noticed that Andrew's patch was setting num_vr_values to
>>> num_ssa_names + num_ssa_names / 10.  I think he meant num_vr_values +
>>> num_vr_values / 10.  Please verify the current incantation makes sense.
>>>
>> no, I meant num_ssa_names.  We are resizing the vector because
>> num_vr_values is out of date (and smaller than num_ssa_names is now),
>> so we need to resize the vector to be at least the number of
>> ssa-names... and I added 10% just in case we arent done adding new ones.
>>
>>
>> if num_vr_values is 100, and we've added 200 ssa-names, num_ssa_names
>> would now be 300.   if you resize based on num_vr_values, you could
>> still go off the end of the vector.
> 
> OK, I've changed the resize to allocate 2X as well.  So now we'll have:
> 
> +  unsigned int old_sz = num_vr_values;
> +  num_vr_values = num_ssa_names * 2;
> +  vr_value = XRESIZEVEC (value_range *, vr_value, num_vr_values);
> etc
> 
> And the original allocation will also be 2X.
I don't think we want the resize to be 2X, we've tried to get away from
those kinds of growth patterns.  The 10% from Andrew's patch seems like
a better choice for the resize.

jeff


Re: types for VR_VARYING

2019-08-14 Thread Aldy Hernandez




On 8/14/19 9:50 AM, Andrew MacLeod wrote:

On 8/13/19 8:39 PM, Aldy Hernandez wrote:



Yes, it was 2X.

I noticed that Richi made some changes to the lattice handling for 
VARYING while the discussion was on-going.  I missed these, and had 
failed to adapt the patch for it.  I would appreciate a final review 
of the attached patch, especially the vr-values.c changes, which I 
have modified to play nice with current trunk.


I also noticed that Andrew's patch was setting num_vr_values to 
num_ssa_names + num_ssa_names / 10.  I think he meant num_vr_values + 
num_vr_values / 10.  Please verify the current incantation makes sense.


no, I meant num_ssa_names.  We are resizing the vector because 
num_vr_values is out of date (and smaller than num_ssa_names is now), so 
we need to resize the vector to be at least the number of ssa-names... 
and I added 10% just in case we arent done adding new ones.



if num_vr_values is 100, and we've added 200 ssa-names, num_ssa_names 
would now be 300.   if you resize based on num_vr_values, you could 
still go off the end of the vector.


OK, I've changed the resize to allocate 2X as well.  So now we'll have:

+  unsigned int old_sz = num_vr_values;
+  num_vr_values = num_ssa_names * 2;
+  vr_value = XRESIZEVEC (value_range *, vr_value, num_vr_values);
etc

And the original allocation will also be 2X.

Aldy


Re: types for VR_VARYING

2019-08-14 Thread Andrew MacLeod

On 8/13/19 8:39 PM, Aldy Hernandez wrote:



Yes, it was 2X.

I noticed that Richi made some changes to the lattice handling for 
VARYING while the discussion was on-going.  I missed these, and had 
failed to adapt the patch for it.  I would appreciate a final review 
of the attached patch, especially the vr-values.c changes, which I 
have modified to play nice with current trunk.


I also noticed that Andrew's patch was setting num_vr_values to 
num_ssa_names + num_ssa_names / 10.  I think he meant num_vr_values + 
num_vr_values / 10.  Please verify the current incantation makes sense.


no, I meant num_ssa_names.  We are resizing the vector because 
num_vr_values is out of date (and smaller than num_ssa_names is now), so 
we need to resize the vector to be at least the number of ssa-names... 
and I added 10% just in case we arent done adding new ones.



if num_vr_values is 100, and we've added 200 ssa-names, num_ssa_names 
would now be 300.   if you resize based on num_vr_values, you could 
still go off the end of the vector.



Andrew





Re: types for VR_VARYING

2019-08-13 Thread Aldy Hernandez



On 8/12/19 7:46 PM, Jeff Law wrote:

On 8/12/19 12:43 PM, Aldy Hernandez wrote:

This is a fresh re-post of:

https://gcc.gnu.org/ml/gcc-patches/2019-07/msg6.html

Andrew gave me some feedback a week ago, and I obviously don't remember
what it was because I was about to leave on PTO.  However, I do remember
I addressed his concerns before getting drunk on rum in tropical islands.

FWIW found a great coffee infused rum while in Kauai last week.  I'm not
a coffee fan, but it was wonderful.  The one bottle we brought back
isn't going to last until Cauldron and I don't think I can get a special
order filled before I leave :(


You must bring some to Cauldron before we believe you. :)



Their more traditional rums were good as well.  Koloa Rum.  See if you
can get it locally :-)




This patch adds MIN/MAX values for VR_VARYING.  As was discussed
earlier, we are only changing VR_VARYING, not VR_UNDEFINED as was the
original plan.

As I mentioned earlier, I am tired of re-doing ChangeLogs, so I'll whip
up the changelog when the review starts.

ACK.


ChangeLog entries included in attached patch.






@@ -150,12 +166,11 @@ vr_values::set_defs_to_varying (gimple *stmt)
ssa_op_iter i;
tree def;
FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
-{
-  value_range *vr = get_value_range (def);
-  /* Avoid writing to vr_const_varying get_value_range may return.  */
-  if (!vr->varying_p ())
-   vr->set_varying ();
-}
+if (value_range_base::supports_type_p (TREE_TYPE (def)))
+  {
+   value_range *vr = get_value_range (def);
+   vr->set_varying (TREE_TYPE (def));
+  }
  }

Is the supports_type_p stuff there to placate the calls from ipa-cp?  I
can live with it in the short term, but it really feels like there
should be something in the ipa-cp client that avoids this silliness.


I am not happy with this either, but there are various places where 
statements that are !stmt_interesting_for_vrp() are still setting a 
range of VARYING, which is then being ignored at a later time.


For example, vrp_initialize:

  if (!stmt_interesting_for_vrp (phi))
{
  tree lhs = PHI_RESULT (phi);
  set_def_to_varying (lhs);
  prop_set_simulate_again (phi, false);
}

Also in evrp_range_analyzer::record_ranges_from_stmt(), where we if the 
statement is interesting for VRP but extract_range_from_stmt() does not 
produce a useful range, we also set a varying for a range we will never 
use.  Similarly for a statement that is not interesting in this hunk.


Then there is vrp_prop::visit_stmt() where we also set VARYING for types 
that VRP will never handle:


  case IFN_ADD_OVERFLOW:
  case IFN_SUB_OVERFLOW:
  case IFN_MUL_OVERFLOW:
  case IFN_ATOMIC_COMPARE_EXCHANGE:
/* These internal calls return _Complex integer type,
   which VRP does not track, but the immediate uses
   thereof might be interesting.  */
if (lhs && TREE_CODE (lhs) == SSA_NAME)
  {
imm_use_iterator iter;
use_operand_p use_p;
enum ssa_prop_result res = SSA_PROP_VARYING;

set_def_to_varying (lhs);

I've adjusted the patch so that set_def_to_varying will set the range to 
VR_UNDEFINED if !supports_type_p.  This is a fail safe, as we can't 
really do anything with a nonsensical range.  I just don't want to leave 
the range in an indeterminate state.





  
  /* Update the value range and equivalence set for variable VAR to



@@ -1920,7 +1935,7 @@ vr_values::dump_all_value_ranges (FILE *file)
  vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges")
  {
values_propagated = false;
-  num_vr_values = num_ssa_names;
+  num_vr_values = num_ssa_names + num_ssa_names / 10;
vr_value = XCNEWVEC (value_range *, num_vr_values);
vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
bitmap_obstack_initialize (&vrp_equiv_obstack);

My recollection was someone (Richi) proposed 2X for the initial
allocation which should ensure that in all but the most pathological
cases that we never trigger a reallocation.  In terms of "wasted" space,
it shouldn't matter in practice.

So if you could check the old thread and verify that Richi recommended
the 2X initial allocation and if so, make that minor update.


Yes, it was 2X.

I noticed that Richi made some changes to the lattice handling for 
VARYING while the discussion was on-going.  I missed these, and had 
failed to adapt the patch for it.  I would appreciate a final review of 
the attached patch, especially the vr-values.c changes, which I have 
modified to play nice with current trunk.


I also noticed that Andrew's patch was setting num_vr_values to 
num_ssa_names + num_ssa_names / 10.  I think he meant num_vr_values + 
num_vr_values / 10.  Please verify the current incantation makes sense.


Tested on x86-64 Linux.

OK for trunk?

Aldy
commit 4c21b0f667176933f67469372da7459b8cf0e

Re: types for VR_VARYING

2019-08-12 Thread Jeff Law
On 8/12/19 12:43 PM, Aldy Hernandez wrote:
> This is a fresh re-post of:
> 
> https://gcc.gnu.org/ml/gcc-patches/2019-07/msg6.html
> 
> Andrew gave me some feedback a week ago, and I obviously don't remember
> what it was because I was about to leave on PTO.  However, I do remember
> I addressed his concerns before getting drunk on rum in tropical islands.
FWIW found a great coffee infused rum while in Kauai last week.  I'm not
a coffee fan, but it was wonderful.  The one bottle we brought back
isn't going to last until Cauldron and I don't think I can get a special
order filled before I leave :(

Their more traditional rums were good as well.  Koloa Rum.  See if you
can get it locally :-)


> 
> This patch adds MIN/MAX values for VR_VARYING.  As was discussed
> earlier, we are only changing VR_VARYING, not VR_UNDEFINED as was the
> original plan.
> 
> As I mentioned earlier, I am tired of re-doing ChangeLogs, so I'll whip
> up the changelog when the review starts.
ACK.



> @@ -150,12 +166,11 @@ vr_values::set_defs_to_varying (gimple *stmt)
>ssa_op_iter i;
>tree def;
>FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
> -{
> -  value_range *vr = get_value_range (def);
> -  /* Avoid writing to vr_const_varying get_value_range may return.  */
> -  if (!vr->varying_p ())
> - vr->set_varying ();
> -}
> +if (value_range_base::supports_type_p (TREE_TYPE (def)))
> +  {
> + value_range *vr = get_value_range (def);
> + vr->set_varying (TREE_TYPE (def));
> +  }
>  }
Is the supports_type_p stuff there to placate the calls from ipa-cp?  I
can live with it in the short term, but it really feels like there
should be something in the ipa-cp client that avoids this silliness.


>  
>  /* Update the value range and equivalence set for variable VAR to

> @@ -1920,7 +1935,7 @@ vr_values::dump_all_value_ranges (FILE *file)
>  vr_values::vr_values () : vrp_value_range_pool ("Tree VRP value ranges")
>  {
>values_propagated = false;
> -  num_vr_values = num_ssa_names;
> +  num_vr_values = num_ssa_names + num_ssa_names / 10;
>vr_value = XCNEWVEC (value_range *, num_vr_values);
>vr_phi_edge_counts = XCNEWVEC (int, num_ssa_names);
>bitmap_obstack_initialize (&vrp_equiv_obstack);
My recollection was someone (Richi) proposed 2X for the initial
allocation which should ensure that in all but the most pathological
cases that we never trigger a reallocation.  In terms of "wasted" space,
it shouldn't matter in practice.

So if you could check the old thread and verify that Richi recommended
the 2X initial allocation and if so, make that minor update.

Jeff





types for VR_VARYING

2019-08-12 Thread Aldy Hernandez

This is a fresh re-post of:

https://gcc.gnu.org/ml/gcc-patches/2019-07/msg6.html

Andrew gave me some feedback a week ago, and I obviously don't remember 
what it was because I was about to leave on PTO.  However, I do remember 
I addressed his concerns before getting drunk on rum in tropical islands.


This patch adds MIN/MAX values for VR_VARYING.  As was discussed 
earlier, we are only changing VR_VARYING, not VR_UNDEFINED as was the 
original plan.


As I mentioned earlier, I am tired of re-doing ChangeLogs, so I'll whip 
up the changelog when the review starts.


Tested on x86-64 Linux.

OK?

Aldy
commit dad943a48ff2fccc203bf11839b7e3016e44dfe1
Author: Aldy Hernandez 
Date:   Mon Jul 22 10:04:43 2019 +0200

Add type to VR_VARYING.

diff --git a/gcc/gimple-ssa-evrp-analyze.c b/gcc/gimple-ssa-evrp-analyze.c
index 4c68af847e1..0184703a13c 100644
--- a/gcc/gimple-ssa-evrp-analyze.c
+++ b/gcc/gimple-ssa-evrp-analyze.c
@@ -251,13 +251,18 @@ evrp_range_analyzer::record_ranges_from_phis (basic_block bb)
   if (virtual_operand_p (lhs))
 	continue;
 
+  /* Skips floats and other things we can't represent in a
+	 range.  */
+  if (!value_range_base::supports_type_p (TREE_TYPE (lhs)))
+	continue;
+
   value_range vr_result;
   bool interesting = stmt_interesting_for_vrp (phi);
   if (!has_unvisited_preds && interesting)
 	vr_values->extract_range_from_phi_node (phi, &vr_result);
   else
 	{
-	  vr_result.set_varying ();
+	  vr_result.set_varying (TREE_TYPE (lhs));
 	  /* When we have an unvisited executable predecessor we can't
 	 use PHI arg ranges which may be still UNDEFINED but have
 	 to use VARYING for them.  But we can still resort to
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 69c00a9c5a5..859ad3fbaf5 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -977,7 +977,12 @@ ipcp_vr_lattice::set_to_bottom ()
 {
   if (m_vr.varying_p ())
 return false;
-  m_vr.set_varying ();
+  /* ?? We create all sorts of VARYING ranges for floats, structures,
+ and other types which we cannot handle as ranges.  We should
+ probably avoid handling them throughout the pass, but it's easier
+ to create a sensible VARYING here and let the lattice
+ propagate.  */
+  m_vr.set_varying (integer_type_node);
   return true;
 }
 
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 785227df690..43bca63da09 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -182,8 +182,10 @@ record_temporary_equivalences_from_phis (edge e,
 	new_vr->deep_copy (vr_values->get_value_range (src));
 	  else if (TREE_CODE (src) == INTEGER_CST)
 	new_vr->set (src);
+	  else if (value_range_base::supports_type_p (TREE_TYPE (src)))
+	new_vr->set_varying (TREE_TYPE (src));
 	  else
-	new_vr->set_varying ();
+	new_vr->set_undefined ();
 
 	  /* This is a temporary range for DST, so push it.  */
 	  evrp_range_analyzer->push_value_range (dst, new_vr);
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 8b80bce8945..3911db9c26e 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -440,14 +440,16 @@ get_range_info (const_tree name, value_range_base &vr)
   wide_int wmin, wmax;
   enum value_range_kind kind = get_range_info (name, &wmin, &wmax);
 
-  if (kind == VR_VARYING || kind == VR_UNDEFINED)
-min = max = NULL;
+  if (kind == VR_VARYING)
+vr.set_varying (TREE_TYPE (name));
+  else if (kind == VR_UNDEFINED)
+vr.set_undefined ();
   else
 {
   min = wide_int_to_tree (TREE_TYPE (name), wmin);
   max = wide_int_to_tree (TREE_TYPE (name), wmax);
+  vr.set (kind, min, max);
 }
-  vr.set (kind, min, max);
   return kind;
 }
 
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index de2f39d8487..e215b032f78 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -186,9 +186,11 @@ value_range_base::check ()
 	break;
   }
 case VR_UNDEFINED:
-case VR_VARYING:
   gcc_assert (!min () && !max ());
   break;
+case VR_VARYING:
+  gcc_assert (m_min && m_max);
+  break;
 default:
   gcc_unreachable ();
 }
@@ -214,6 +216,10 @@ value_range::check ()
 bool
 value_range_base::equal_p (const value_range_base &other) const
 {
+  /* Ignore types for undefined.  All undefines are equal.  */
+  if (undefined_p ())
+return m_kind == other.m_kind;
+
   return (m_kind == other.m_kind
 	  && vrp_operand_equal_p (m_min, other.m_min)
 	  && vrp_operand_equal_p (m_max, other.m_max));
@@ -269,16 +275,19 @@ value_range::set_undefined ()
 }
 
 void
-value_range_base::set_varying ()
+value_range_base::set_varying (tree type)
 {
+  gcc_assert (supports_type_p (type));
   m_kind = VR_VARYING;
-  m_min = m_max = NULL;
+  m_min = vrp_val_min (type, true);
+  m_max = vrp_val_max (type, true);
 }
 
 void
-value_range::set_varying ()
+value_range::set_varying (tree type)
 {
-  set (VR_VARYING, NULL, NULL, NULL);
+  value_range_base::set_varying (type);
+  equiv_clear ();
 }
 
 /* Return TRUE