Re: [x86 testsuite] preserve full register across main

2019-08-24 Thread Uros Bizjak
On Friday, August 23, 2019, Alexandre Oliva  wrote:
> This test uses a call-saved register as a global variable.  It
> attempts to preserve its value across main, but only the lower int
> part is preserved, which is not good enough for x86_64, when the
> runtime that calls main() happens to hold something in the chosen
> register that is not a zero-extension from the 32-bit value, and
> rightfully expects the full register to remain unchanged when main()
> returns.
>
> Tested on x86_64-linux-gnu, both -m64 and -m32.  Ok to install?
>
>
> for  gcc/testsuite/ChangeLog
>
> * gcc.target/i386/20020616-1.c: Preserve full register across
> main.
> ---
>  gcc/testsuite/gcc.target/i386/20020616-1.c |   14 +-
>  1 file changed, 9 insertions(+), 5 deletions(-)
>
> diff --git a/gcc/testsuite/gcc.target/i386/20020616-1.c
b/gcc/testsuite/gcc.target/i386/20020616-1.c
> index 5641826b4837..3b8cf8e41783 100644
> --- a/gcc/testsuite/gcc.target/i386/20020616-1.c
> +++ b/gcc/testsuite/gcc.target/i386/20020616-1.c
> @@ -2,12 +2,16 @@
>  /* { dg-do run } */
>  /* { dg-options "-O2" } */
>
> +/* We need this type to be as wide as the register chosen below, so
> +   that, when we preserve it across main, we preserve all of it.  */
> +typedef long reg_type;

Can __attribute__ ((mode (__word__))) be used here?

Otherwise OK.

Thanks,
Uros.

>  #if !__PIC__
> -register int k asm("%ebx");
> +register reg_type k asm("%ebx");
>  #elif __amd64
> -register int k asm("%r12");
> +register reg_type k asm("%r12");
>  #else
> -register int k asm("%esi");
> +register reg_type k asm("%esi");
>  #endif
>
>  void __attribute__((noinline))
> @@ -18,7 +22,7 @@ foo()
>
>  void test()
>  {
> -  int i;
> +  reg_type i;
>for (i = 0; i < 10; i += k)
>  {
>k = 0;
> @@ -28,7 +32,7 @@ void test()
>
>  int main()
>  {
> -  int old = k;
> +  reg_type old = k;
>test();
>k = old;
>return 0;
>
> --
> Alexandre Oliva, freedom fighter  he/him   https://FSFLA.org/blogs/lxo
> Be the change, be Free! FSF Latin America board member
> GNU Toolchain EngineerFree Software Evangelist
> Hay que enGNUrecerse, pero sin perder la terGNUra jamás - Che GNUevara
>


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: [PATCH v6 3/3] PR80791 Consider doloop cmp use in ivopts

2019-08-24 Thread Kewen.Lin
Hi Bin,

on 2019/8/23 下午5:43, Bin.Cheng wrote:
> On Fri, Aug 23, 2019 at 4:27 PM Kewen.Lin  wrote:
>>
>> Hi Bin
>>
>> on 2019/8/23 上午10:19, Bin.Cheng wrote:
>>> On Thu, Aug 22, 2019 at 3:09 PM Kewen.Lin  wrote:

 Hi Bin,

 on 2019/8/22 下午1:46, Bin.Cheng wrote:
> On Thu, Aug 22, 2019 at 11:18 AM Kewen.Lin  wrote:
>>
>> Hi Bin,
>>
>> Thanks for your time!
>>
>> on 2019/8/21 下午8:32, Bin.Cheng wrote:
>>> On Wed, Aug 14, 2019 at 3:23 PM Kewen.Lin  wrote:

 Hi!

 Comparing to the previous versions of implementation mainly based on 
 the
 existing IV cands but zeroing the related group/use cost, this new one 
 is based
 on Richard and Segher's suggestion introducing one doloop dedicated IV 
 cand.

 Some key points are listed below:
   1) New field doloop_p in struct iv_cand to indicate doloop dedicated 
 IV cand.
   2) Special name "doloop" assigned.
   3) Doloop IV cand with form (niter+1, +, -1)
   4) For doloop IV cand, no extra one cost like BIV, assign zero cost 
 for step.
   5) Support may_be_zero (regressed PR is in this case), the base of 
 doloop IV
  can be COND_EXPR, add handlings in cand_value_at and 
 may_eliminate_iv.
   6) Add more expr support in force_expr_to_var_cost for reasonable 
 cost
  calculation on the IV base with may_be_zero (like COND_EXPR).
   7) Set zero cost when using doloop IV cand for doloop use.
   8) Add three hooks (should we merge _generic and _address?).
 *) have_count_reg_decr_p, is to indicate the target has special 
 hardware
count register, we shouldn't consider the impact of doloop IV 
 when
calculating register pressures.
 *) doloop_cost_for_generic, is the extra cost when using doloop IV 
 cand for
generic type IV use.
 *) doloop_cost_for_address, is the extra cost when using doloop IV 
 cand for
address type IV use.
>>
 The new patch addressing the comments is attached.
 Could you please have a look again?  Thanks in advance!
>>> Thanks for working on this.  A bit more nit-pickings.
>>>
>>> -add_candidate_1 (data, base, step, important,
>>> -IP_NORMAL, use, NULL, orig_iv);
>>> -  if (ip_end_pos (data->current_loop)
>>> +add_candidate_1 (data, base, step, important, IP_NORMAL, use, NULL, 
>>> doloop,
>>> +orig_iv);
>>> +  if (!doloop && ip_end_pos (data->current_loop)
>>> Could you add some comments elaborating why ip_end_pos candidate
>>> shouldn't be added for doloop case?  Because the increment position is
>>> wrong.
>>>
>>> Also if you make doloop the last default parameter of add_candidate_1,
>>> you can save more unnecessary changes to calls to add_candidate?
>>>
>>> -cost = get_computation_cost (data, use, cand, false,
>>> -&inv_vars, NULL, &inv_expr);
>>> +{
>>> +  cost = get_computation_cost (data, use, cand, false, &inv_vars, NULL,
>>> +  &inv_expr);
>>> +  if (cand->doloop_p)
>>> +   cost += targetm.doloop_cost_for_generic;
>>> +}
>>> This adjustment
>>>
>>>cost = get_computation_cost (data, use, cand, true,
>>>&inv_vars, &can_autoinc, &inv_expr);
>>>
>>> +  if (cand->doloop_p)
>>> +cost += targetm.doloop_cost_for_address;
>>> +
>>> and this adjustment can be moved into get_computation_cost where all
>>> cost adjustments are done.
>>>
>>> +  /* For doloop candidate/use pair, adjust to zero cost.  */
>>> +  if (group->doloop_p && cand->doloop_p)
>>> +   cost = no_cost;
>>> Note above code handles comparing against zero case and decreases the
>>> cost by one (which prefers the same kind candidate as doloop one),
>>> it's very possible to have -1 cost for doloop cand here.  how about
>>> just set to no_cost if it's positive?  Your call.
>>>
>>> +/* For the targets which support doloop, to predict whether later RTL 
>>> doloop
>>> +   transformation will perform on this loop, further detect the doloop use 
>>> and
>>> +   mark the flag doloop_use_p if predicted.  */
>>> +
>>> +void
>>> +predict_and_process_doloop (struct ivopts_data *data)
>>> A better name here? Sorry I don't have another candidate in mind...
>>>
>>> +  data->doloop_use_p = false;
>>> This can be moved to the beginning of above
>>> 'predict_and_process_doloop' function.
>>>
>>> Lastly, could you please add some brief description/comment about
>>> doloop handling as a subsection in the file head comment?
>>>
>>> Otherwise, the ivopt changes look good to me.
>>>
>>> Thanks,
>>> bin
>>>
>>
>> Thanks for your prompt reply!  I've updated the code as your comments,
>> the updated version is attached.  Looking forward

Re: [patch, fortran] Fix PR 91390 - treatment of extra parameter in a subroutine call

2019-08-24 Thread Steve Kargl
On Tue, Aug 20, 2019 at 10:32:37PM +0200, Thomas König wrote:
> 
> 2019-08-20  Thomas Koenig  
> 
>   PR fortran/91390
>   * frontend-passes.c (check_externals_procedure): New
>   function. If a procedure is not in the translation unit, create
>   an "interface" for it, including its formal arguments.
>   (check_externals_code): Use check_externals_procedure for common
>   code with check_externals_expr.
>   (check_externals_expr): Vice versa.
>   * gfortran.h (gfc_get_formal_from_actual-arglist): New prototype.
>   (gfc_compare_actual_formal): New prototype.
>   * interface.c (compare_actual_formal): Rename to
>   (gfc_compare_actual_forma): New function, make global.

spelling. forma -> formal

> 
> 2019-08-20  Thomas Koenig  
> 
>   PR fortran/91390
>   * gfortran.dg/bessel_3.f90: Add type mismatch errors.
>   * gfortran.dg/coarray_7.f90: Rename subroutines to avoid
>   additional errors.
>   * gfortran.dg/g77/20010519-1.f: Add -std=legacy. Remove
>   warnings for ASSIGN. Add warnings for type mismatch.
>   * gfortran.dg/goacc/acc_on_device-1.f95: Add -std=legacy.
>   Add cath-all warning.

spelling. cath -> catch


OK.  Thanks for taking on this task.

As to the open question about how to handle this check,
I would create -fallow-argument-mismatch (or whatever
option name you like).  gfortran issues an error if
a mismatch is detected.  -fallow-... would reduce the
error to warning, which can only be silenced with -w.
Hopefully, this will encourage users to fix the code.

-- 
steve


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: [patch, fortran] Fix PR 91390 - treatment of extra parameter in a subroutine call

2019-08-24 Thread Thomas König

Hi Steve,


OK.  Thanks for taking on this task.


Committed (r274902). Thanks for the review!


As to the open question about how to handle this check,
I would create -fallow-argument-mismatch (or whatever
option name you like).  gfortran issues an error if
a mismatch is detected.  -fallow-... would reduce the
error to warning, which can only be silenced with -w.
Hopefully, this will encourage users to fix the code.


Yes, that is what I will submit next.  -fallow-argument-mismatch
sounds like a good name, unless somebody else comes up with a
better name.

Regards

Thomas


Re: [C++ PATCH] vfunc overrider simplification

2019-08-24 Thread Nathan Sidwell

On 8/23/19 3:24 PM, Nathan Sidwell wrote:
In fixing a vfunc override bug on the modules branch, I noticed that 
check_for_override can simply check IDENTIFIER_VIRTUAL_P -- the dtor 
identifier and those for conversion operators will have it set 
correctly.  (there a multiple conversion operator identifiers, but we 
can only be overriding the one with the same return type, so that's fine.)


that turns out to be untrue -- the conversion operator table 
distinguishes between different typedefs of the same type.  This patch 
restores the DECL_CONV_FN_P test.


Applying to trunk.

nathan

--
Nathan Sidwell
2019-08-24  Nathan Sidwell  

	cp/
	* class.c (check_for_overrides): Conversion operators need
	checking too.

	testsuite/
	* g++.dg/inherit/virtual14.C: New.

Index: cp/class.c
===
--- cp/class.c	(revision 274902)
+++ cp/class.c	(working copy)
@@ -2817,10 +2817,12 @@ check_for_override (tree decl, tree ctyp
 return;
 
   /* IDENTIFIER_VIRTUAL_P indicates whether the name has ever been
- used for a vfunc.  That avoids the expensive
- look_for_overrides call that when we know there's nothing to
- find.  */
-  if (IDENTIFIER_VIRTUAL_P (DECL_NAME (decl))
+ used for a vfunc.  That avoids the expensive look_for_overrides
+ call that when we know there's nothing to find.  As conversion
+ operators for the same type can have distinct identifiers, we
+ cannot optimize those in that way.  */
+  if ((IDENTIFIER_VIRTUAL_P (DECL_NAME (decl))
+   || DECL_CONV_FN_P (decl))
   && look_for_overrides (ctype, decl)
   /* Check staticness after we've checked if we 'override'.  */
   && !DECL_STATIC_FUNCTION_P (decl))
Index: testsuite/g++.dg/inherit/virtual14.C
===
--- testsuite/g++.dg/inherit/virtual14.C	(nonexistent)
+++ testsuite/g++.dg/inherit/virtual14.C	(working copy)
@@ -0,0 +1,24 @@
+// { dg-do run }
+
+struct base 
+{
+  virtual operator int () { return 0;}
+};
+
+typedef int q;
+
+struct d : base
+{
+  operator q () { return 1; }
+};
+
+int invoke (base *d)
+{
+  return int (*d);
+}
+
+int main ()
+{
+  d d;
+  return !(invoke (&d) == 1);
+}