Re: [PATCH 2/4] - relax strlen range optimization to avoid making assumptions about types

2018-10-10 Thread Martin Sebor

On 10/10/2018 03:18 PM, Jeff Law wrote:

On 10/2/18 10:37 AM, Martin Sebor wrote:

[2/4] - Relax strlen range optimization to avoid making assumptions
about types

This main part of this patch is to relax the strlen range
optimization to avoid relying on array types.  Instead, the function
either removes the upper bound of the strlen result altogether, or
constrains it by the size of referenced declaration (without
attempting to deal with common symbols).

A seemingly "big" change here is splitting up the static
get_range_strlen workhorse into two functions to make it easier
to follow.  The attached cc-9-2-gimple-fold.c.diff-b shows
the diff for the file without considering whitespace changes.

An important change to the get_range_strlen function worth calling
out to is the introduction of the tight_bound local variable.
It controls whether the upper bound computed by the function is
suitable for optimization (the larger value) or warnings
(the smaller value).

Another important change here is replacing the type and fuzzy
arguments to get_range_strlen with a single enum.  The two arguments
were confusing and with all combinations of their possible values
being meaningful.  The original extern get_range_strlen overload
with the type and fuzzy arguments is retained in this patch to
keep the changes contained.  It is removed in [4/4].

Finally, a large number of tests needed adjusting here.  I also
added a few new tests to better exercise the changes.


gcc-9-2.diff

[2/4] - Relax strlen range optimization to avoid making assumptions about types

gcc/ChangeLog:

* calls.c (maybe_warn_nonstring_arg): Test for -1.
* gimple-fold.c (get_range_strlen): Forward declare static.
(get_range_strlen_tree): New helper.
(get_range_strlen): Move tree code into get_range_strlen_tree.
Replace type and fuzzy arguments with a single enum.
Avoid optimizing ranges based on type, optimize on decl size intead.
(get_range_strlen): New extern overload.
(get_range_strlen): Use new overload above.
(get_maxval_strlen): Declared static.  Assert preconditions.
Use new overload above.
(gimple_fold_builtin_strcpy): Adjust to pass enum.
(gimple_fold_builtin_strncpy): Same.
(gimple_fold_builtin_strcat): Same.
(gimple_fold_builtin_fputs): Same.
(gimple_fold_builtin_memory_chk): Same.
(gimple_fold_builtin_stxcpy_chk): Same.
(gimple_fold_builtin_stxncpy_chk): Same.
(gimple_fold_builtin_snprintf_chk): Same.
(gimple_fold_builtin_sprintf): Same.
(gimple_fold_builtin_snprintf): Same.
(gimple_fold_builtin_strlen): Simplify.  Call set_strlen_range.
* gimple-fold.h (StrlenType): New enum.
(get_maxval_strlen): Remove.
(get_range_strlen): Change default argument value to true (strict).
* tree-ssa-strlen.c (set_strlen_range): New function.
(maybe_set_strlen_range): Call it.  Make static.
(maybe_diag_stxncpy_trunc): Use new get_range_strlen overload.
Adjust.
* tree-ssa-strlen.h (set_strlen_range): Declare.

gcc/testsuite/ChangeLog:

* g++.dg/init/strlen.C: New test.
* gcc.c-torture/execute/strlen-5.c: New test.
* gcc.c-torture/execute/strlen-6.c: New test.
* gcc.c-torture/execute/strlen-7.c: New test.
* gcc.dg/strlenopt-36.c: Remove tests for an overly aggressive
optimization.
* gcc.dg/strlenopt-40.c: Adjust tests to reflect a relaxed
optimization, remove others for an overly aggressive optimization.
* gcc.dg/strlenopt-45.c: Same.
* gcc.dg/strlenopt-48.c: Adjust tests to reflect a relaxed
optimization.
* gcc.dg/strlenopt-51.c: Same.
* gcc.dg/strlenopt-59.c: New test.

So from a review standpoint, a distinct patch that splits up the
function, but makes no behavioral changes would help.  That can be gated
in quickly and it reduces the amount of noise one has to sort through in
the changes that affect behavior.  Though the git diff ignoring
whitespace definitely helped.


The part with no behavioral changes is patch 1/4.  This part is
meant to relax the optimization.  The other changes like adding
the enum are meant to help make the code readable.



Camelcase is verboten.  Please don't use it (StrlenType and its
associated enumeration values).   Make the enumeration type lower case
and make the enumeration values all caps.  That's standard practice.

Was this tested independently?  I applied patch #1 and this to my tree,
and I get a bunch of regressions.

builtin-snprintf-warn-?.c
builtin-sprintf-warn-?.c
pr79376.c

In all there's ~75 regressions with this patch.


I tested each patch individually but overlooked some regressions
among all the intermittent failures.  Ultimately, it only makes
sense to me to either apply the whole series or nothing.  I don't
think there are "nuggets" in there that could be 

Re: introduce --enable-mingw-full32 to default to --large-address-aware

2018-10-10 Thread NightStrike
On Wed, Oct 10, 2018 at 7:37 PM JonY <10wa...@gmail.com> wrote:
>
> On 10/10/2018 04:58 AM, Alexandre Oliva wrote:
> > On Oct 10, 2018, JonY <10wa...@gmail.com> wrote:
> >
> >> On 10/10/2018 03:24 AM, Alexandre Oliva wrote:
> >>> On Oct  9, 2018, JonY <10wa...@gmail.com> wrote:
> >
> >>> Now, if you wish it to affect Cygwin as well, I could implement that,
> >>> and drop -mingw from the option name.  I'd retain the current defaults
> >>> of each target, unless there's a strong reason to change them.
> >
> >> In that case, no objections then.
> >
> > Thanks.  Now, before I proceed, please clarify: did you mean you had no
> > objections to the patch I last proposed, or to the plan in my last
> > paragraph above?
> >
>
> Your last proposed plan to use --enable-mingw-large-address-aware to
> affect only mingw. If there are more targets in the future that need
> this, we can always drop the mingw part in the configure option.

Except that options typically don't get removed, just deprecated.  It
seems cleaner to me to drop mingw from the name and make it default to
enabled for cygwin.


[PATCH] add simple attribute introspection

2018-10-10 Thread Martin Sebor

While writing tests for fixes and enhancements for attribute
handling I keep finding myself coming up with the same boiler-
plate code to verify whether an attribute has or has not been
successfully applied.  It's often error-prone because it
depends on the subtle and unique effects each attribute has
on optimizers or code generation in general.

Implementing an API just for testing might perhaps be excessive
but I suspect that users would find use for such a feature too.
I can even envision wanting to selectively apply attributes to
one's own symbols depending on their presence or absence on
other symbols (as an extension to the patch I posted for pr81824
that introduces the copy attribute to copy attributes from one
symbol to another).

The attached patch introduces a built-in function called
__builtin_has_attribute that makes some of this possible.
See the documentation and tests for details.

The C++ implementation is only tested using the C tests and
I'm pretty sure it doesn't do the right thing for templates
but I think it can be extended to do that in a followup patch
or an update to this one.

The C tests don't exhaustively exercise all attributes so it's
quite possible there are gaps/bugs where the built-in doesn't
return the right value due to missing special handling.
Attribute format validation is nearly non-existent.  I view
these shortcomings as minor and they too can be plugged in
a followup patch.

Ultimately, if this is viewed as useful as I'm hoping it will
be, I'd like to move the special handling from has_attribute
and to a callback function pointed from attribute_spec.  That
way each attribute, front-end and back-end alike, could, in
addition the attribute handler, implement its own special
query routine without the details leaking into the rest of
the compiler.

Martin
gcc/c/ChangeLog:

	* c-parser.c (c_parser_has_attribute_expression): New function.
	(c_parser_attribute): New function.
	(c_parser_attributes): Move code into c_parser_attribute.
	(c_parser_unary_expression): Handle RID_HAS_ATTRIBUTE_EXPRESSION.

gcc/c-family/ChangeLog:

	* c-attribs.c (validate_attribute, has_attribute): New functions.
	* c-common.h (has_attribute): Declare.
	* c-common.c (c_common_resword): Add RID_HAS_ATTRIBUTE_EXPRESSION.
	* c-common.h (rid): Same.

gcc/cp/ChangeLog:

	* cp-tree.h (cp_check_const_attributes): Declare.
	* decl2.c (cp_check_const_attributes): Declare extern.
	* parser.c (cp_parser_has_attribute_expression): New function.
	(cp_parser_unary_expression): Handle RID_HAS_ATTRIBUTE_EXPRESSION.
	(cp_parser_gnu_attribute_list): Add argument.

gcc/ChangeLog:

	* doc/extend.texi (Other Builtins): Add __builtin_has_attribute.

gcc/testsuite/ChangeLog:

	* c-c++-common/builtin-has-attribute-2.c: New test.
	* c-c++-common/builtin-has-attribute-3.c: New test.
	* c-c++-common/builtin-has-attribute.c: New test.
	* gcc.dg/builtin-has-attribute.c: New test.
diff --git a/gcc/c-family/c-attribs.c b/gcc/c-family/c-attribs.c
index 3a88766..56967fa 100644
--- a/gcc/c-family/c-attribs.c
+++ b/gcc/c-family/c-attribs.c
@@ -3678,3 +3678,220 @@ handle_patchable_function_entry_attribute (tree *, tree, tree, int, bool *)
   /* Nothing to be done here.  */
   return NULL_TREE;
 }
+
+/* Attempt to partially validate a single attribute ATTR if it were
+   to be applied to an entity OPER.  */
+
+static bool
+validate_attribute (location_t atloc, tree oper, tree attr)
+{
+  /* Determine whether the name of the attribute is valid
+ and fail with an error if not.  */
+  tree atname = get_attribute_name (attr);
+  if (!lookup_attribute_spec (atname))
+{
+  if (atloc != UNKNOWN_LOCATION)
+	error_at (atloc, "unknown attribute %qE", atname);
+  return false;
+}
+
+  if (!TREE_VALUE (attr))
+return true;
+
+  /* FIXME: Do some validation.  */
+  if (!strcmp (IDENTIFIER_POINTER (atname), "format"))
+return true;
+
+  /* Only when attribute arguments have been provided try to validate
+ the whole thing.  decl_attributes doesn't return an indication of
+ success or failure so proceed regardless.  */
+  const char tmpname[] = "__builtin_has_attribute_tmp.";
+  tree tmpid = get_identifier (tmpname);
+  tree tmpdecl;
+  if (TYPE_P (oper))
+tmpdecl = build_decl (atloc, TYPE_DECL,
+			  tmpid, oper);
+  else
+tmpdecl = build_decl (atloc, TREE_CODE (oper),
+			  tmpid, TREE_TYPE (oper));
+
+  /* Temporarily clear CURRENT_FUNCTION_DECL to make decl_attributes
+ believe the DECL declared above is at file scope.  (See bug 87526.)  */
+  tree save_curfunc = current_function_decl;
+  current_function_decl = NULL_TREE;
+  if (DECL_P (tmpdecl))
+{
+  if (DECL_P (oper))
+	DECL_EXTERNAL (tmpdecl) = DECL_EXTERNAL (oper);
+  TREE_PUBLIC (tmpdecl) = TREE_PUBLIC (oper);
+}
+  decl_attributes (, attr, 0);
+  current_function_decl = save_curfunc;
+
+  /* FIXME: Change decl_attributes to indicate success or failure.  */
+  return true;
+}
+
+/* Return true if the DECL, EXPR, or TYPE t 

Re: [PATCH 2/2 v3][IRA,LRA] Fix PR86939, IRA incorrectly creates an interference between a pseudo register and a hard register

2018-10-10 Thread Peter Bergner
On 10/8/18 9:52 AM, Jeff Law wrote:
> My tester is showing a variety of problems as well.  hppa, sh4, aarch64,
> aarch64_be, alpha arm* and s390x bootstraps are all failing at various
> points.   Others may trickle in over time, but clearly something went
> wrong recently.  I'm going to start trying to pick them off after the
> morning meetings are wrapped up.

Hi Vlad and Jeff,

I looked into the PA-RISC test case issue Jeff sent me that is caused by my
patch that handles conflicts wrt reg copies and I _think_ I have a handle
on what the problem is, but don't yet know how to fix.  Jeff, I agree with
the analysis you gave in your email to me, but to get Vlad up to speed, here
it is again along with some additional info.

Compiling the test case, we have the following RTL during IRA.  I have also
annotated the pseudos in the RTL to include their hard reg assignment:

(insn 30 19 32 3 (set (reg/f:SI 112 "%r19") ))
(insn 32 30 20 3 (set (reg:SI 26 %r26)
  (reg/f:SI 101 "%r26")))
[snip]
(insn 23 22 49 3 (set (reg:SI 109 "%r28")
 (mem:SI (reg/f:SI 101 "%r26"
(insn 49 23 31 3 (set (reg/f:SI 100 "%r28")
(if_then_else:SI (eq (reg:SI 109 "%r28") (const_int 15 [0xf]))
(reg/f:SI 101 "%r26")
(const_int 0 [0])))
 (expr_list:REG_DEAD (reg:SI 109 "%r28")
(expr_list:REG_DEAD (reg/f:SI 101 "%r26"
(insn 31 49 33 3 (set (mem/f:SI (reg/f:SI 112 "%r19"))
  (reg/f:SI 100 "%r28"))
 (expr_list:REG_DEAD (reg/f:SI 112 "%r19")
(expr_list:REG_DEAD (reg/f:SI 100 "%r28"
(call_insn 33 31 36 3 (parallel [
(call (mem:SI (symbol_ref/v:SI ("@_Z3yowP11dw_cfi_node"))
(const_int 16 [0x10]))
(clobber (reg:SI 1 %r1))
(clobber (reg:SI 2 %r2))
(use (const_int 0 [0]))])
 (expr_list:REG_DEAD (reg:SI 26 %r26))
(expr_list:SI (use (reg:SI 26 %r26)

Before my patch, hard reg %r26 and pseudo 101 conflicted, but with my patch
they now (correctly) do not.  IRA is able to assign hard regs to all of the
pseudos, but the constraints in the pattern for insn 49 forces op0 (pseudo 100)
and op1 (pseudo 101) to have the same hard reg.  They are not, so LRA comes
along and spills insn 49 with the following reloads:

Reloads for insn # 49
Reload 0: reload_in (SI) = (reg/f:SI 26 %r26 [orig:101 _10 ] [101])
  reload_out (SI) = (reg/f:SI 28 %r28 [orig:100 iftmp.2_5 ] [100])
  GENERAL_REGS, RELOAD_OTHER (opnum = 0)
  reload_in_reg: (reg/f:SI 26 %r26 [orig:101 _10 ] [101])
  reload_out_reg: (reg/f:SI 28 %r28 [orig:100 iftmp.2_5 ] [100])
  reload_reg_rtx: (reg/f:SI 26 %r26 [orig:101 _10 ] [101])

..giving us the following updated insn:

(insn 49 23 58 3 (set (reg/f:SI 26 %r26 [101])
(if_then_else:SI (eq (reg:SI 28 %r28 [109])
(const_int 15))
(reg/f:SI 26 %r26 [101])
(const_int 0 [0]

The problem is, that hard reg %r26 is defined in insn 32, to be used in
insn 33, so using %r26 as the reload reg is wrong, because it will clobber
the value we set in insn 32.  Looking thru LRA, it looks like LRA assumes
that for a reload, if one of the input pseudos dies in the insn, then the
hard reg it was assigned to is available to use.  That assumption is (now)
wrong, because another pseudo may be using that hard reg or in this case,
the hard reg itself is still live.

For this example, pseudo 109 also dies in insn 49 and since it's hard reg
%r28 isn't live thru the insn, we could have used that instead.  However,
we cannot just look at REG_DEAD notes for free hard regs to use for reload
regs.  We need to make sure that that hard reg isn't also assigned to another
pseudo that is live at that insn or even that the hard reg itself is live.

Vlad, you know the LRA code better than anyone.  Will it be easy to find
all the places where we create reload regs and fix them up so that we
look at more than just REG_DEAD notes?  Even though looking at REG_DEAD
notes isn't enough, I still think the majority of the time those regs
probably will be free to use, we just have to check for the special
cases like above where they are not.

Peter




Re: [C++ PATCH] Fix up bitfield handling in typeid (PR c++/87547)

2018-10-10 Thread Jason Merrill
OK.
On Wed, Oct 10, 2018 at 5:17 AM Jakub Jelinek  wrote:
>
> Hi!
>
> typeid of an expression that is a bitfield right now returns various weird
> results, depending on what exact type ignoring precision we choose for the
> bitfield.  Haven't found exact wording in the standard that would back this
> out though.  clang++ agrees with the patched g++ though.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2018-10-10  Jakub Jelinek  
>
> PR c++/87547
> * rtti.c (get_tinfo_decl_dynamic): Use unlowered_expr_type instead
> of TREE_TYPE.
>
> * g++.dg/rtti/typeid12.C: New test.
>
> --- gcc/cp/rtti.c.jj2018-08-27 17:50:43.782489578 +0200
> +++ gcc/cp/rtti.c   2018-10-09 10:52:42.348604424 +0200
> @@ -273,7 +273,7 @@ get_tinfo_decl_dynamic (tree exp, tsubst
>exp = resolve_nondeduced_context (exp, complain);
>
>/* peel back references, so they match.  */
> -  type = non_reference (TREE_TYPE (exp));
> +  type = non_reference (unlowered_expr_type (exp));
>
>/* Peel off cv qualifiers.  */
>type = TYPE_MAIN_VARIANT (type);
> --- gcc/testsuite/g++.dg/rtti/typeid12.C.jj 2018-10-09 10:42:19.580094220 
> +0200
> +++ gcc/testsuite/g++.dg/rtti/typeid12.C2018-10-09 10:42:04.105354872 
> +0200
> @@ -0,0 +1,16 @@
> +// PR c++/87547
> +// { dg-do run }
> +
> +#include 
> +
> +struct S { unsigned int a : 4; unsigned int b : 12; int c; unsigned long d : 
> 8; } s;
> +
> +int
> +main ()
> +{
> +  if (typeid (s.a) != typeid (unsigned int)
> +  || typeid (s.b) != typeid (unsigned int)
> +  || typeid (s.c) != typeid (int)
> +  || typeid (s.d) != typeid (unsigned long))
> +__builtin_abort ();
> +}
>
> Jakub


Re: [C++ PATCH] Fix up __has_cpp_attribute (no_unique_address)

2018-10-10 Thread Jason Merrill
OK, thanks.
On Wed, Oct 10, 2018 at 10:02 AM Jakub Jelinek  wrote:
>
> On Wed, Oct 03, 2018 at 06:05:43PM +0200, Jakub Jelinek wrote:
> > On Wed, Oct 03, 2018 at 11:56:15AM -0400, Jason Merrill wrote:
> > > --- a/gcc/c-family/c-lex.c
> > > +++ b/gcc/c-family/c-lex.c
> > > @@ -356,6 +356,8 @@ c_common_has_attribute (cpp_reader *pfile)
> > >|| is_attribute_p ("nodiscard", attr_name)
> > >|| is_attribute_p ("fallthrough", attr_name))
> > > result = 201603;
> > > + else if (is_attribute_p ("no_unique_address", attr_name))
> > > +   result = 20180312;
> >
> > Seems for all other attributes we return either 0, 1 or mm, you return
> > here mmdd, is that intentional?  If users think it is mm, then
> > they'd read it as December 201803.
>
> Jonathan verified that the value should be 201803, tested on x86_64-linux,
> ok for trunk?
>
> 2018-10-10  Jakub Jelinek  
>
> * c-lex.c (c_common_has_attribute): Return 201803 instead of 20180312
> for no_unique_address.
>
> * g++.dg/cpp2a/feat-cxx2a.C: New test.
>
> --- gcc/c-family/c-lex.c.jj 2018-10-08 15:18:36.665860856 +0200
> +++ gcc/c-family/c-lex.c2018-10-10 15:48:46.180923864 +0200
> @@ -357,7 +357,7 @@ c_common_has_attribute (cpp_reader *pfil
>|| is_attribute_p ("fallthrough", attr_name))
> result = 201603;
>   else if (is_attribute_p ("no_unique_address", attr_name))
> -   result = 20180312;
> +   result = 201803;
>   if (result)
> attr_name = NULL_TREE;
> }
> --- gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C.jj  2018-10-10 15:52:00.896663247 
> +0200
> +++ gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C 2018-10-10 15:52:59.865675782 
> +0200
> @@ -0,0 +1,447 @@
> +// { dg-options "-std=c++2a -I${srcdir}/g++.dg/cpp1y 
> -I${srcdir}/g++.dg/cpp1y/testinc" }
> +
> +//  C++98 features:
> +
> +#ifndef __cpp_rtti
> +#  error "__cpp_rtti"
> +#elif  __cpp_rtti != 199711
> +#  error "__cpp_rtti != 199711"
> +#endif
> +
> +#ifndef __cpp_exceptions
> +#  error "__cpp_exceptions"
> +#elif  __cpp_exceptions != 199711
> +#  error "__cpp_exceptions != 199711"
> +#endif
> +
> +//  C++11 features:
> +
> +#ifndef __cpp_raw_strings
> +#  error "__cpp_raw_strings"
> +#elif __cpp_raw_strings != 200710
> +#  error "__cpp_raw_strings != 200710"
> +#endif
> +
> +#ifndef __cpp_unicode_literals
> +#  error "__cpp_unicode_literals"
> +#elif __cpp_unicode_literals != 200710
> +#  error "__cpp_unicode_literals != 200710"
> +#endif
> +
> +#ifndef __cpp_user_defined_literals
> +#  error "__cpp_user_defined_literals"
> +#elif __cpp_user_defined_literals != 200809
> +#  error "__cpp_user_defined_literals != 200809"
> +#endif
> +
> +#ifndef __cpp_lambdas
> +#  error "__cpp_lambdas"
> +#elif __cpp_lambdas != 200907
> +#  error "__cpp_lambdas != 200907"
> +#endif
> +
> +#ifndef __cpp_range_based_for
> +#  error "__cpp_range_based_for"
> +#elif __cpp_range_based_for != 201603
> +#  error "__cpp_range_based_for != 201603"
> +#endif
> +
> +#ifndef __cpp_decltype
> +#  error "__cpp_decltype"
> +#elif __cpp_decltype != 200707
> +#  error "__cpp_decltype != 200707"
> +#endif
> +
> +#ifndef __cpp_attributes
> +#  error "__cpp_attributes"
> +#elif __cpp_attributes != 200809
> +#  error "__cpp_attributes != 200809"
> +#endif
> +
> +#ifndef __cpp_rvalue_references
> +#  error "__cpp_rvalue_references"
> +#elif __cpp_rvalue_references != 200610
> +#  error "__cpp_rvalue_references != 200610"
> +#endif
> +
> +#ifndef __cpp_variadic_templates
> +#  error "__cpp_variadic_templates"
> +#elif __cpp_variadic_templates != 200704
> +#  error "__cpp_variadic_templates != 200704"
> +#endif
> +
> +#ifndef __cpp_initializer_lists
> +#  error "__cpp_initializer_lists"
> +#elif __cpp_initializer_lists != 200806
> +#  error "__cpp_initializer_lists != 200806"
> +#endif
> +
> +#ifndef __cpp_delegating_constructors
> +#  error "__cpp_delegating_constructors"
> +#elif __cpp_delegating_constructors != 200604
> +#  error "__cpp_delegating_constructors != 200604"
> +#endif
> +
> +#ifndef __cpp_nsdmi
> +#  error "__cpp_nsdmi"
> +#elif __cpp_nsdmi != 200809
> +#  error "__cpp_nsdmi != 200809"
> +#endif
> +
> +#ifndef __cpp_inheriting_constructors
> +#  error "__cpp_inheriting_constructors"
> +#elif  __cpp_inheriting_constructors!= 201511
> +#  error "__cpp_inheriting_constructors != 201511"
> +#endif
> +
> +#ifndef __cpp_ref_qualifiers
> +#  error "__cpp_ref_qualifiers"
> +#elif __cpp_ref_qualifiers != 200710
> +#  error "__cpp_ref_qualifiers != 200710"
> +#endif
> +
> +#ifndef __cpp_alias_templates
> +#  error "__cpp_alias_templates"
> +#elif __cpp_alias_templates != 200704
> +#  error "__cpp_alias_templates != 200704"
> +#endif
> +
> +#ifndef __cpp_threadsafe_static_init
> +#  error "__cpp_threadsafe_static_init"
> +#elif __cpp_threadsafe_static_init != 200806
> +#  error "__cpp_threadsafe_static_init != 200806"
> 

Re: introduce --enable-mingw-full32 to default to --large-address-aware

2018-10-10 Thread JonY
On 10/10/2018 04:58 AM, Alexandre Oliva wrote:
> On Oct 10, 2018, JonY <10wa...@gmail.com> wrote:
> 
>> On 10/10/2018 03:24 AM, Alexandre Oliva wrote:
>>> On Oct  9, 2018, JonY <10wa...@gmail.com> wrote:
> 
>>> Now, if you wish it to affect Cygwin as well, I could implement that,
>>> and drop -mingw from the option name.  I'd retain the current defaults
>>> of each target, unless there's a strong reason to change them.
> 
>> In that case, no objections then.
> 
> Thanks.  Now, before I proceed, please clarify: did you mean you had no
> objections to the patch I last proposed, or to the plan in my last
> paragraph above?
> 

Your last proposed plan to use --enable-mingw-large-address-aware to
affect only mingw. If there are more targets in the future that need
this, we can always drop the mingw part in the configure option.



signature.asc
Description: OpenPGP digital signature


Re: [Patch, Fortran] PR fortran/83522 – reject array-valued substrings

2018-10-10 Thread Paul Richard Thomas
This seems to have caused errors in the testsuite. I guess that the
problem is that the testcases are invalid :-(

>From David Edelsohn:
Error: Substring reference of nonscalar not permitted at (1)

arrayio_11.f90
arrayio_12.f90
associate_23.f90
data_char_1.f90
deferred_character_2.f90
deferred_character_22.f90
deferred_character_23.f90
deferred_character_8.f90
deferred_type_component_3.f90

Cheers

Paul

On Mon, 8 Oct 2018 at 23:16, Thomas Koenig  wrote:
>
> Hi Tobias,
>
> nice to hear from you again!
>
> > Build and regtested on x86_64-linux.
> > OK for the trunk?
>
> OK. Thanks for the patch!
>
> Regards
>
> Thomas



--
"If you can't explain it simply, you don't understand it well enough"
- Albert Einstein


Fix PR middle-end/87574

2018-10-10 Thread Eric Botcazou
It turns out that, even if cgraph_node::expand_thunk happily overrides the 
DECL_IGNORED_P setting on the thunk from the front-end, this is necessary when 
the thunk is initially a back-end thunk and then turned into a GIMPLE thunk, 
e.g. because of inlining, to play nice with early debug info generation.

So the patch reinstates the overriding, but only when expanding to GIMPLE.

Tested on x86-64/Linux, applied on the mainline as obvious.


2018-10-10  Eric Botcazou  

PR middle-end/87574
* cgraphunit.c (cgraph_node::expand_thunk): Force DECL_IGNORED_P on
the thunk when expanding to GIMPLE.


2018-10-10  Eric Botcazou  

* g++.dg/other/pr87574.C: New test.

-- 
Eric BotcazouIndex: cgraphunit.c
===
--- cgraphunit.c	(revision 264986)
+++ cgraphunit.c	(working copy)
@@ -1862,6 +1862,12 @@ cgraph_node::expand_thunk (bool output_a
 	 DECL_ARGUMENTS.  In this case force_gimple_thunk is true.  */
   if (in_lto_p && !force_gimple_thunk)
 	get_untransformed_body ();
+
+  /* We need to force DECL_IGNORED_P when the thunk is created
+	 after early debug was run.  */
+  if (force_gimple_thunk)
+	DECL_IGNORED_P (thunk_fndecl) = 1;
+
   a = DECL_ARGUMENTS (thunk_fndecl);
 
   current_function_decl = thunk_fndecl;
// PR middle-end/87574
// Testcase by David Binderman 

// { dg-do compile }
// { dg-options "-O2 -g -Wno-return-type" }

class a {
public:
  virtual ~a();
};
class c {
public:
  enum j {};
  virtual j d() = 0;
};
class e : a, c {
  j d();
};
class f;
class g {
public:
  static g *h();
  f *i();
};
class f {
public:
  template  b *l(int);
};
c::j e::d() {}
void m() {
  for (int k;;)
g::h()->i()->l(k)->d();
}


Re: [PATCH] Make strlen range computations more conservative

2018-10-10 Thread Jeff Law
On 9/15/18 2:43 AM, Bernd Edlinger wrote:
> Hi,
> 
> this is an update on my strlen range patch (V7).  Again re-based and
> retested to current trunk.
> 
> I am aware that Martin wants to re-factor the interface of get_range_strlen
> and have no objections against, but I'd suggest that to be a follow-up patch.
> 
> I might suggest to rename one of the two get_range_strlen functions at the
> same time as it is rather confusing to have to count the parameters in order
> to tell which function is meant.
> 
> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
> Is it OK for trunk?
> 
> 
> Thanks
> Bernd.
> 
> 
> changelog-range-strlen-v7.txt
> 
> gcc:
> 2018-08-26  Bernd Edlinger  
> 
>   * gimple-fold.c (looks_like_a_char_array_without_typecast_p): New
>   helper function for strlen range estimations.
>   (get_range_strlen): Use looks_like_a_char_array_without_typecast_p
>   for warnings, but use GIMPLE semantics otherwise.
>   * tree-ssa-strlen.c (maybe_set_strlen_range): Use GIMPLE semantics.
>   (get_min_string_length): Avoid not NUL terminated string literals.
> 
> testsuite:
> 2018-08-26  Bernd Edlinger  
> 
>   * c-c++-common/attr-nonstring-3.c: Remove xfail.
>   * gcc.dg/pr83373.c: Add xfail.
>   * gcc.dg/strlenopt-36.c: Add xfail.
>   * gcc.dg/strlenopt-40.c: Adjust test expectations.
>   * gcc.dg/strlenopt-45.c: Adjust test expectations.
>   * gcc.dg/strlenopt-48.c: Add xfail.
>   * gcc.dg/strlenopt-51.c: Adjust test expectations.
>   * gcc.dg/strlenopt-59.c: New test.
>   * gcc.dg/strlenopt-60.c: New test.
Just an FYI -- this is not forgotten.  I'll be poking at it tomorrow.

Jeff


Re: [PATCH 4/4] - Replace uses of old get_range_strlen with the new one.

2018-10-10 Thread Jeff Law
On 10/2/18 10:37 AM, Martin Sebor wrote:
> [4/4] - Replace uses of old get_range_strlen with the new one.
> 
> This change switches the remaining get_range_strlen() callers
> to use the new overload of the function that takes a strlen_data_t
> argument.  There are no functional changes here.
> 
> gcc-9-4.diff
> 
> [4/4] - Replace uses of old get_range_strlen with the new one.
> 
> gcc/ChangeLog:
> 
>   * builtins.c (check_access): Use new get_range_strlen.
>   (check_strncat_sizes): Ditto.
>   (expand_builtin_strncat): Ditto.
>   * calls.c (maybe_warn_nonstring_arg): Ditto.
>   * gimple-fold.h (get_range_strlen): Remove unused overload.
>   * gimple-fold.c (get_range_strlen): Ditto.
>   (gimple_fold_builtin_strlen): Use new get_range_strlen.
> 
> diff --git a/gcc/builtins.c b/gcc/builtins.c
> index 3e31af4..daa520b 100644
> --- a/gcc/builtins.c
> +++ b/gcc/builtins.c
> @@ -3235,8 +3235,10 @@ check_access (tree exp, tree, tree, tree dstwrite,
>the upper bound given by MAXREAD add one to it for
>the terminating nul.  Otherwise, set it to one for
>the same reason, or to MAXREAD as appropriate.  */
> -   get_range_strlen (srcstr, range, /* eltsize = */ 1,
> - /* strict = */ false );
> +   strlen_data_t lendata (/* eltsize = */ 1);
> +   get_range_strlen (srcstr, );
> +   range[0] = lendata.minlen;
> +   range[1] = lendata.maxsize;
> if (range[0] && (!maxread || TREE_CODE (maxread) == INTEGER_CST))
Glad to see this cleaned up a little.  For whatever reason I find those
/* parm = */ value arguments make quick parsing of the code insanely
painful -- particularly when there's more than one of them.  Getting
down to just one helps a lot.

I don't see anything terribly concerning.  Obviously we may need
adjustments due to changes in earlier patches, but those would seem trivial.

jeff


Re: [PATCH 3/4] - Change sprintf to use new get_range_strlen overload

2018-10-10 Thread Jeff Law
On 10/2/18 10:37 AM, Martin Sebor wrote:
> [3/4] - Change sprintf to use new get_range_strlen overload
> 
> This change makes use of the new get_range_strlen() overload
> in gimple-ssa-sprintf.c.  This necessitated a few changes to
> the API but also enabled the removal of the flexarray member
> from strlen_data_t.
> 
> This also patch restores the bool return value for the public
> get_strlen_range function but with a different meaning (to
> indicate whether the computed range is suitable as is to rely
> on for optimization, rather than whether the argument may
> refer to a flexible array member).
> 
> The changes to gimple-ssa-sprintf.c involve more indentation
> adjustments than new functionality so to make the review easier
> I attach gcc-9-3-gimple-ssa-sprintf.c.diff-b with the white
> space changes stripped.
> 
> gcc-9-3.diff
> 
> [3/4] - Change sprintf to use new get_range_strlen overload
> 
> gcc/ChangeLog:
> 
>   * gimple-fold.c (get_range_strlen): Avoid clearing minlen after
>   recursive call fails for COND_EXPR and GIMPLE_PHI.
>   Set minlen to ssize_type rather than size_type.  Remove flexarray.
>   (get_range_strlen): Return bool.
>   (get_range_strlen): Return bool.  Clear minmaxlen[0].
>   * gimple-fold.h (strlen_data_t): Remove member.  Update comments.
>   (get_range_strlen): Return bool.
>   * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Reset lenrange[0]
>   when maxlen is unbounded.
>   * gimple-ssa-sprintf.c (get_string_length): Call new overload of
>   get_range_strlen.  Adjust max, likely, and unlikely counters for
>   strings of unbounded lengths.
This fixes most, but not all of the regressions introduced in patch #2
(pr79376 continues to regress).  However it introduces a bunch of
regressions on warn-sprintf-no-nul.c.

I wouldn't be surprised if we're losing range information.  Essentially
the sprintf bits want to say "give me whatever data you've got.  I don't
care if there's an unterminated string."   I wouldn't be surprised if
the changes to get_range_strlen are running afoul of those needs as the
changes to the sprintf bits themselves look pretty reasonable.



> @@ -2055,12 +2068,12 @@ get_string_length (tree str, unsigned eltsize)
>   of an array at the end of a struct assume that it's longer than
>   the array bound says it is in case it's used as a poor man's
>   flexible array member, such as in struct S { char a[4]; };  */
> -  res.range.unlikely = flexarray ? HOST_WIDE_INT_MAX : res.range.max;
> +  if (/* lendata.flexarray || */ unbounded)
> +res.range.unlikely = HOST_WIDE_INT_MAX;
> +  else
> +res.range.unlikely = res.range.max;
Please remove the commented out code if indeed it's no longer desired.


Jeff


[patch] allow target config to state r18 is fixed on aarch64

2018-10-10 Thread Olivier Hainque
Hello,

The aarch64 "platform register" r18 is currently
unconditionally used as a scratch register by gcc.

Working on a VxWorks port for this arch (that we
plan to contribute soon), we discovered that VxWorks
has an internal use of this register so it needs
to be considered "fixed" for this port.

Hence the attached patch proposal, which we have been
using successfully for a while now. It just introduces
a FIXED_R18 config macro, defaulted to 0, which an OS
specific config file may redefine.

Is this ok to commit ?

Thanks in advance,

With Kind Regards,

Olivier


2018-03-18  Olivier Hainque  

* config/aarch64/aarch64.h (FIXED_R18): New
internal configuration macro, defaulted to 0.
(FIXED_REGISTERS): Use it.
(STATIC_CHAIN_REGNUM): Fallback to r11 instead
of r18 if the latter is fixed.

diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index fa9af26..2e69a4d 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -284,11 +284,13 @@ extern unsigned aarch64_architecture_version;
 
 /* Standard register usage.  */
 
+#define FIXED_R18 0
+
 /* 31 64-bit general purpose registers R0-R30:
R30 LR (link register)
R29 FP (frame pointer)
R19-R28 Callee-saved registers
-   R18 The platform register; use as temporary register.
+   R18 The platform register; use as temporary register if !FIXED_R18.
R17 IP1 The second intra-procedure-call temporary register
(can be used by call veneers and PLT code); otherwise use
as a temporary register
@@ -324,7 +326,7 @@ extern unsigned aarch64_architecture_version;
   {\
 0, 0, 0, 0,   0, 0, 0, 0,  /* R0 - R7 */   \
 0, 0, 0, 0,   0, 0, 0, 0,  /* R8 - R15 */  \
-0, 0, 0, 0,   0, 0, 0, 0,  /* R16 - R23 */ \
+0, 0, FIXED_R18, 0, 0, 0, 0, 0,/* R16 - R23 */ \
 0, 0, 0, 0,   0, 1, 0, 1,  /* R24 - R30, SP */ \
 0, 0, 0, 0,   0, 0, 0, 0,   /* V0 - V7 */   \
 0, 0, 0, 0,   0, 0, 0, 0,   /* V8 - V15 */ \
@@ -419,7 +421,7 @@ extern unsigned aarch64_architecture_version;
uses alloca.  */
 #define EXIT_IGNORE_STACK  (cfun->calls_alloca)
 
-#define STATIC_CHAIN_REGNUMR18_REGNUM
+#define STATIC_CHAIN_REGNUM(!(FIXED_R18) ? R18_REGNUM : R11_REGNUM)
 #define HARD_FRAME_POINTER_REGNUM  R29_REGNUM
 #define FRAME_POINTER_REGNUM   SFP_REGNUM
 #define STACK_POINTER_REGNUM   SP_REGNUM


Re: [PATCH 2/4] - relax strlen range optimization to avoid making assumptions about types

2018-10-10 Thread Jeff Law
On 10/2/18 10:37 AM, Martin Sebor wrote:
> [2/4] - Relax strlen range optimization to avoid making assumptions
> about types
> 
> This main part of this patch is to relax the strlen range
> optimization to avoid relying on array types.  Instead, the function
> either removes the upper bound of the strlen result altogether, or
> constrains it by the size of referenced declaration (without
> attempting to deal with common symbols).
> 
> A seemingly "big" change here is splitting up the static
> get_range_strlen workhorse into two functions to make it easier
> to follow.  The attached cc-9-2-gimple-fold.c.diff-b shows
> the diff for the file without considering whitespace changes.
> 
> An important change to the get_range_strlen function worth calling
> out to is the introduction of the tight_bound local variable.
> It controls whether the upper bound computed by the function is
> suitable for optimization (the larger value) or warnings
> (the smaller value).
> 
> Another important change here is replacing the type and fuzzy
> arguments to get_range_strlen with a single enum.  The two arguments
> were confusing and with all combinations of their possible values
> being meaningful.  The original extern get_range_strlen overload
> with the type and fuzzy arguments is retained in this patch to
> keep the changes contained.  It is removed in [4/4].
> 
> Finally, a large number of tests needed adjusting here.  I also
> added a few new tests to better exercise the changes.
> 
> 
> gcc-9-2.diff
> 
> [2/4] - Relax strlen range optimization to avoid making assumptions about 
> types
> 
> gcc/ChangeLog:
> 
>   * calls.c (maybe_warn_nonstring_arg): Test for -1.
>   * gimple-fold.c (get_range_strlen): Forward declare static.
>   (get_range_strlen_tree): New helper.
>   (get_range_strlen): Move tree code into get_range_strlen_tree.
>   Replace type and fuzzy arguments with a single enum.
>   Avoid optimizing ranges based on type, optimize on decl size intead.
>   (get_range_strlen): New extern overload.
>   (get_range_strlen): Use new overload above.
>   (get_maxval_strlen): Declared static.  Assert preconditions.
>   Use new overload above.
>   (gimple_fold_builtin_strcpy): Adjust to pass enum.
>   (gimple_fold_builtin_strncpy): Same.
>   (gimple_fold_builtin_strcat): Same.
>   (gimple_fold_builtin_fputs): Same.
>   (gimple_fold_builtin_memory_chk): Same.
>   (gimple_fold_builtin_stxcpy_chk): Same.
>   (gimple_fold_builtin_stxncpy_chk): Same.
>   (gimple_fold_builtin_snprintf_chk): Same.
>   (gimple_fold_builtin_sprintf): Same.
>   (gimple_fold_builtin_snprintf): Same.
>   (gimple_fold_builtin_strlen): Simplify.  Call set_strlen_range.
>   * gimple-fold.h (StrlenType): New enum.
>   (get_maxval_strlen): Remove.
>   (get_range_strlen): Change default argument value to true (strict).
>   * tree-ssa-strlen.c (set_strlen_range): New function.
>   (maybe_set_strlen_range): Call it.  Make static.
>   (maybe_diag_stxncpy_trunc): Use new get_range_strlen overload.
>   Adjust.
>   * tree-ssa-strlen.h (set_strlen_range): Declare.
> 
> gcc/testsuite/ChangeLog:
> 
>   * g++.dg/init/strlen.C: New test.
>   * gcc.c-torture/execute/strlen-5.c: New test.
>   * gcc.c-torture/execute/strlen-6.c: New test.
>   * gcc.c-torture/execute/strlen-7.c: New test.
>   * gcc.dg/strlenopt-36.c: Remove tests for an overly aggressive
>   optimization.
>   * gcc.dg/strlenopt-40.c: Adjust tests to reflect a relaxed
>   optimization, remove others for an overly aggressive optimization.
>   * gcc.dg/strlenopt-45.c: Same.
>   * gcc.dg/strlenopt-48.c: Adjust tests to reflect a relaxed
>   optimization.
>   * gcc.dg/strlenopt-51.c: Same.
>   * gcc.dg/strlenopt-59.c: New test.
So from a review standpoint, a distinct patch that splits up the
function, but makes no behavioral changes would help.  That can be gated
in quickly and it reduces the amount of noise one has to sort through in
the changes that affect behavior.  Though the git diff ignoring
whitespace definitely helped.

Camelcase is verboten.  Please don't use it (StrlenType and its
associated enumeration values).   Make the enumeration type lower case
and make the enumeration values all caps.  That's standard practice.

Was this tested independently?  I applied patch #1 and this to my tree,
and I get a bunch of regressions.

builtin-snprintf-warn-?.c
builtin-sprintf-warn-?.c
pr79376.c

In all there's ~75 regressions with this patch.

It's unclear if those are inherent in the patch, a result of previous
API changes (c_strlen in particular), or me incorrectly resolving
conflicts for various hunks.  Some may be fixed in #3 or #4.  In which
case we just need to be aware of the dependencies between the patches
from a testsuite regression standpoint.

It would be advisable to go back to Bernd's patch and see if his new
tests 

Re: C++ PATCH for c++/87567, constexpr rejects call to non-constexpr function

2018-10-10 Thread Marek Polacek
On Wed, Oct 10, 2018 at 03:48:34PM -0400, Jason Merrill wrote:
> On Wed, Oct 10, 2018 at 11:58 AM Marek Polacek  wrote:
> >
> > In this testcase, the call to f() can never be a constant expression, but
> > that's not a problem because it is never reached.  We handle a similar 
> > scenario
> > for IF_STMT, so we can just do the same.  The RANGE_FOR_STMT case seems to
> > never be reached in the whole testsuite, so I didn't change that.
> 
> That seems like a hole in the testsuite.  How about this?
> 
> constexpr int
> fn3()
> {
>   struct empty_range {
> constexpr int* begin() { return 0; }
> constexpr int* end() { return 0; }
>   } e;
>   for (auto x : e)
> f();
>   return 0;
> }
> 
> The patch is OK; you can address fn3 in a follow-up patch.

Thanks.  fn3() still only triggers case FOR_STMT, because RANGE_FOR_STMT are
only created in templates, and are converted to FOR_STMTs in tsubst_expr.

But I've now found a testcase that triggers the RANGE_FOR_STMT case:

int f() { return 1; }

template
constexpr void
fn4 ()
{
  struct empty_range {
constexpr int* begin() { return 0; }
constexpr int* end() { return 0; }
  } e;
  constexpr int j = ({ for (auto x : e) f(); 1; });
}

void
fn5 ()
{
  fn4();
}

However, we fail to compile both fn3 and fn4, because we're unable to evaluate
__for_begin != __for_end.  I'm going to try to figure out why.

Marek


[PATCH] v2: C++: simplify output from suggest_alternatives_for

2018-10-10 Thread David Malcolm
On Tue, 2018-10-09 at 18:38 -0400, Jason Merrill wrote:
> On Tue, Oct 9, 2018 at 1:19 PM David Malcolm 
> wrote:
> > +  /* Emulation of a "move" constructor, but really a copy
> > + constructor.  */
> > +
> > +  name_hint (const name_hint )
> > +  : m_suggestion (other.m_suggestion),
> > +m_deferred (const_cast (other).take_deferred ())
> > +  {
> > +  }
> > +
> > +  /* Emulation of "move" assigment, but really copy
> > assignment.  */
> > +
> > +  name_hint& operator= (const name_hint )
> > +  {
> > +m_suggestion = other.m_suggestion;
> > +m_deferred = const_cast (other).take_deferred ();
> > +return *this;
> > +  }
> > +
> > +  /* Take ownership of this name_hint's deferred_diagnostic, for
> > use
> > + in chaining up deferred diagnostics.  */
> > +  gnu::unique_ptr take_deferred () { return
> > move (m_deferred); }
> 
> Why do you want to propagate this hackery into name_hint?  I would
> expect the defaulted special member functions to do the right thing
> with m_deferred: in -std=c++98 the implicit copy ops call the
> gnu::unique_ptr copy ops that actually move, and in -std=c++11 and up
> we're calling the move constructor for std::unique_ptr, which does
> the
> right thing.
> 
> This also doesn't limit the hack to C++98 mode the way unique-ptr.h
> does.
> 
> Jason

Thanks for looking at this.

I ran into issues trying to pass around name_hint instances:

../../src/gcc/cp/name-lookup.c: In function 'name_hint 
suggest_alternatives_in_other_namespaces(location_t, tree)':
../../src/gcc/cp/name-lookup.c:5591:52: error: use of deleted function 
'name_hint::name_hint(const name_hint&)'
5591 |   return ns_hints.maybe_decorate_with_limit (result);
 |^
In file included from ../../src/gcc/cp/name-lookup.c:36:
../../src/gcc/c-family/name-hint.h:91:7: note: 'name_hint::name_hint(const 
name_hint&)' is implicitly deleted because the default definition would be 
ill-formed:
91 | class name_hint
   |   ^
../../src/gcc/c-family/name-hint.h:91:7: error: use of deleted function 
'std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with 
_Tp = deferred_diagnostic; _Dp = std::default_delete]'
In file included from 
/home/david/coding/gcc-python/gcc-svn-trunk/install-dogfood/include/c++/9.0.0/memory:80,
 from ../../src/gcc/../include/unique-ptr.h:78,
 from ../../src/gcc/system.h:730,
 from ../../src/gcc/cp/name-lookup.c:23:
/home/david/coding/gcc-python/gcc-svn-trunk/install-dogfood/include/c++/9.0.0/bits/unique_ptr.h:394:7:
 note: declared here
394 |   unique_ptr(const unique_ptr&) = delete;
|   ^~
../../src/gcc/cp/name-lookup.c:5512:1: note:   initializing argument 1 of 
'name_hint namespace_hints::maybe_decorate_with_limit(name_hint)'
5512 | namespace_hints::maybe_decorate_with_limit (name_hint hint)
 | ^~~

I can't use the default copy constructor or assignment operators for an
object containing a gnu::unique_ptr on C++11, as std::unique_ptr has:

  // Disable copy from lvalue.
  unique_ptr(const unique_ptr&) = delete;
  unique_ptr& operator=(const unique_ptr&) = delete;

If I understand things right, in C++11 I should be using move
construction/move assignment for this.

I can't write "&&" in the function params to explicitly request an
rvalue-reference, as the code need to be compatible with C++98.

std::move is only defined in C++11 onwards.

Our include/unique-ptr.h defines a gnu::move: for C++11 it's std::move,
but for C++98 it's only defined for the unique_ptr template.

A solution that seems to work appears to be to define gnu::move for
C++98 for all types rather than just gnu::unique_ptr, implementing it
in terms of copying an object via lvalue reference, so that we can
explicitly request a move using "gnu::move" (==std::move on C++),
without using C++11 syntax, and falling back to a copy on C++98
(which effectively moves the ptr from the "victim").

Does that sound sane?

I implemented "take_deferred" as I wanted to keep m_deferred private,
and needed an "accessor".  With the above formulation, it becomes:

{ return move (m_deferred); }

Here's an updated version of the patch which implements the above idea:

Changed in v2:
* dropped addition of name_hint copy ctor and copy assignment in
  favor of using gnu::move wherever move assignment needs to happen
  or be emulated
* generalized gnu::move for pre-C++11 to apply to all lvalue references,
  rather than just to gnu::unique_ptr
* drop stray !DECL_P identified in another email

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu

I also tested a non-bootstrap build with gcc 4.8 and with trunk (to build
without and with C++11), running various testcases under valgrind.

OK for trunk?

include/ChangeLog:
* unique-ptr.h (gnu::move): Generalize so it applies to all
lvalue references, rather than just to unique_ptr values.


Make std::forward_list iterator operators inline friend

2018-10-10 Thread François Dumont
Same patch as for std::list iterators. I only additionally move doc on 
those operators.


I also avoid redefining some typedef that are already defined in 
_Fwd_list_base<>.


    * include/bits/forward_list.h
    (_Fwd_list_iterator<>::operator==): Replace member function with inline
    friend.
    (_Fwd_list_iterator<>::operator!=): Likewise.
    (_Fwd_list_const_iterator<>::operator==): Likewise.
    (_Fwd_list_const_iterator<>::operator!=): Likewise.
    (operator==(const _Fwd_list_iterator<>&,
    const _Fwd_list_const_iterator<>&)): Remove.
    (operator!=(const _Fwd_list_iterator<>&,
    const _Fwd_list_const_iterator<>&)): Remove.
    (forward_list<>::_Node): Take typedef from base type.
    (forward_list<>::iterator): Likewise.
    (forward_list<>::const_iterator): Likewise.

Tested under Linux x86_64.

Ok to commit ?

François

diff --git a/libstdc++-v3/include/bits/forward_list.h b/libstdc++-v3/include/bits/forward_list.h
index 84a4ad4d5dc..ebec3b5c818 100644
--- a/libstdc++-v3/include/bits/forward_list.h
+++ b/libstdc++-v3/include/bits/forward_list.h
@@ -173,13 +173,20 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	return __tmp;
   }
 
-  bool
-  operator==(const _Self& __x) const noexcept
-  { return _M_node == __x._M_node; }
+  /**
+   *  @brief  Forward list iterator equality comparison.
+   */
+  friend bool
+  operator==(const _Self& __x, const _Self& __y) noexcept
+  { return __x._M_node == __y._M_node; }
 
-  bool
-  operator!=(const _Self& __x) const noexcept
-  { return _M_node != __x._M_node; }
+
+  /**
+   *  @brief  Forward list iterator inequality comparison.
+   */
+  friend bool
+  operator!=(const _Self& __x, const _Self& __y) noexcept
+  { return __x._M_node != __y._M_node; }
 
   _Self
   _M_next() const noexcept
@@ -244,13 +251,19 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 	return __tmp;
   }
 
-  bool
-  operator==(const _Self& __x) const noexcept
-  { return _M_node == __x._M_node; }
+  /**
+   *  @brief  Forward list const_iterator equality comparison.
+   */
+  friend bool
+  operator==(const _Self& __x, const _Self& __y) noexcept
+  { return __x._M_node == __y._M_node; }
 
-  bool
-  operator!=(const _Self& __x) const noexcept
-  { return _M_node != __x._M_node; }
+  /**
+   *  @brief  Forward list const_iterator inequality comparison.
+   */
+  friend bool
+  operator!=(const _Self& __x, const _Self& __y) noexcept
+  { return __x._M_node != __y._M_node; }
 
   _Self
   _M_next() const noexcept
@@ -264,24 +277,6 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   const _Fwd_list_node_base* _M_node;
 };
 
-  /**
-   *  @brief  Forward list iterator equality comparison.
-   */
-  template
-inline bool
-operator==(const _Fwd_list_iterator<_Tp>& __x,
-	   const _Fwd_list_const_iterator<_Tp>& __y) noexcept
-{ return __x._M_node == __y._M_node; }
-
-  /**
-   *  @brief  Forward list iterator inequality comparison.
-   */
-  template
-inline bool
-operator!=(const _Fwd_list_iterator<_Tp>& __x,
-	   const _Fwd_list_const_iterator<_Tp>& __y) noexcept
-{ return __x._M_node != __y._M_node; }
-
   /**
*  @brief  Base class for %forward_list.
*/
@@ -433,8 +428,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
 
 private:
   typedef _Fwd_list_base<_Tp, _Alloc>		_Base;
-  typedef _Fwd_list_node<_Tp>			_Node;
   typedef _Fwd_list_node_base			_Node_base;
+  typedef typename _Base::_Node			_Node;
   typedef typename _Base::_Node_alloc_type		_Node_alloc_type;
   typedef typename _Base::_Node_alloc_traits	_Node_alloc_traits;
   typedef allocator_traits<__alloc_rebind<_Alloc, _Tp>>	_Alloc_traits;
@@ -447,8 +442,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   typedef value_type&reference;
   typedef const value_type&const_reference;
 
-  typedef _Fwd_list_iterator<_Tp>			iterator;
-  typedef _Fwd_list_const_iterator<_Tp>		const_iterator;
+  typedef typename _Base::iterator			iterator;
+  typedef typename _Base::const_iterator		const_iterator;
   typedef std::size_tsize_type;
   typedef std::ptrdiff_tdifference_type;
   typedef _Alloc	allocator_type;


Re: [Patch 1/3][Aarch64] Implement Aarch64 SIMD ABI

2018-10-10 Thread Steve Ellcey

> LGTM otherwise, but I'll leave the AArch64 maintainers to do the
> main review.
> 
> Thanks,
> Richard

Here is an updated version that addresses the issues you raised.  The
only thing I did not try to do is to
change aarch64_use_simple_return_insn_p, so shrink wrapping of SIMD
functions will still not happen.  I think that may be a good thing,
but I am not sure of everything involved in getting that to work so I
skipped it for now while I work on the rest of the simd ABI changes
like the ones in patches 2 and 3.

I also added a new test to make sure that the code
in aarch64_epilogue_uses was not saving extraneous registers.  While
that function returns true for all vector registers that a SIMD
function must save, only registers that are used/clobbered in the
function will be saved.  That is now tested with the simd-abi-5.c
test.

Steve Ellcey
sell...@cavium.com


2018-10-10  Steve Ellcey  

* config/aarch64/aarch64-protos.h (aarch64_use_simple_return_insn_p):
New prototype.
(aarch64_epilogue_uses): Ditto.
* config/aarch64/aarch64.c (aarch64_attribute_table): New array.
(aarch64_simd_decl_p): New function.
(aarch64_reg_save_mode): New function.
(aarch64_is_simd_call_p): New function.
(aarch64_function_ok_for_sibcall): Check for simd calls.
(aarch64_layout_frame): Check for simd function.
(aarch64_gen_storewb_pair): Handle E_TFmode.
(aarch64_push_regs): Use aarch64_reg_save_mode to get mode.
(aarch64_gen_loadwb_pair): Handle E_TFmode.
(aarch64_pop_regs): Use aarch64_reg_save_mode to get mode.
(aarch64_gen_store_pair): Handle E_TFmode.
(aarch64_gen_load_pair): Ditto.
(aarch64_save_callee_saves): Handle different mode sizes.
(aarch64_restore_callee_saves): Ditto.
(aarch64_components_for_bb): Check for simd function.
(aarch64_epilogue_uses): New function.
(aarch64_process_components): Check for simd function.
(aarch64_expand_prologue): Ditto.
(aarch64_expand_epilogue): Ditto.
(aarch64_expand_call): Ditto.
(aarch64_use_simple_return_insn_p): New function.
(TARGET_ATTRIBUTE_TABLE): New define.
* config/aarch64/aarch64.h (EPILOGUE_USES): Redefine.
(FP_SIMD_SAVED_REGNUM_P): New macro.
* config/aarch64/aarch64.md (simple_return): New define_expand.
(load_pair_dw_tftf): New instruction.
(store_pair_dw_tftf): Ditto.
(loadwb_pair_): Ditto.
("storewb_pair_): Ditto.


2018-10-10  Steve Ellcey  

* gcc.target/aarch64/torture/aarch64-torture.exp: New file.
* gcc.target/aarch64/torture/simd-abi-1.c: New test.
* gcc.target/aarch64/torture/simd-abi-2.c: Ditto.
* gcc.target/aarch64/torture/simd-abi-3.c: Ditto.
* gcc.target/aarch64/torture/simd-abi-4.c: Ditto.
* gcc.target/aarch64/torture/simd-abi-5.c: Ditto.diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 5f18837..0f54adf 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -467,6 +467,7 @@ bool aarch64_split_dimode_const_store (rtx, rtx);
 bool aarch64_symbolic_address_p (rtx);
 bool aarch64_uimm12_shift (HOST_WIDE_INT);
 bool aarch64_use_return_insn_p (void);
+bool aarch64_use_simple_return_insn_p (void);
 const char *aarch64_mangle_builtin_type (const_tree);
 const char *aarch64_output_casesi (rtx *);
 
@@ -552,6 +553,8 @@ void aarch64_split_simd_move (rtx, rtx);
 /* Check for a legitimate floating point constant for FMOV.  */
 bool aarch64_float_const_representable_p (rtx);
 
+extern int aarch64_epilogue_uses (int);
+
 #if defined (RTX_CODE)
 void aarch64_gen_unlikely_cbranch (enum rtx_code, machine_mode cc_mode,
    rtx label_ref);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index d385b24..2d4e47b 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -1088,6 +1088,15 @@ static const struct processor *selected_tune;
 /* The current tuning set.  */
 struct tune_params aarch64_tune_params = generic_tunings;
 
+/* Table of machine attributes.  */
+static const struct attribute_spec aarch64_attribute_table[] =
+{
+  /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
+   affects_type_identity, handler, exclude } */
+  { "aarch64_vector_pcs", 0, 0, false, true,  true,  false, NULL, NULL },
+  { NULL, 0, 0, false, false, false, false, NULL, NULL }
+};
+
 #define AARCH64_CPU_DEFAULT_FLAGS ((selected_cpu) ? selected_cpu->flags : 0)
 
 /* An ISA extension in the co-processor and main instruction set space.  */
@@ -1466,6 +1475,45 @@ aarch64_hard_regno_mode_ok (unsigned regno, machine_mode mode)
   return false;
 }
 
+/* Return true if this is a definition of a vectorized simd function.  */
+
+static bool
+aarch64_simd_decl_p (tree fndecl)
+{
+  tree fntype;
+
+  if (fndecl == NULL)
+return false;
+  

Re: C++ PATCH for c++/87567, constexpr rejects call to non-constexpr function

2018-10-10 Thread Jason Merrill
On Wed, Oct 10, 2018 at 11:58 AM Marek Polacek  wrote:
>
> In this testcase, the call to f() can never be a constant expression, but
> that's not a problem because it is never reached.  We handle a similar 
> scenario
> for IF_STMT, so we can just do the same.  The RANGE_FOR_STMT case seems to
> never be reached in the whole testsuite, so I didn't change that.

That seems like a hole in the testsuite.  How about this?

constexpr int
fn3()
{
  struct empty_range {
constexpr int* begin() { return 0; }
constexpr int* end() { return 0; }
  } e;
  for (auto x : e)
f();
  return 0;
}

The patch is OK; you can address fn3 in a follow-up patch.

Jason


[PING**2] [PATCH] Fix not properly nul-terminated string constants in JIT

2018-10-10 Thread Bernd Edlinger
Ping...


On 08/26/18 21:40, Bernd Edlinger wrote:
> Ping...
> 
> This is just plain wrong, independent
> of any STRING_CST semantic issues.
> 
> The original patch (retested on current trunk) is
> here: https://gcc.gnu.org/ml/gcc-patches/2018-08/msg00370.html
> 
> 
> On 08/05/18 18:59, Bernd Edlinger wrote:
>> Hi!
>>
>>
>> My other patch with adds assertions to varasm.c regarding correct
>> nul termination of sting literals did make these incorrect string
>> constants in JIT frontend fail.
>>
>> The string constants are not nul terminated if their length exceeds
>> 200 characters.  The test cases do not use strings of that size where
>> that would make a difference.  But using a fixed index type is clearly
>> wrong.
>>
>> This patch removes the fixed char[200] array type from playback::context,
>> and uses build_string_literal instead of using build_string directly.
>>
>>
>> Bootstrapped and reg-tested on x86_64-pc-linux-gnu.
>> Is it OK for trunk?
>>
>>
>> Thanks
>> Bernd.


Re: [PATCH 1/4] introduce struct strlen_data_t into gimple-fold

2018-10-10 Thread Jeff Law
On 10/2/18 10:37 AM, Martin Sebor wrote:
> [1/4] - Introduce struct strlen_data_t into gimple-fold
> 
> This patch introduces a new data structure to reduce the number
> of arguments and overloads of the get_range_strlen API.  One of
> the goals of this change is to make the API safer to use for
> optimization (which looks for "permissive" results to account
> even for some undefined uses) vs warnings (which relies on
> conservative results to avoid false positives).  The patch also
> adds provides explicit arguments to get_range_strlen and adds
> descriptive comments to make the affected code easier to follow.
> Beyond making use of the new data structure the patch makes no
> observable changes.
> 
> The changes to gcc/testsuite/gcc.dg/strlenopt-51.c fix a few
> typos with no functional effect and tweak the helper macro
> used by the test to make debugging slightly easier.
> 
> gcc-9-1.diff
> 
> [1/4] - Introduce struct strlen_data_t into gimple-fold.
> 
> gcc/ChangeLog:
> 
>   * builtins.c (check_access): Document argumens to a function call.
>   (check_strncat_sizes): Same.
>   (expand_builtin_strncat): Same.
>   * calls.c (maybe_warn_nonstring_arg): Same.
>   * gimple-fold.h (struct strlen_data_t): New type.
>   (get_range_strlen): New overload.
>   * gimple-fold.c (struct strlen_data_t): New type.
>   (get_range_strlen): Change declaration to take strlen_data_t*
>   argument instead of length, flexp, eltsize, and nonstr.
>   Adjust to use strlen_data_t members instead of other arguments.
>   Also set strlen_data_t::maxsize to the same value as maxlen.
>   (extern get_range_strlen): Define new overload.
>   (get_maxval_strlen): Adjust to use strlen_data_t.
>   * gimple-ssa-sprintf.c (get_string_length): Same.
> 
> gcc/testsuite/ChangeLog:
>   gcc.dg/strlenopt-51.c: Add counter to macros and fix typos.
> 
> diff --git a/gcc/calls.c b/gcc/calls.c
> index e9660b6..11f00ad 100644
> --- a/gcc/calls.c
> +++ b/gcc/calls.c
> @@ -1582,7 +1585,8 @@ maybe_warn_nonstring_arg (tree fndecl, tree exp)
> {
>   tree arg = CALL_EXPR_ARG (exp, argno);
> g if (!get_attr_nonstring_decl (arg))
> -   get_range_strlen (arg, lenrng);
> +   get_range_strlen (arg, lenrng, /* eltsize = */ 1,
> + /* strict = */ false);
> }
>}
>/* Fall through.  */
As Bernd noted, something clearly went wrong here with the patch the "g"
at the beginning of the line.  Hand-edited patch perhaps?  Regardless I
assume you'll fix this.


> diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
> index 1e84722..8f71e9c 100644
> --- a/gcc/gimple-fold.c
> +++ b/gcc/gimple-fold.c
> @@ -1262,11 +1262,13 @@ gimple_fold_builtin_memset (gimple_stmt_iterator 
> *gsi, tree c, tree len)
>  }
>  
>  
> -/* Obtain the minimum and maximum string length or minimum and maximum
> -   value of ARG in LENGTH[0] and LENGTH[1], respectively.
> +/* Try to obtain the range of the lengths of the string(s) referenced
> +   by ARG, or the size of the largest array ARG referes to if the range
> +   of lengths cannot be determined, and store all in *PDATA.
> If ARG is an SSA name variable, follow its use-def chains.  When
> -   TYPE == 0, if LENGTH[1] is not equal to the length we determine or
> -   if we are unable to determine the length or value, return false.
> +   TYPE == 0, then if PDATA->MAXLEN is not equal to the determined
> +   length or if we are unable to determine the length or value, return
> +   false.
> VISITED is a bitmap of visited variables.
> TYPE is 0 if string length should be obtained, 1 for maximum string
> length and 2 for maximum value ARG can have.
So can we clarify the return value?  What is the return value for types
other than 0?  I struggled with parsing that before this patch :-)


>  
>  static bool
> -get_range_strlen (tree arg, tree length[2], bitmap *visited, int type,
> -   int fuzzy, bool *flexp, unsigned eltsize, tree *nonstr)
> +get_range_strlen (tree arg, bitmap *visited, int type, int fuzzy,
> +   strlen_data_t *pdata)
So ISTM we should keep ELTSIZE as distinct parameter as its strictly an
input.  That in turn allows *PDATA to be strictly filled in as an output.



>  
>  
> diff --git a/gcc/gimple-fold.h b/gcc/gimple-fold.h
> index 26e2727..0d523e7 100644
> --- a/gcc/gimple-fold.h
> +++ b/gcc/gimple-fold.h
> @@ -25,6 +25,53 @@ along with GCC; see the file COPYING3.  If not see
>  extern tree create_tmp_reg_or_ssa_name (tree, gimple *stmt = NULL);
>  extern tree canonicalize_constructor_val (tree, tree);
>  extern tree get_symbol_constant_value (tree);
> +
> +struct strlen_data_t
> +{
> +  /* [MIN, MAXSIZE, MAXLEN] is a range describing the length of
> + a string of possibly unknown length.  For a string of known
> + length the range is a constant where MIN == MAXSIZE == MAXLEN
> + holds.
> + For other strings, MIN is the length of 

Re: [PATCH, rs6000] testcases for vec_insert

2018-10-10 Thread Segher Boessenkool
On Wed, Oct 10, 2018 at 01:24:52PM -0500, Will Schmidt wrote:
> > For all the scan-assembler tests, did you verify these are exactly the
> > instructions we want generated?
> 
> "want" may be a bit strong, but I do verified that is what we get now.

The difference is if the testcases start failing with random compiler
changes while there is nothing wrong, or not.

We'll know soon enough ;-)


Segher


Re: [PING][PATCH] tighten up -Wclass-memaccess for ctors/dtors (PR 84851)

2018-10-10 Thread Jeff Law
On 10/8/18 8:22 PM, Martin Sebor wrote:
> Ping: https://gcc.gnu.org/ml/gcc-patches/2018-05/msg01528.html
> 
> I will go ahead and commit this as obvious this week if there
> are no objections.
Go ahead.

Jeff


Re: [PATCH] diagnose bogus assume_aligned attributes (PR 87533)

2018-10-10 Thread Jeff Law
On 10/5/18 4:56 PM, Martin Sebor wrote:
> While working on tests for an enhancement in the area of
> attributes I noticed that the handler for attribute assume_aligned
> (among others) does only a superficial job of detecting meaningless
> specifications such as using the attribute on a function returning
> void or alignments that aren't powers of two, out-of-range offsets,
> and so on.  None of the expected warnings in the test case triggers
> (Clang diagnoses all of them).
> 
> The attached patch improves the detection of these nonsensical
> constructs, and brings GCC closer to the more thorough job other
> compilers do.  Tested on x86_64-linux.
> 
> Martin
> 
> gcc-87533.diff
> 
> PR middle-end/87533 - bogus assume_aligned attribute silently accepted
> 
> gcc/c-family/ChangeLog:
> 
>   PR middle-end/87533
>   * c-attribs.c (handle_assume_aligned_attribute): Diagnose and
>   reject invalid attribute specifications.
> 
> gcc/testsuite/ChangeLog:
> 
>   PR middle-end/87533
>   * gcc.dg/attr-assume_aligned-4.c: New test.
OK.
jeff


Re: [PATCH] Reset insn priority after inc/ref replacement in haifa sched

2018-10-10 Thread Jeff Law
On 10/10/18 10:03 AM, Robin Dapp wrote:
> Hi,
> 
> as my last message
> (https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00280.html) did not
> garner much attention, I'm posting it in proper patch form this time.
> The problem I'm trying to solve is that an insn's priority seems
> unchanged if the priority of insns that depend on it is changed (and the
> first insn's priority was computed by on of these dependent insns'
> priority).  If I missed something or there is another way this should be
> working, I'd like to learn about that.
> 
> A non-bootstrapped test suite run on s390 showed no regressions and an
> x86 one is currently running (current HEAD didn't bootstrap for me on
> x86). The actual code changes throughout SPEC2006 are minor and the
> performance impact is negligible provided we do not hit a fixable bad
> case as described in my last message.
> 
> Regards
>  Robin
> 
> --
> 
> gcc/ChangeLog:
> 
> 2018-10-10  Robin Dapp  
> 
> * haifa-sched.c (apply_replacement):
>   Reset insn priority after inc/ref replacement.
> 
See my last message.  I find myself wondering if we need to reset
INSN_PRIORITY_STATUS in update_insn_after_change and/or calling
update_insn_after_change on INSN in additional to calling it on DESC->insn.

jeff


Re: sched2 priorities and replacements

2018-10-10 Thread Jeff Law
On 10/4/18 9:54 AM, Robin Dapp wrote:
> Hi,
> 
> I'm working on some insn latency changes in the s390 backend and noticed
> a regression in the SPEC2006 bzip2 test case that was due to some insns
> being scheduled differently.
> 
> The sequence in short form before my change is
> 
> ;;  | insn | prio |
> ;;  |  823 |1 | %r1=%r1+0x1nothing
> ;;  |  420 |1 | %r3=zxn([%r1]) nothing
> ;;  |  422 |1 | [%r1]=%r7  nothing
> ;;  |  421 |0 | %r4=%r3nothing
> ;;  |  423 |0 | %r7=%r3nothing
> ;;  |  428 |0 | {pc={(%r6!=%r3)?L424:pc};clobber %cc;} nothing
> 
> sched2 detects a memory inc/ref that can be changed in order to get rid
> of the dependency 823 -> 420.  After that insn 420 is selected and the
> same happens for insn 422 before insn 823 is scheduled at third
> position.  Actually, what promotes 420 to the first position in the
> ready queue is not the priority but some of the tie breakers.
> 
> Now, after my change the situation looks like:
> 
> ;;  | insn | prio |
> ;;  |  825 |6 | %r1=%r1+0x1nothing
> ;;  |  420 |4 | %r3=zxn([%r1]) nothing
> ;;  |  422 |3 | [%r1]=%r5  nothing
> ;;  |  421 |0 | %r4=%r3nothing
> ;;  |  423 |0 | %r5=%r3nothing
> ;;  |  428 |0 | {pc={(%r7!=%r3)?L424:pc};clobber %cc;} nothing
> ;;   --- forward dependences: 
> 
> The same inc/ref as before is detected but insn 825 still has the
> highest priority and will be selected in the next cycle.  Subsequently,
> the replacement is reverted and insn 420, 422 are scheduled.  This
> introduces a data dependency 825 -> 420 that wasn't there before.
> 
> In haifa-sched.c:apply_replacement (), after applying the replacement,
> the dependent insn (420) is updated and its scheduling properties are
> reset.  Nothing happens with insn 825 however.  I would have expected
> that its priority should be recomputed after breaking a dependency since
> it is recursively determined by the priority of the dependent insns.
> 
> As a quick hack, I did
> 
> diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
> index 1fdc9df9fb2..1340f34ed9f 100644
> --- a/gcc/haifa-sched.c
> +++ b/gcc/haifa-sched.c
> @@ -4713,7 +4713,18 @@ apply_replacement (dep_t dep, bool immediately)
>success = validate_change (desc->insn, desc->loc, desc->newval, 0);
>gcc_assert (success);
> 
> +  rtx_insn *insn = DEP_PRO (dep);
> +  INSN_PRIORITY_STATUS (insn) = -1;
> +  sd_iterator_def sd_it;
> +  sd_it = sd_iterator_start (insn, SD_LIST_FORW);
> +  while (sd_iterator_cond (_it, ))
> +   {
> + DEP_COST (dep) = UNKNOWN_DEP_COST;
> + sd_iterator_next (_it);
> +   }
> +  priority (insn);
>update_insn_after_change (desc->insn);
> +
>if ((TODO_SPEC (desc->insn) & (HARD_DEP | DEP_POSTPONED)) == 0)
> fix_tick_ready (desc->insn);
> 
> which prompts a recomputation of 825's priority and helps with my
> regression (but doesn't get rid of it completely).  I haven't checked
> any other test case but wanted to hear some opinions first.
> 
> This looks really basic and I'm rather sure I missed some other
> scheduling part that could deal with this kind of situation.  Would
> somebody mind elucidating?
It could well be an oversight.  Bernd S. doesn't chime in much these
days, so I don't necessarily think we'll get an answer from him.

In theory I think we're supposed to call update_insn_after_change.  I
see it doesn't twiddle INSN_PRIORITY_STATUS, but it does reset DEP_DOST,
INSN_COST and INSN_TICK.

So I'd see if we're calling update_insn_after_change appropriately.  And
if so, then I'd consider twiddling it to update INSN_PRIORITY_STATUS in
addition to the things it already does.

jeff



Re: [PATCH, rs6000] vec_extract testcase coverage

2018-10-10 Thread Segher Boessenkool
Hi!

On Wed, Oct 10, 2018 at 10:14:42AM -0500, Will Schmidt wrote:
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p7.c
> @@ -0,0 +1,60 @@
> +/* Verify that overloaded built-ins for vec_extract() with char
> +   inputs produce the right code with a power7 (BE) target.  */
> +
> +/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
> +/* { dg-require-effective-target powerpc_altivec_ok } */

powerpc_altivec_ok is true on all systems nowadays.

> +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
> "-mcpu=power7" } } */
> +/* { dg-options "-maltivec -mcpu=power7 -O2" } */

And -mcpu=power7 implies -maltivec, too.

> +/* { dg-final { scan-assembler-times "lhz|lha|lhzx|lhax" 6  } } */

"lhz" matches "lhzx" as well, etc.


But this will all work afaics so okay for trunk with or without fixing it
up a little.  Thanks!


Segher


Re: [PATCH, rs6000] testcases for vec_insert

2018-10-10 Thread Will Schmidt
On Wed, 2018-10-10 at 12:33 -0500, Segher Boessenkool wrote:
> Hi!
> 
> On Wed, Oct 10, 2018 at 10:14:31AM -0500, Will Schmidt wrote:
> >   Add some testcases for verification of vec_insert() codegen.
> > The char,float,int,short tests are broken out into -p8 and -p9
> > variants due to codegen variations between the platforms.
> > 
> > Tested across assorted power linux platforms.  OK for trunk?
> 
> > +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-insert-char-p8.c
> 
> > +/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
> 
> The usual questions wrt lp64 :-)
> 
> > +/* { dg-require-effective-target powerpc_p8vector_ok } */
> > +/* { dg-options "-maltivec -O2" } */
> 
> You say the same thing (and more) two lines later :-)

heh, I really meant it, i guess.

> 
> > +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
> > "-mcpu=power8" } } */
> > +/* { dg-options "-maltivec -O2 -mcpu=power8" } */
> 
> -maltivec is implied by -mcpu=power8 if you do nothing special.
> 
> Similar for the other tests.

Yup, I'll clean those up.  (this and the other submitted patches).
Thanks for the review. :-)

> For all the scan-assembler tests, did you verify these are exactly the
> instructions we want generated?

"want" may be a bit strong, but I do verified that is what we get now.

What I specifically do is compare what we do generate now with what we
end up generating after I attempt some early gimple-folding, and make
sure any changes are equivalent or better.

> Minus the nits, look great, okay for trunk.  Thanks!
> 
> 
> Segher
> 




Re: [PATCH] Optimize sin(atan(x)), take 2

2018-10-10 Thread Jeff Law
On 10/5/18 6:09 AM, Giuliano Augusto Faulin Belinassi wrote:
> Thank you for the review. I will address all these issues :-).
> 
>> Imagine a pause here while I lookup isolation of radicals  It's been
>> a long time...   OK.  Sure.  I see what you're doing here...
> 
> Sorry, but I really did not understand your comment. Should I write a
> shorter comment for that function?
Not at all -- I was just trying to be funny.  I was struggling to
understand the comment  so I tried to recreate the steps necessary to
transform the equation myself.  And quickly realized that it's been 30
years since I've had to do that kind of algebra  :-)

> 
>> Not  sure what you mean for safety reasons.  The calculations to produce
>> "c" then convert it into a REAL_VALUE_TYPE all make sense.  Just not
>> sure what this line is really meant to do.
> 
> Imagine the following case:
> Let "c" be the real constant such that it is certain that for every x
>> "c",  1/sqrt(x*x + 1) = 1.
> Suppose now that our calculation leads us to a c' < "c" due to a minor
> imprecision.
> The logic here is that 10 * c' > "c" and everything will work, thus it is 
> safer.
> Note however that I cannot prove that 10 * c' > "c", but I would be
> really surprised
> if this does not holds.
Ah.  I  understand.  This probably warrants a slightly better comment.

Jeff


Re: [PATCHv2] Handle not explicitly zero terminated strings in merge sections

2018-10-10 Thread Jeff Law
On 10/9/18 6:45 AM, Bernd Edlinger wrote:
> On 10/03/18 18:31, Jeff Law wrote:
>>> -  && (len = int_size_in_bytes (TREE_TYPE (decl))) > 0
>>> -  && TREE_STRING_LENGTH (decl) >= len)
>>> +  && (len = int_size_in_bytes (TREE_TYPE (decl))) >= 0
>>> +  && TREE_STRING_LENGTH (decl) == len)
>> Not sure why you want to test for >= 0 here.  > 0 seems sufficient,
>> though I guess there's no harm in the = 0 case.
>>
> 
> Aehm, cough...
> 
> Sorry Jeff, I need to change that back.  It turns out that
> completely empty strings don't work right, because of this
> check in output_constant:
> 
> output_constant (tree exp, unsigned HOST_WIDE_INT size, unsigned int align,
>   bool reverse, bool merge_strings)
> {
>enum tree_code code;
>unsigned HOST_WIDE_INT thissize;
>rtx cst;
> 
>if (size == 0 || flag_syntax_only)
>  return size;
> 
> So while my intention was to add a null-termination for all strings, 
> including empty ones,
> this does not work for empty strings, which was diagnosed by the solaris 
> assembler/linker.
> 
> However since those empty strings do not use any space, there is no 
> improvement
> by merging them in the first place.
> 
> 
> Rainer bootstrapped the attached patch successfully.
> Is it OK for trunk?
OK.  Funny I almost called out the zero size stuff as being pointless to
bother handling in the first place.  Oh well.

Jeff


Re: [PR 87339, testsuite] Fix failure of gcc.dg/warn-abs-1.c on some targets

2018-10-10 Thread Jeff Law
On 10/10/18 6:35 AM, Martin Jambor wrote:
> Hi,
> 
> On Wed, Oct 10 2018, Christophe Lyon wrote:
>> On 10/10/2018 13:17, Martin Jambor wrote:
>>> Hi,
>>>
>>> On Wed, Sep 26 2018, Joseph Myers wrote:
 On Wed, 26 Sep 2018, Martin Jambor wrote:

> I see, I guess the easiest is to skip the test on targets that do not
> really have long double, although if someone thinks that is too
> restrictive, I can also split the test again and move long double bits
> to a separate test.
 You should be able to use

 { dg-warning "warning regex" "test name" { target { large_long_double } } }

 to make the expectation of a warning conditional without making the whole
 test conditional.
>>> I hoped that Christophe would try this out because I do not have an easy
>>> access to a problematic architecture, but I can at least confirm that
>>> the following still passes on x86_64-linux (and should also pass on
>>> archs without long double, if I understood Joseph well).
>>
>> I did: https://gcc.gnu.org/ml/gcc-patches/2018-09/msg01713.html
>> Sorry if I wasn't explicit enough
> 
> Oh, sorry, I somehow completely missed that.  Thanks for testing then.
> 
>>> @@ -57,7 +57,7 @@ void tst_notcomplex (int *pi, long *pl, long double *pld)
>>>   void tst_cplx_size (complex double *pcd, complex long double *pcld)
>>>   {
>>> *pcd = cabsf (*pcd);   /* { dg-warning "may cause truncation of value" 
>>> } */
>>> -  *pcld = cabs (*pcld);  /* { dg-warning "may cause truncation of value" } 
>>> */
>>> +  *pcld = cabs (*pcld);  /* { /* { dg-warning "may cause truncation of 
>>> value" "cabs trunc" { target {
>>
>> OK for me, except that you have an extra '/*' in the line above.
>>
> 
> Silly me, the fixed patch is below.  OK for trunk?
> 
> Martin
> 
> 
> 2018-10-10  Martin Jambor  
> 
>   testsuite/
>   * gcc.dg/warn-abs-1.c: Guard tests assuming size of long double is
>   greater that the size of double by target large_long double.
OK
jeff


Re: [PATCH, rs6000] testcases for vec_insert

2018-10-10 Thread Segher Boessenkool
Hi!

On Wed, Oct 10, 2018 at 10:14:31AM -0500, Will Schmidt wrote:
>   Add some testcases for verification of vec_insert() codegen.
> The char,float,int,short tests are broken out into -p8 and -p9
> variants due to codegen variations between the platforms.
> 
> Tested across assorted power linux platforms.  OK for trunk?

> +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-insert-char-p8.c

> +/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */

The usual questions wrt lp64 :-)

> +/* { dg-require-effective-target powerpc_p8vector_ok } */
> +/* { dg-options "-maltivec -O2" } */

You say the same thing (and more) two lines later :-)

> +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
> "-mcpu=power8" } } */
> +/* { dg-options "-maltivec -O2 -mcpu=power8" } */

-maltivec is implied by -mcpu=power8 if you do nothing special.

Similar for the other tests.

For all the scan-assembler tests, did you verify these are exactly the
instructions we want generated?

Minus the nits, look great, okay for trunk.  Thanks!


Segher


Re: [PATCH, rs6000] testcase coverage for vec_sel builtins

2018-10-10 Thread Segher Boessenkool
Hi!

On Wed, Oct 10, 2018 at 10:14:21AM -0500, Will Schmidt wrote:
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-select-double.c
> @@ -0,0 +1,22 @@
> +/* Verify that overloaded built-ins for vec_sel with 
> +   double inputs for VSX produce the right code.  */
> +
> +/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */

Why only on lp64?

> +/* { dg-require-effective-target powerpc_p8vector_ok } */
> +/* { dg-options "-mvsx -mpower8-vector -O2" } */

-mpower8-vector implies -mvsx.

> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-select-float.c
> @@ -0,0 +1,22 @@
> +/* Verify that overloaded built-ins for vec_sel with float 
> +   inputs for VSX produce the right code.  */
> +
> +/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */

Why lp64?

Okay for trunk with the lp64's fixed or explained.  Thanks!


Segher


Re: [PATCH, rs6000] early gimple folding for vec_mergee and vec_mergeo intrinsics

2018-10-10 Thread Segher Boessenkool
Hi!

On Wed, Oct 10, 2018 at 10:14:01AM -0500, Will Schmidt wrote:
> 2018-10-09  Will Schmidt 
> 
>   * config/rs6000/rs6000.c: (fold_mergeeo_helper): New helper function.

* config/rs6000/rs6000.c (fold_mergeeo_helper): New helper function.

(i.e. no colon there)

>gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
>gimple_set_location (g, gimple_location (stmt));
>gsi_replace (gsi, g, true);
>  }

An empty line here please.

> +/* Helper function to handle the vector merge[eo] built-ins.
> + * The permute vector contains even or odd values that index
> + * across both arg1 and arg2.  The even/odd-ness is handled via the
> + * shift argument passed in.  */

And no leading stars.  It isn't clear from this what value should be in
the permute vector or the shift variable.  Maybe you shouldn't mention
the vector here at all?  And use a "bool odd" parameter (or "use_odd" like
for mergehl"?

> +  /* The permute_type will match the lhs for integral types.  For double and
> + float types, the permute type needs to map to the V2 or V4 type that
> + matches size.  */
> +  tree permute_type;
> +  if (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type)))
> +permute_type = lhs_type;
> +  else
> +{
> +  if (types_compatible_p (TREE_TYPE (lhs_type),
> +   TREE_TYPE (V2DF_type_node)))
> + permute_type = V2DI_type_node;
> +  else if (types_compatible_p (TREE_TYPE (lhs_type),
> +TREE_TYPE (V4SF_type_node)))
> + permute_type = V4SI_type_node;
> +  else
> + gcc_unreachable ();
> +}

Maybe this stuff should be factored out?  mergehl has similar.

> + /* Build the permute vector.  */
> +  for (int i = 0; i < n_elts / 2; i++)
> +  {
> + elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
> +2*i + shift));
> + elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
> +2*i + shift + n_elts));
> +  }

All the indents are wrong here :-)

  /* Build the permute vector.  */
  for (int i = 0; i < n_elts / 2; i++)
{
  elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
 2*i + shift));
  elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
 2*i + shift + n_elts));
}

> +case P8V_BUILTIN_VMRGEW_V4SI:
> +case P8V_BUILTIN_VMRGEW_V2DI:
> +case P8V_BUILTIN_VMRGEW_V4SF:
> +case P8V_BUILTIN_VMRGEW_V2DF:
> + fold_mergeeo_helper (gsi, stmt, 0);
> +  return true;

The "fold" line should be indented only 6 chars deep, too (it's wrong in
the existing code as well).

Okay for trunk with those things improved.  Thanks!


Segher


[PATCH] Reset insn priority after inc/ref replacement in haifa sched

2018-10-10 Thread Robin Dapp
Hi,

as my last message
(https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00280.html) did not
garner much attention, I'm posting it in proper patch form this time.
The problem I'm trying to solve is that an insn's priority seems
unchanged if the priority of insns that depend on it is changed (and the
first insn's priority was computed by on of these dependent insns'
priority).  If I missed something or there is another way this should be
working, I'd like to learn about that.

A non-bootstrapped test suite run on s390 showed no regressions and an
x86 one is currently running (current HEAD didn't bootstrap for me on
x86). The actual code changes throughout SPEC2006 are minor and the
performance impact is negligible provided we do not hit a fixable bad
case as described in my last message.

Regards
 Robin

--

gcc/ChangeLog:

2018-10-10  Robin Dapp  

* haifa-sched.c (apply_replacement):
Reset insn priority after inc/ref replacement.
commit 69ade62116eecf0a2bdf1cb099158e6d1dca1f3f
Author: Robin Dapp 
Date:   Mon Oct 8 15:26:58 2018 +0200

recompute priority of insn whose dependencies have changed after applying an inc/ref replacement.

diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 1fdc9df9fb2..1a7fe7b78e2 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -4713,7 +4713,21 @@ apply_replacement (dep_t dep, bool immediately)
   success = validate_change (desc->insn, desc->loc, desc->newval, 0);
   gcc_assert (success);
 
+  rtx_insn *insn = DEP_PRO (dep);
+
+  INSN_PRIORITY_STATUS (insn) = -1;
+
+  sd_iterator_def sd_it;
+  sd_it = sd_iterator_start (insn, SD_LIST_FORW);
+  while (sd_iterator_cond (_it, ))
+	{
+	  DEP_COST (dep) = UNKNOWN_DEP_COST;
+	  sd_iterator_next (_it);
+	}
+
+  priority (insn);
   update_insn_after_change (desc->insn);
+
   if ((TODO_SPEC (desc->insn) & (HARD_DEP | DEP_POSTPONED)) == 0)
 	fix_tick_ready (desc->insn);
 


C++ PATCH for c++/87567, constexpr rejects call to non-constexpr function

2018-10-10 Thread Marek Polacek
In this testcase, the call to f() can never be a constant expression, but
that's not a problem because it is never reached.  We handle a similar scenario
for IF_STMT, so we can just do the same.  The RANGE_FOR_STMT case seems to
never be reached in the whole testsuite, so I didn't change that.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-10-10  Marek Polacek  

PR c++/87567 - constexpr rejects call to non-constexpr function.
* constexpr.c (potential_constant_expression_1) : Return
true if the condition is always false.
: Likewise.

* g++.dg/cpp1y/constexpr-loop7.C: New test.

diff --git gcc/cp/constexpr.c gcc/cp/constexpr.c
index 403edda8c47..4fa8c965a9d 100644
--- gcc/cp/constexpr.c
+++ gcc/cp/constexpr.c
@@ -5818,8 +5818,16 @@ potential_constant_expression_1 (tree t, bool want_rval, 
bool strict, bool now,
 case FOR_STMT:
   if (!RECUR (FOR_INIT_STMT (t), any))
return false;
-  if (!RECUR (FOR_COND (t), rval))
+  tmp = FOR_COND (t);
+  if (!RECUR (tmp, rval))
return false;
+  if (tmp)
+   {
+ if (!processing_template_decl)
+   tmp = cxx_eval_outermost_constant_expr (tmp, true);
+ if (integer_zerop (tmp))
+   return true;
+   }
   if (!RECUR (FOR_EXPR (t), any))
return false;
   if (!RECUR (FOR_BODY (t), any))
@@ -5840,8 +5848,13 @@ potential_constant_expression_1 (tree t, bool want_rval, 
bool strict, bool now,
   return true;
 
 case WHILE_STMT:
-  if (!RECUR (WHILE_COND (t), rval))
+  tmp = WHILE_COND (t);
+  if (!RECUR (tmp, rval))
return false;
+  if (!processing_template_decl)
+   tmp = cxx_eval_outermost_constant_expr (tmp, true);
+  if (integer_zerop (tmp))
+   return true;
   if (!RECUR (WHILE_BODY (t), any))
return false;
   if (breaks (jump_target) || continues (jump_target))
diff --git gcc/testsuite/g++.dg/cpp1y/constexpr-loop7.C 
gcc/testsuite/g++.dg/cpp1y/constexpr-loop7.C
index e69de29bb2d..6733820fee2 100644
--- gcc/testsuite/g++.dg/cpp1y/constexpr-loop7.C
+++ gcc/testsuite/g++.dg/cpp1y/constexpr-loop7.C
@@ -0,0 +1,21 @@
+// PR c++/87567
+// { dg-do compile { target c++14 } }
+
+constexpr bool always_false() { return false; }
+int f() { return 1; }
+
+constexpr int
+fn1 ()
+{
+  while (always_false ())
+return f();
+  return 0;
+}
+
+constexpr int
+fn2 ()
+{
+  for (;always_false();)
+return f();
+  return 0;
+}


[PATCH] PR libstdc++/87544 limit max_size() to PTRDIFF_MAX / sizeof(T)

2018-10-10 Thread Jonathan Wakely

The C++17 standard requires the default implementation for
allocator_traits::max_size to return SIZE_MAX / sizeof(value_type).
That causes GCC to warn because the value could be larger than can
sensibly be passed to malloc. This patch changes the new_allocator and
malloc_allocator max_size() members to use PTRDIFF_MAX instead of
SIZE_MAX (and because they define it, the allocator_traits default isn't
used). This also changes vector::max_size to impose a sensible limit
using PTRDIFF_MAX for cases where the value from the allocator or
allocator_traits is not sensible.

PR libstdc++/87544
* include/bits/stl_vector.h (vector::_S_max_size): Limit size to
PTRDIFF_MAX / sizeof(value_type).
* include/ext/malloc_allocator.h (malloc_allocator::max_size):
Likewise.
* include/ext/new_allocator.h (new_allocator::max_size): Likewise.
* testsuite/23_containers/vector/allocator/minimal.cc: Adjust
expected value for max_size().
* testsuite/23_containers/vector/capacity/87544.cc: New test.

Tested x86_64-linux, committed to trunk.

commit 57daf3cdf2668f944417cc4550faec588f83a790
Author: Jonathan Wakely 
Date:   Wed Oct 10 15:23:12 2018 +0100

PR libstdc++/87544 limit max_size() to PTRDIFF_MAX / sizeof(T)

The C++17 standard requires the default implementation for
allocator_traits::max_size to return SIZE_MAX / sizeof(value_type).
That causes GCC to warn because the value could be larger than can
sensibly be passed to malloc. This patch changes the new_allocator and
malloc_allocator max_size() members to use PTRDIFF_MAX instead of
SIZE_MAX (and because they define it, the allocator_traits default isn't
used). This also changes vector::max_size to impose a sensible limit
using PTRDIFF_MAX for cases where the value from the allocator or
allocator_traits is not sensible.

PR libstdc++/87544
* include/bits/stl_vector.h (vector::_S_max_size): Limit size to
PTRDIFF_MAX / sizeof(value_type).
* include/ext/malloc_allocator.h (malloc_allocator::max_size):
Likewise.
* include/ext/new_allocator.h (new_allocator::max_size): Likewise.
* testsuite/23_containers/vector/allocator/minimal.cc: Adjust
expected value for max_size().
* testsuite/23_containers/vector/capacity/87544.cc: New test.

diff --git a/libstdc++-v3/include/bits/stl_vector.h 
b/libstdc++-v3/include/bits/stl_vector.h
index 47856473107..37607417d08 100644
--- a/libstdc++-v3/include/bits/stl_vector.h
+++ b/libstdc++-v3/include/bits/stl_vector.h
@@ -1726,7 +1726,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
   static size_type
   _S_max_size(const _Tp_alloc_type& __a) _GLIBCXX_NOEXCEPT
   {
-   const size_t __diffmax = __gnu_cxx::__numeric_traits::__max;
+   // std::distance(begin(), end()) cannot be greater than PTRDIFF_MAX,
+   // and realistically we can't store more than PTRDIFF_MAX/sizeof(T)
+   // (even if std::allocator_traits::max_size says we can).
+   const size_t __diffmax
+ = __gnu_cxx::__numeric_traits::__max / sizeof(_Tp);
const size_t __allocmax = _Alloc_traits::max_size(__a);
return (std::min)(__diffmax, __allocmax);
   }
diff --git a/libstdc++-v3/include/ext/malloc_allocator.h 
b/libstdc++-v3/include/ext/malloc_allocator.h
index 8739c1fdaa3..8eaf5d44cf7 100644
--- a/libstdc++-v3/include/ext/malloc_allocator.h
+++ b/libstdc++-v3/include/ext/malloc_allocator.h
@@ -139,7 +139,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   size_type
   max_size() const _GLIBCXX_USE_NOEXCEPT 
-  { return size_t(-1) / sizeof(_Tp); }
+  {
+#if __PTRDIFF_MAX__ < __SIZE_MAX__
+   return size_t(__PTRDIFF_MAX__) / sizeof(_Tp);
+#else
+   return size_t(-1) / sizeof(_Tp);
+#endif
+  }
 
 #if __cplusplus >= 201103L
   template
diff --git a/libstdc++-v3/include/ext/new_allocator.h 
b/libstdc++-v3/include/ext/new_allocator.h
index 19e7ad02e75..7c50731736b 100644
--- a/libstdc++-v3/include/ext/new_allocator.h
+++ b/libstdc++-v3/include/ext/new_allocator.h
@@ -130,7 +130,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   size_type
   max_size() const _GLIBCXX_USE_NOEXCEPT
-  { return size_t(-1) / sizeof(_Tp); }
+  {
+#if __PTRDIFF_MAX__ < __SIZE_MAX__
+   return size_t(__PTRDIFF_MAX__) / sizeof(_Tp);
+#else
+   return size_t(-1) / sizeof(_Tp);
+#endif
+  }
 
 #if __cplusplus >= 201103L
   template
diff --git a/libstdc++-v3/testsuite/23_containers/vector/allocator/minimal.cc 
b/libstdc++-v3/testsuite/23_containers/vector/allocator/minimal.cc
index 7a75d9189b2..5e989b0f8c7 100644
--- a/libstdc++-v3/testsuite/23_containers/vector/allocator/minimal.cc
+++ b/libstdc++-v3/testsuite/23_containers/vector/allocator/minimal.cc
@@ -35,7 +35,7 @@ void test01()
   typedef std::vector test_type;
   test_type v(alloc_type{});
   v.push_back(T());
-  VERIFY( v.max_size() == 

Re: [PATCH, rs6000] testcases for vec_mergee and vec_mergeo

2018-10-10 Thread Segher Boessenkool
Hi Will,

On Wed, Oct 10, 2018 at 10:13:48AM -0500, Will Schmidt wrote:
> Some additional testcases to exercise the vec_mergee and
> vec_mergeo intrinsics.
> 
> Tested across assorted power linux platforms.  OK for trunk?

Sure, that looks fine, okay for trunk.  Thanks!  One little thing:

> +/* { dg-do compile } */
> +/* { dg-require-effective-target powerpc_p8vector_ok } */
> +/* { dg-options "-mcpu=power8 -mpower8-vector " } */

-mpower8-vector is redundant with -mcpu=power8.

It's still correct of course, you don't need to change this, just FYI.

Thanks!


Segher


Re: [PATCH, testsuite] memchr-1.c wide char and AIX

2018-10-10 Thread Martin Sebor

On 10/06/2018 04:13 PM, David Edelsohn wrote:

On Fri, Oct 5, 2018 at 5:47 PM Martin Sebor  wrote:


David,

Attached is a patch to conditionalize the memchr-1.c test
to pass even with 2-byte wchar_t's.  It also adds a compile
only test to verify memchr with -fnarrow-wchar.  I verified
the changes on LE x86_64-linux and BE powerpc64-linux but
if you could confirm they also work on AIX that would be
great.


With the patch, the memchr failures on AIX are fixed.



Thanks!  I've checked it in as r265020.

Martin


Re: [PATCH] C++: simplify output from suggest_alternatives_for

2018-10-10 Thread Jason Merrill
On Tue, Oct 9, 2018 at 1:19 PM David Malcolm  wrote:
> + if (!DECL_P (decl)
> + && decl == error_mark_node)

You don't need to check DECL_P here.

Jason


[PATCH, rs6000] vec_extract testcase coverage

2018-10-10 Thread Will Schmidt
Hi,
Testcase coverage for the vec_extract builtins.

Due to codegen differences between (p7,p8,p9) targets, these
have been split into bits and pieces as seen.

Tested across assorted power linux platforms.  OK for trunk?

Thanks,
-Will

[testsuite]

2018-10-09  Will Schmidt  

* gcc.target/powerpc/fold-vec-extract-char.p7.c: New.
* gcc.target/powerpc/fold-vec-extract-char.p8.c: New.
* gcc.target/powerpc/fold-vec-extract-char.p9.c: New.
* gcc.target/powerpc/fold-vec-extract-double.p7.c: New.
* gcc.target/powerpc/fold-vec-extract-double.p8.c: New.
* gcc.target/powerpc/fold-vec-extract-double.p9.c: New.
* gcc.target/powerpc/fold-vec-extract-float.p7.c: New.
* gcc.target/powerpc/fold-vec-extract-float.p8.c: New.
* gcc.target/powerpc/fold-vec-extract-float.p9.c: New.
* gcc.target/powerpc/fold-vec-extract-int.p7.c: New.
* gcc.target/powerpc/fold-vec-extract-int.p8.c: New.
* gcc.target/powerpc/fold-vec-extract-int.p9.c: New.
* gcc.target/powerpc/fold-vec-extract-longlong.p7.c: New.
* gcc.target/powerpc/fold-vec-extract-longlong.p8.c: New.
* gcc.target/powerpc/fold-vec-extract-longlong.p9.c: New.
* gcc.target/powerpc/fold-vec-extract-short.p7.c: New.
* gcc.target/powerpc/fold-vec-extract-short.p8.c: New.
* gcc.target/powerpc/fold-vec-extract-short.p9.c: New.

diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p7.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p7.c
new file mode 100644
index 000..67acfe7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p7.c
@@ -0,0 +1,60 @@
+/* Verify that overloaded built-ins for vec_extract() with char
+   inputs produce the right code with a power7 (BE) target.  */
+
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power7" } } */
+/* { dg-options "-maltivec -mcpu=power7 -O2" } */
+
+// Six tests total. Targeting P7 (BE).
+// P7 variable offset:  addi, li,   stxvw4x, rldicl, add, lbz, (extsb)
+// P7 const offset:   li, addi, stxvw4x,  lbz, (extsb)
+/* one extsb (extend sign-bit) instruction generated for each test against
+   unsigned types */
+
+/* { dg-final { scan-assembler-times {\maddi\M} 6 } } */
+/* { dg-final { scan-assembler-times {\mli\M} 6 } } */
+/* { dg-final { scan-assembler-times {\mstxvw4x\M|\mstvx\M|\mstxv\M} 6 } } */
+/* { dg-final { scan-assembler-times {\mrldicl\M} 3 } } */
+/* { dg-final { scan-assembler-times {\madd\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mlbz\M} 6 } } */
+/* { dg-final { scan-assembler-times {\mextsb\M} 2 } } */
+
+#include 
+
+unsigned char
+testbc_var (vector bool char vbc2, signed int si)
+{
+  return vec_extract (vbc2, si);
+}
+
+signed char
+testsc_var (vector signed char vsc2, signed int si)
+{
+  return vec_extract (vsc2, si);
+}
+
+unsigned char
+testuc_var (vector unsigned char vuc2, signed int si)
+{
+  return vec_extract (vuc2, si);
+}
+
+unsigned char
+testbc_cst (vector bool char vbc2)
+{
+  return vec_extract (vbc2, 12);
+}
+
+signed char
+testsc_cst (vector signed char vsc2)
+{
+  return vec_extract (vsc2, 12);
+}
+
+unsigned char
+testuc_cst (vector unsigned char vuc2)
+{
+  return vec_extract (vuc2, 12);
+}
+
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p8.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p8.c
new file mode 100644
index 000..bfe5d26
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-extract-char.p8.c
@@ -0,0 +1,64 @@
+/* Verify that overloaded built-ins for vec_extract() with char
+   inputs produce the right code with a P8 (LE or BE) target.  */
+
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power8" } } */
+/* { dg-options "-mcpu=power8 -O2" } */
+
+// six tests total. Targeting P8LE / P8BE.
+// P8 LE variable offset: rldicl, subfic, sldi, mtvsrd, xxpermdi, vslo, 
mfvsrd, sradi, (extsb)
+// P8 LE constant offset: vspltb, mfvsrd, rlwinm, (extsb)
+// P8 BE variable offset: sldi, mtvsrd, xxpermdi, vslo, 
mfvsrd, sradi, (extsb)
+// P8 BE constant offset: vspltb, mfvsrd, rlwinm, (extsb)
+
+/* { dg-final { scan-assembler-times {\mrldicl\M} 3 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\msubfic\M} 3 { target { le } } } } */
+/* { dg-final { scan-assembler-times {\msldi\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mmtvsrd\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mxxpermdi\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mvslo\M} 3 } } */
+/* { dg-final { scan-assembler-times {\mmfvsrd\M} 6 } } */
+/* { dg-final { scan-assembler-times {\msradi\M} 3 } } */
+/* 

[PATCH, rs6000] testcases for vec_insert

2018-10-10 Thread Will Schmidt
Hi,
  Add some testcases for verification of vec_insert() codegen.
The char,float,int,short tests are broken out into -p8 and -p9
variants due to codegen variations between the platforms.

Tested across assorted power linux platforms.  OK for trunk?

Thanks
-Will

[testsuite]

2018-10-10  Will Schmidt  

* gcc.target/powerpc/fold-vec-insert-char-p8.c: New.
* gcc.target/powerpc/fold-vec-insert-char-p9.c: New.
* gcc.target/powerpc/fold-vec-insert-double.c: New.
* gcc.target/powerpc/fold-vec-insert-float-p8.c: New.
* gcc.target/powerpc/fold-vec-insert-float-p9.c: New.
* gcc.target/powerpc/fold-vec-insert-int-p8.c: New.
* gcc.target/powerpc/fold-vec-insert-int-p9.c: New.
* gcc.target/powerpc/fold-vec-insert-longlong.c: New.
* gcc.target/powerpc/fold-vec-insert-short-p8.c: New.
* gcc.target/powerpc/fold-vec-insert-short-p9.c: New.

diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-insert-char-p8.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-insert-char-p8.c
new file mode 100644
index 000..1c634c6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-insert-char-p8.c
@@ -0,0 +1,60 @@
+/* Verify that overloaded built-ins for vec_insert () with char
+   inputs produce the right codegen.  */
+
+/* The below contains vec_insert () calls with both variable and constant
+ values.  Only the constant value calls are early-gimple folded, but all
+ are tested for coverage.  */
+
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-maltivec -O2" } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power8" } } */
+/* { dg-options "-maltivec -O2 -mcpu=power8" } */
+
+#include 
+
+vector bool char testub_var (unsigned char x, vector bool char v, signed int i)
+{
+   return vec_insert (x, v, i);
+}
+vector signed char testss_var (signed char x, vector signed char v, signed int 
i)
+{
+   return vec_insert (x, v, i);
+}
+vector unsigned char testsu_var (signed char x, vector unsigned char v, signed 
int i)
+{
+   return vec_insert (x, v, i);
+}
+vector unsigned char testuu_var (unsigned char x, vector unsigned char v, 
signed int i)
+{
+   return vec_insert (x, v, i);
+}
+vector bool char testub_cst  (unsigned char x, vector bool char v)
+{
+   return vec_insert (x, v, 12);
+}
+vector signed char testss_cst  (signed char x, vector signed char v)
+{
+   return vec_insert (x, v, 12);
+}
+vector unsigned char testsu_cst (signed char x, vector unsigned char v)
+{
+   return vec_insert (x, v, 12);
+}
+vector unsigned char testuu_cst (unsigned char x, vector unsigned char v)
+{
+   return vec_insert (x, v, 12);
+}
+
+/* one store per _var test */
+/* { dg-final { scan-assembler-times {\mstvx\M|\mstxvw4x\M} 4 } } */
+/* one store-byte per test */
+/* { dg-final { scan-assembler-times {\mstb\M} 8 } } */
+/* one load per test */
+/* { dg-final { scan-assembler-times {\mlvx\M|\mlxvw4x\M} 8 } } */
+
+/* one lvebx per _cst test.*/
+/* { dg-final { scan-assembler-times {\mlvebx\M} 4 } } */
+/* one vperm per _cst test.*/
+/* { dg-final { scan-assembler-times {\mvperm\M} 4 } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-insert-char-p9.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-insert-char-p9.c
new file mode 100644
index 000..4fb43e1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-insert-char-p9.c
@@ -0,0 +1,57 @@
+/* Verify that overloaded built-ins for vec_insert () with char
+   inputs produce the right codegen.  */
+
+/* The below contains vec_insert () calls with both variable and constant
+ values.  Only the constant value calls are early-gimple folded, but all
+ are tested for coverage.  */
+
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-options "-maltivec -O2" } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power9" } } */
+/* { dg-options "-maltivec -O2 -mcpu=power9" } */
+
+#include 
+
+vector bool char testub_var (unsigned char x, vector bool char v, signed int i)
+{
+   return vec_insert (x, v, i);
+}
+vector signed char testss_var (signed char x, vector signed char v, signed int 
i)
+{
+   return vec_insert (x, v, i);
+}
+vector unsigned char testsu_var (signed char x, vector unsigned char v, signed 
int i)
+{
+   return vec_insert (x, v, i);
+}
+vector unsigned char testuu_var (unsigned char x, vector unsigned char v, 
signed int i)
+{
+   return vec_insert (x, v, i);
+}
+vector bool char testub_cst  (unsigned char x, vector bool char v)
+{
+   return vec_insert (x, v, 12);
+}
+vector signed char testss_cst  (signed char x, vector signed char v)
+{
+   return vec_insert (x, v, 12);
+}
+vector unsigned char testsu_cst (signed char x, vector unsigned char v)
+{
+   return vec_insert 

[PATCH, rs6000] early gimple folding for vec_mergee and vec_mergeo intrinsics

2018-10-10 Thread Will Schmidt
Hi,
  Add support for early gimple folding of the vec_mergee() and vec_mergeo()
intrinsics.

Testcases posted separately.
Tested across assorted power linux platforms.

OK for trunk?

Thanks,
-Will

[gcc]

2018-10-09  Will Schmidt 

* config/rs6000/rs6000.c: (fold_mergeeo_helper): New helper function.
(rs6000_gimple_fold_builtin): Add hooks for vec_mergee and vec_mergeo
intrinsics.

diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 5c7ab2b..a77049e 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -15161,10 +15161,57 @@ fold_mergehl_helper (gimple_stmt_iterator *gsi, 
gimple *stmt, int use_high)
 
   gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
   gimple_set_location (g, gimple_location (stmt));
   gsi_replace (gsi, g, true);
 }
+/* Helper function to handle the vector merge[eo] built-ins.
+ * The permute vector contains even or odd values that index
+ * across both arg1 and arg2.  The even/odd-ness is handled via the
+ * shift argument passed in.  */
+static void
+fold_mergeeo_helper (gimple_stmt_iterator *gsi, gimple *stmt, int shift)
+{
+  tree arg0 = gimple_call_arg (stmt, 0);
+  tree arg1 = gimple_call_arg (stmt, 1);
+  tree lhs = gimple_call_lhs (stmt);
+  tree lhs_type = TREE_TYPE (lhs);
+  int n_elts = TYPE_VECTOR_SUBPARTS (lhs_type);
+
+  /* The permute_type will match the lhs for integral types.  For double and
+ float types, the permute type needs to map to the V2 or V4 type that
+ matches size.  */
+  tree permute_type;
+  if (INTEGRAL_TYPE_P (TREE_TYPE (lhs_type)))
+permute_type = lhs_type;
+  else
+{
+  if (types_compatible_p (TREE_TYPE (lhs_type),
+ TREE_TYPE (V2DF_type_node)))
+   permute_type = V2DI_type_node;
+  else if (types_compatible_p (TREE_TYPE (lhs_type),
+  TREE_TYPE (V4SF_type_node)))
+   permute_type = V4SI_type_node;
+  else
+   gcc_unreachable ();
+}
+  tree_vector_builder elts (permute_type, VECTOR_CST_NELTS (arg0), 1);
+
+ /* Build the permute vector.  */
+  for (int i = 0; i < n_elts / 2; i++)
+  {
+   elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
+  2*i + shift));
+   elts.safe_push (build_int_cst (TREE_TYPE (permute_type),
+  2*i + shift + n_elts));
+  }
+
+  tree permute = elts.build ();
+
+  gimple *g = gimple_build_assign (lhs, VEC_PERM_EXPR, arg0, arg1, permute);
+  gimple_set_location (g, gimple_location (stmt));
+  gsi_replace (gsi, g, true);
+}
 
 /* Fold a machine-dependent built-in in GIMPLE.  (For folding into
a constant, use rs6000_fold_builtin.)  */
 
 bool
@@ -15862,10 +15909,25 @@ rs6000_gimple_fold_builtin (gimple_stmt_iterator *gsi)
 case VSX_BUILTIN_XXMRGHW_4SF:
 case VSX_BUILTIN_VEC_MERGEH_V2DF:
fold_mergehl_helper (gsi, stmt, 0);
return true;
 
+/* Flavors of vec_mergee.  */
+case P8V_BUILTIN_VMRGEW_V4SI:
+case P8V_BUILTIN_VMRGEW_V2DI:
+case P8V_BUILTIN_VMRGEW_V4SF:
+case P8V_BUILTIN_VMRGEW_V2DF:
+   fold_mergeeo_helper (gsi, stmt, 0);
+  return true;
+/* Flavors of vec_mergeo.  */
+case P8V_BUILTIN_VMRGOW_V4SI:
+case P8V_BUILTIN_VMRGOW_V2DI:
+case P8V_BUILTIN_VMRGOW_V4SF:
+case P8V_BUILTIN_VMRGOW_V2DF:
+   fold_mergeeo_helper (gsi, stmt, 1);
+  return true;
+
 /* d = vec_pack (a, b) */
 case P8V_BUILTIN_VPKUDUM:
 case ALTIVEC_BUILTIN_VPKUHUM:
 case ALTIVEC_BUILTIN_VPKUWUM:
   {




[PATCH, rs6000] testcases for vec_mergee and vec_mergeo

2018-10-10 Thread Will Schmidt
Hi,

Some additional testcases to exercise the vec_mergee and
vec_mergeo intrinsics.

Tested across assorted power linux platforms.  OK for trunk?

Thanks
-Will

[testsuite]

2018-10-10  Will Schmidt  

* gcc.target/powerpc/fold-vec-mergeeo-floatdouble.c: New.
* gcc.target/powerpc/fold-vec-mergeeo-int.c: New.
* gcc.target/powerpc/fold-vec-mergeeo-longlong.c: New.

diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-mergeeo-floatdouble.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-mergeeo-floatdouble.c
new file mode 100644
index 000..d711848
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-mergeeo-floatdouble.c
@@ -0,0 +1,46 @@
+/* Verify that overloaded built-ins for vec_splat with float and
+   double inputs produce the right results.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -mpower8-vector " } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power8" } } */
+
+#include 
+
+/*
+   vector float foo = vec_mergee (vector float, vector float);
+   vector float foo = vec_mergeo (vector float, vector float);
+   vector double foo = vec_mergee (vector double , vector double);
+   vector double foo = vec_mergeo (vector double , vector double);
+*/
+
+vector float
+testf_ee (vector float vf1, vector float vf2)
+{
+  return vec_mergee (vf1, vf2);
+}
+
+vector float
+testf_eo (vector float vf1, vector float vf2)
+{
+  return vec_mergeo (vf1, vf2);
+}
+
+vector double
+testd_ee ( vector double vd1, vector double vd2)
+{
+  return vec_mergee (vd1, vd2);
+}
+
+vector double
+testd_eo ( vector double vd1, vector double vd2)
+{
+  return vec_mergeo (vd1, vd2);
+}
+/* Doubles will generate vmrg*w instructions.  */
+/* { dg-final { scan-assembler-times "vmrgow" 1 } } */
+/* { dg-final { scan-assembler-times "vmrgew" 1 } } */
+/* Floats will generate some number of xxpermdi instructions.  Ensure we get 
at least one. */
+/* { dg-final { scan-assembler "xxpermdi" } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-mergeeo-int.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-mergeeo-int.c
new file mode 100644
index 000..565f3ac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-mergeeo-int.c
@@ -0,0 +1,48 @@
+/* Verify that overloaded built-ins for vec_mergee and vec_mergeo with int
+ inputs produce the right codegen.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mpower8-vector -mcpu=power8" } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power8" } } */
+
+#include 
+
+vector bool int
+testbi_ee (vector bool int v1, vector bool int v2)
+{
+  return vec_mergee (v1, v2);
+}
+
+vector signed int
+testsi_ee (vector signed int v1, vector signed int v2)
+{
+  return vec_mergee (v1, v2);
+}
+
+vector unsigned int
+testui_ee (vector unsigned int v1, vector unsigned int v2)
+{
+  return vec_mergee (v1, v2);
+}
+
+vector bool int
+testbi_eo (vector bool int v1, vector bool int v2)
+{
+  return vec_mergeo (v1, v2);
+}
+
+vector signed int
+testsi_eo (vector signed int v1, vector signed int v2)
+{
+  return vec_mergeo (v1, v2);
+}
+
+vector unsigned int
+testui_eo (vector unsigned int v1, vector unsigned int v2)
+{
+  return vec_mergeo (v1, v2);
+}
+/* { dg-final { scan-assembler-times "vmrgew" 3 } } */
+/* { dg-final { scan-assembler-times "vmrgow" 3 } } */
+
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-mergeeo-longlong.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-mergeeo-longlong.c
new file mode 100644
index 000..a5e59bf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-mergeeo-longlong.c
@@ -0,0 +1,52 @@
+/* Verify that overloaded built-ins for vec_mergee and vec_mergeo
+ with long long inputs produce the right codegen.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mpower8-vector -mcpu=power8" } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { 
"-mcpu=power8" } } */
+
+#include 
+
+
+vector bool long long
+testbi_ee (vector bool long long v1, vector bool long long v2)
+{
+  return vec_mergee (v1, v2);
+}
+
+vector bool long long
+testbi_eo (vector bool long long v1, vector bool long long v2)
+{
+  return vec_mergeo (v1, v2);
+}
+
+vector signed long long
+testsi_ee (vector signed long long v1, vector signed long long v2)
+{
+  return vec_mergee (v1, v2);
+}
+
+vector signed long long
+testsi_eo (vector signed long long v1, vector signed long long v2)
+{
+  return vec_mergeo (v1, v2);
+}
+
+vector unsigned long long
+testui_ee (vector unsigned long long v1, vector unsigned long long v2)
+{
+  return vec_mergee (v1, v2);
+}
+
+vector unsigned long long
+testui_eo (vector unsigned long long v1, vector unsigned long long v2)
+{
+  return vec_mergeo (v1, v2);
+}
+
+/* long long ...   */
+/* vec_mergee and 

[PATCH, rs6000] testcase coverage for vec_sel builtins

2018-10-10 Thread Will Schmidt
Hi,
Add testcase coverage for the vec_sel builtins.

Tested across assorted Linux platforms.

OK for trunk?

Thanks,
-Will

[testsuite]

2018-10-10  Will Schmidt  

* gcc.target/powerpc/fold-vec-select-char.c: New.
* gcc.target/powerpc/fold-vec-select-double.c: New.
* gcc.target/powerpc/fold-vec-select-float.c: New.
* gcc.target/powerpc/fold-vec-select-int.c: New.
* gcc.target/powerpc/fold-vec-select-longlong.c: New.
* gcc.target/powerpc/fold-vec-select-short.c: New.

diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-select-char.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-select-char.c
new file mode 100644
index 000..5c82b39
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-select-char.c
@@ -0,0 +1,46 @@
+/* Verify that overloaded built-ins for vec_sel with char
+   inputs produce the right code.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec -O2" } */
+
+#include 
+
+vector bool char
+test1_0 (vector bool char x, vector bool char y, vector bool char z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector bool char
+test1_1 (vector bool char x,vector bool char y, vector unsigned char z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector signed char
+test3_0 (vector signed char x,vector signed char y, vector bool char  z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector signed char
+test3_1 (vector signed char x,vector signed char  y, vector unsigned char z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector unsigned char
+test6_0 (vector unsigned char x,vector unsigned char  y,vector bool char  z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector unsigned char
+test6_1 (vector unsigned char x,vector unsigned char  y, vector unsigned char 
z)
+{
+  return vec_sel (x, y, z);
+}
+
+/* { dg-final { scan-assembler-times {\mxxsel\M|\mvsel\M} 6 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-select-double.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-select-double.c
new file mode 100644
index 000..02ae63a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-select-double.c
@@ -0,0 +1,22 @@
+/* Verify that overloaded built-ins for vec_sel with 
+   double inputs for VSX produce the right code.  */
+
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mvsx -mpower8-vector -O2" } */
+
+#include 
+
+vector double
+test2_0 (vector double x, vector double y, vector bool long long z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector double
+test2_1 (vector double x, vector double y, vector unsigned long z)
+{
+  return vec_sel (x, y, z);
+}
+
+/* { dg-final { scan-assembler-times "xxsel" 2 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-select-float.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-select-float.c
new file mode 100644
index 000..085ba8a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-select-float.c
@@ -0,0 +1,22 @@
+/* Verify that overloaded built-ins for vec_sel with float 
+   inputs for VSX produce the right code.  */
+
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec -O2" } */
+
+#include 
+
+vector float
+test1_0 (vector float x, vector float y, vector bool int z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector float
+test1_1 (vector float x, vector float y, vector unsigned int z)
+{
+  return vec_sel (x, y, z);
+}
+
+/* { dg-final { scan-assembler-times {\mxxsel\M|\mvsel\M} 2 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/fold-vec-select-int.c 
b/gcc/testsuite/gcc.target/powerpc/fold-vec-select-int.c
new file mode 100644
index 000..d62c06d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fold-vec-select-int.c
@@ -0,0 +1,46 @@
+/* Verify that overloaded built-ins for vec_sel with int
+   inputs produce the right code.  */
+
+/* { dg-do compile } */
+/* { dg-require-effective-target powerpc_altivec_ok } */
+/* { dg-options "-maltivec -O2" } */
+
+#include 
+
+vector bool int
+test1_0 (vector bool int x, vector bool int y, vector bool int z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector bool int
+test1_1 (vector bool int x, vector bool int y, vector unsigned int z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector signed int
+test3_0 (vector signed int x, vector signed int y, vector bool int z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector signed int
+test3_1 (vector signed int x, vector signed int y, vector unsigned int z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector unsigned int
+test6_0 (vector unsigned int x, vector unsigned int y, vector bool int z)
+{
+  return vec_sel (x, y, z);
+}
+
+vector unsigned int
+test6_1 (vector unsigned int x, vector unsigned int y, vector unsigned int z)
+{
+  return vec_sel (x, y, z);
+}
+
+/* { dg-final { scan-assembler-times {\mxxsel\M|\mvsel\M} 6 } } */
diff --git 

[PATCH, i386]: Fix PR87573, error: could not split insn

2018-10-10 Thread Uros Bizjak
Existing splitter is not able to split const_vector 0 as
general_operand predicate matches only scalar zeros.

2018-10-10  Uros Bizjak  

PR target/87573
* config/i386/mmx.md (const_vector 0 -> mem splitter): New splitter.

testsuite/ChangeLog:

2018-10-10  Uros Bizjak  

PR target/87573
* gcc.target/i386/pr87573.c: New test.

Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.

Committed to mainline SVN.

Uros.
Index: config/i386/mmx.md
===
--- config/i386/mmx.md  (revision 265018)
+++ config/i386/mmx.md  (working copy)
@@ -217,11 +217,18 @@
 
 (define_split
   [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
-(match_operand:MMXMODE 1 "general_gr_operand"))]
+(match_operand:MMXMODE 1 "nonimmediate_gr_operand"))]
   "!TARGET_64BIT && reload_completed"
   [(const_int 0)]
   "ix86_split_long_move (operands); DONE;")
 
+(define_split
+  [(set (match_operand:MMXMODE 0 "nonimmediate_gr_operand")
+(match_operand:MMXMODE 1 "const0_operand"))]
+  "!TARGET_64BIT && reload_completed"
+  [(const_int 0)]
+  "ix86_split_long_move (operands); DONE;")
+
 (define_expand "movmisalign"
   [(set (match_operand:MMXMODE 0 "nonimmediate_operand")
(match_operand:MMXMODE 1 "nonimmediate_operand"))]
Index: testsuite/gcc.target/i386/pr87573.c
===
--- testsuite/gcc.target/i386/pr87573.c (nonexistent)
+++ testsuite/gcc.target/i386/pr87573.c (working copy)
@@ -0,0 +1,12 @@
+/* PR target/87573 */
+/* { dg-do compile { target ia32 } } */
+/* { dg-options "-O1 -mmmx -mno-sse" } */
+
+typedef char __v8qi __attribute__((vector_size(8)));
+
+__v8qi e;
+
+void f (void)
+{
+  e = (__v8qi) {0, 0, 0, 0, 0, 0, 0, 0};
+}


Re: [PATCHv2] Handle not explicitly zero terminated strings in merge sections

2018-10-10 Thread Rainer Orth
Hi Eric,

>> This isn't necessary on Solaris 11.4, and Solaris 11.3/x86 isn't
>> affected as well.  I'm still determining what the best course of action
>> is: disable string merging support before Solaris 11.4 or enable the
>> workaround above instead.
>
> Out of curiosity, why isn't it necessary on Solaris 11.4?  Is string 
> compression disabled or does it respect alignment on Solaris 11.4?

it's not disabled (I had to disable it when testing an a /bin/as version
with full SHF_MERGE/SHF_STRINGS suppurt recently), so I suspect the
latter.  In S11.4 .rodata and .rodata.str1.8 are merged, with the
alignment of the larger of the two on the output section.

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: [PATCHv2] Handle not explicitly zero terminated strings in merge sections

2018-10-10 Thread Eric Botcazou
> Looking at the .rodata.str1.4 section, I see
> 
> $ objdump -s -j .rodata.str1.8 allocatable_function_5.exe
> 
> allocatable_function_5.exe: file format elf32-sparc-sol2
> 
> Contents of section .rodata.str1.8:
>  10ba8 6d666f6f 2063616c 6c696e67 2000  mfoo calling ...
>  10bb8 666f6f00  6c687300   foo.lhs.
> 
> This string table compression can be disabled with ld -z nocomprstrtab:
> 
>-z nocompstrtab
> 
>Disables the compression of ELF string  tables,  and  comment 
> sec- tions. By default, string compression is applied to SHT_STRTAB sec-
> tions, to SHT_PROGBITS  sections  that  have  their  SHF_MERGE  and
> SHF_STRINGS section flags set, and to comment sections.

Thanks for tracking this down!

> This isn't necessary on Solaris 11.4, and Solaris 11.3/x86 isn't
> affected as well.  I'm still determining what the best course of action
> is: disable string merging support before Solaris 11.4 or enable the
> workaround above instead.

Out of curiosity, why isn't it necessary on Solaris 11.4?  Is string 
compression disabled or does it respect alignment on Solaris 11.4?

-- 
Eric Botcazou


[C++ PATCH] Fix up __has_cpp_attribute (no_unique_address)

2018-10-10 Thread Jakub Jelinek
On Wed, Oct 03, 2018 at 06:05:43PM +0200, Jakub Jelinek wrote:
> On Wed, Oct 03, 2018 at 11:56:15AM -0400, Jason Merrill wrote:
> > --- a/gcc/c-family/c-lex.c
> > +++ b/gcc/c-family/c-lex.c
> > @@ -356,6 +356,8 @@ c_common_has_attribute (cpp_reader *pfile)
> >|| is_attribute_p ("nodiscard", attr_name)
> >|| is_attribute_p ("fallthrough", attr_name))
> > result = 201603;
> > + else if (is_attribute_p ("no_unique_address", attr_name))
> > +   result = 20180312;
> 
> Seems for all other attributes we return either 0, 1 or mm, you return
> here mmdd, is that intentional?  If users think it is mm, then
> they'd read it as December 201803.

Jonathan verified that the value should be 201803, tested on x86_64-linux,
ok for trunk?

2018-10-10  Jakub Jelinek  

* c-lex.c (c_common_has_attribute): Return 201803 instead of 20180312
for no_unique_address.

* g++.dg/cpp2a/feat-cxx2a.C: New test.

--- gcc/c-family/c-lex.c.jj 2018-10-08 15:18:36.665860856 +0200
+++ gcc/c-family/c-lex.c2018-10-10 15:48:46.180923864 +0200
@@ -357,7 +357,7 @@ c_common_has_attribute (cpp_reader *pfil
   || is_attribute_p ("fallthrough", attr_name))
result = 201603;
  else if (is_attribute_p ("no_unique_address", attr_name))
-   result = 20180312;
+   result = 201803;
  if (result)
attr_name = NULL_TREE;
}
--- gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C.jj  2018-10-10 15:52:00.896663247 
+0200
+++ gcc/testsuite/g++.dg/cpp2a/feat-cxx2a.C 2018-10-10 15:52:59.865675782 
+0200
@@ -0,0 +1,447 @@
+// { dg-options "-std=c++2a -I${srcdir}/g++.dg/cpp1y 
-I${srcdir}/g++.dg/cpp1y/testinc" }
+
+//  C++98 features:
+
+#ifndef __cpp_rtti
+#  error "__cpp_rtti"
+#elif  __cpp_rtti != 199711
+#  error "__cpp_rtti != 199711"
+#endif
+
+#ifndef __cpp_exceptions
+#  error "__cpp_exceptions"
+#elif  __cpp_exceptions != 199711
+#  error "__cpp_exceptions != 199711"
+#endif
+
+//  C++11 features:
+
+#ifndef __cpp_raw_strings
+#  error "__cpp_raw_strings"
+#elif __cpp_raw_strings != 200710
+#  error "__cpp_raw_strings != 200710"
+#endif
+
+#ifndef __cpp_unicode_literals
+#  error "__cpp_unicode_literals"
+#elif __cpp_unicode_literals != 200710
+#  error "__cpp_unicode_literals != 200710"
+#endif
+
+#ifndef __cpp_user_defined_literals
+#  error "__cpp_user_defined_literals"
+#elif __cpp_user_defined_literals != 200809
+#  error "__cpp_user_defined_literals != 200809"
+#endif
+
+#ifndef __cpp_lambdas
+#  error "__cpp_lambdas"
+#elif __cpp_lambdas != 200907
+#  error "__cpp_lambdas != 200907"
+#endif
+
+#ifndef __cpp_range_based_for
+#  error "__cpp_range_based_for"
+#elif __cpp_range_based_for != 201603
+#  error "__cpp_range_based_for != 201603"
+#endif
+
+#ifndef __cpp_decltype
+#  error "__cpp_decltype"
+#elif __cpp_decltype != 200707
+#  error "__cpp_decltype != 200707"
+#endif
+
+#ifndef __cpp_attributes
+#  error "__cpp_attributes"
+#elif __cpp_attributes != 200809
+#  error "__cpp_attributes != 200809"
+#endif
+
+#ifndef __cpp_rvalue_references
+#  error "__cpp_rvalue_references"
+#elif __cpp_rvalue_references != 200610
+#  error "__cpp_rvalue_references != 200610"
+#endif
+
+#ifndef __cpp_variadic_templates
+#  error "__cpp_variadic_templates"
+#elif __cpp_variadic_templates != 200704
+#  error "__cpp_variadic_templates != 200704"
+#endif
+
+#ifndef __cpp_initializer_lists
+#  error "__cpp_initializer_lists"
+#elif __cpp_initializer_lists != 200806
+#  error "__cpp_initializer_lists != 200806"
+#endif
+
+#ifndef __cpp_delegating_constructors
+#  error "__cpp_delegating_constructors"
+#elif __cpp_delegating_constructors != 200604
+#  error "__cpp_delegating_constructors != 200604"
+#endif
+
+#ifndef __cpp_nsdmi
+#  error "__cpp_nsdmi"
+#elif __cpp_nsdmi != 200809
+#  error "__cpp_nsdmi != 200809"
+#endif
+
+#ifndef __cpp_inheriting_constructors
+#  error "__cpp_inheriting_constructors"
+#elif  __cpp_inheriting_constructors!= 201511
+#  error "__cpp_inheriting_constructors != 201511"
+#endif
+
+#ifndef __cpp_ref_qualifiers
+#  error "__cpp_ref_qualifiers"
+#elif __cpp_ref_qualifiers != 200710
+#  error "__cpp_ref_qualifiers != 200710"
+#endif
+
+#ifndef __cpp_alias_templates
+#  error "__cpp_alias_templates"
+#elif __cpp_alias_templates != 200704
+#  error "__cpp_alias_templates != 200704"
+#endif
+
+#ifndef __cpp_threadsafe_static_init
+#  error "__cpp_threadsafe_static_init"
+#elif __cpp_threadsafe_static_init != 200806
+#  error "__cpp_threadsafe_static_init != 200806"
+#endif
+
+//  C++14 features:
+
+#ifndef __cpp_binary_literals
+#  error "__cpp_binary_literals"
+#elif __cpp_binary_literals != 201304
+#  error "__cpp_binary_literals != 201304"
+#endif
+
+#ifndef __cpp_init_captures
+#  error "__cpp_init_captures"
+#elif __cpp_init_captures != 201304
+#  error "__cpp_init_captures != 201304"
+#endif
+
+#ifndef __cpp_generic_lambdas

Re: C++ PATCH to implement C++20 P0892R2 - explicit(bool) [v2]

2018-10-10 Thread Marek Polacek
Ping.

On Wed, Oct 03, 2018 at 07:11:37PM -0400, Marek Polacek wrote:
> On Wed, Oct 03, 2018 at 10:24:52AM -0400, Jason Merrill wrote:
> > On Tue, Oct 2, 2018 at 5:25 PM Marek Polacek  wrote:
> > >
> > > On Mon, Oct 01, 2018 at 07:47:10PM -0400, Jason Merrill wrote:
> > > > On Mon, Oct 1, 2018 at 6:41 PM Marek Polacek  wrote:
> > > > >
> > > > > This patch implements C++20 explicit(bool), as described in:
> > > > > .
> > > > >
> > > > > I tried to follow the noexcept specifier implementation where I 
> > > > > could, which
> > > > > made the non-template parts of this fairly easy.  To make 
> > > > > explicit(expr) work
> > > > > with dependent expressions, I had to add DECL_EXPLICIT_SPEC to 
> > > > > lang_decl_fn,
> > > > > which serves as a vessel to get the explicit-specifier to 
> > > > > tsubst_function_decl
> > > > > where I substitute the dependent arguments.
> > > >
> > > > What's the impact of that on memory consumption?  I'm nervous about
> > > > adding another word to most functions when it's not useful to most of
> > > > them.  For several similar things we've been using hash tables on the
> > > > side.
> > >
> > > Yeah, that is a fair concern.  I'm not sure if I know of a good way to 
> > > measure
> > > it.  I took wide-int.ii and ran /usr/bin/time -v ./cc1plus; then it's 
> > > roughly
> > > Maximum resident set size (kbytes): 95020
> > > vs.
> > > Maximum resident set size (kbytes): 95272
> > > which doesn't seem too bad but I don't know if it proves anything.
> > >
> > > If we went with the hash table, would it work like this?
> > > 1) have a hash table mapping decls (key) to explicit-specifiers
> > > 2) instead of setting DECL_EXPLICIT_SPEC put the parsed explicit-specifier
> > >into the table
> > > 3) in tsubst_function_decl look if the fn decl is associated with any
> > >explicit-specifier, if it is, substitute it, and set 
> > > DECL_NONCONVERTING_P
> > >accordingly.
> > 
> > Yes.  I think you want to use tree_cache_map so you don't have to
> > worry about removing entries from the table if the decl is GC'd.
> 
> Done (along with the bit idea).
> 
> > > > > +/* Create a representation of the explicit-specifier with
> > > > > +   constant-expression of EXPR.  COMPLAIN is as for tsubst.  */
> > > > > +
> > > > > +tree
> > > > > +build_explicit_specifier (tree expr, tsubst_flags_t complain)
> > > > > +{
> > > > > +  if (processing_template_decl && value_dependent_expression_p 
> > > > > (expr))
> > > > > +/* Wait for instantiation.  tsubst_function_decl will take care 
> > > > > of it.  */
> > > > > +return expr;
> > > > > +
> > > > > +  expr = perform_implicit_conversion_flags (boolean_type_node, expr,
> > > > > +   complain, LOOKUP_NORMAL);
> > > > > +  expr = instantiate_non_dependent_expr (expr);
> > > > > +  expr = cxx_constant_value (expr);
> > > > > +  return expr;
> > > > > +}
> > > >
> > > > Is there a reason not to use build_converted_constant_expr?
> > >
> > > build_converted_constant_expr doesn't allow narrowing conversions but we 
> > > should
> > > allow them in explicit-specifier which takes "contextually converted 
> > > constant
> > > expression of type bool", much like in
> > >
> > > constexpr int foo () { return 42; }
> > > static_assert (foo());
> > >
> > > Right?
> > 
> > That's what the standard seems to require, but I think that's broken;
> > I cc'd you on my email to the reflector.
> 
> Thanks.  Let's see how that pans; for now I've changed the patch to use
> build_converted_constant_expr and tweaked the tests.
> 
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
> 
> 2018-10-03  Marek Polacek  
> 
>   Implement P0892R2, explicit(bool).
>   * c-cppbuiltin.c (c_cpp_builtins): Define __cpp_explicit_bool.
> 
>   * call.c (add_template_candidate_real): Return if the declaration is
>   explicit and we're only looking for non-converting constructor.
>   * cp-tree.h (lang_decl_fn): Add has_dependent_explicit_spec_p bit.
>   (DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P): New macro.
>   (build_explicit_specifier, store_explicit_specifier): Declare.
>   * decl.c (build_explicit_specifier): New function.
>   * parser.c (cp_parser_decl_specifier_seq): Add explicit_specifier
>   parameter.  Pass it down to cp_parser_function_specifier_opt.
>   (cp_parser_function_specifier_opt): Add explicit_specifier parameter.
>   : Parse C++20 explicit(bool).
>   (cp_parser_explicit_instantiation): Update call to
>   cp_parser_function_specifier_opt.
>   (cp_parser_member_declaration): Have cp_parser_decl_specifier_seq save
>   the explicit-specifier.  Save it using store_explicit_specifier.
>   (cp_parser_single_declaration): Likewise.
>   * pt.c (store_explicit_specifier, lookup_explicit_specifier): New.
>   (tsubst_function_decl): Handle explicit(dependent-expr).
> 
>   * 

Re: [PR 87339, testsuite] Fix failure of gcc.dg/warn-abs-1.c on some targets

2018-10-10 Thread Christophe Lyon
On Wed, 10 Oct 2018 at 14:35, Martin Jambor  wrote:
>
> Hi,
>
> On Wed, Oct 10 2018, Christophe Lyon wrote:
> > On 10/10/2018 13:17, Martin Jambor wrote:
> >> Hi,
> >>
> >> On Wed, Sep 26 2018, Joseph Myers wrote:
> >>> On Wed, 26 Sep 2018, Martin Jambor wrote:
> >>>
>  I see, I guess the easiest is to skip the test on targets that do not
>  really have long double, although if someone thinks that is too
>  restrictive, I can also split the test again and move long double bits
>  to a separate test.
> >>> You should be able to use
> >>>
> >>> { dg-warning "warning regex" "test name" { target { large_long_double } } 
> >>> }
> >>>
> >>> to make the expectation of a warning conditional without making the whole
> >>> test conditional.
> >> I hoped that Christophe would try this out because I do not have an easy
> >> access to a problematic architecture, but I can at least confirm that
> >> the following still passes on x86_64-linux (and should also pass on
> >> archs without long double, if I understood Joseph well).
> >
> > I did: https://gcc.gnu.org/ml/gcc-patches/2018-09/msg01713.html
> > Sorry if I wasn't explicit enough
>
> Oh, sorry, I somehow completely missed that.  Thanks for testing then.
>
> >> @@ -57,7 +57,7 @@ void tst_notcomplex (int *pi, long *pl, long double *pld)
> >>   void tst_cplx_size (complex double *pcd, complex long double *pcld)
> >>   {
> >> *pcd = cabsf (*pcd);   /* { dg-warning "may cause truncation of value" 
> >> } */
> >> -  *pcld = cabs (*pcld);  /* { dg-warning "may cause truncation of value" 
> >> } */
> >> +  *pcld = cabs (*pcld);  /* { /* { dg-warning "may cause truncation of 
> >> value" "cabs trunc" { target {
> >
> > OK for me, except that you have an extra '/*' in the line above.
> >
>
> Silly me, the fixed patch is below.  OK for trunk?
>
OK for me.

> Martin
>
>
> 2018-10-10  Martin Jambor  
>
> testsuite/
> * gcc.dg/warn-abs-1.c: Guard tests assuming size of long double is
> greater that the size of double by target large_long double.
> ---
>  gcc/testsuite/gcc.dg/warn-abs-1.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/gcc/testsuite/gcc.dg/warn-abs-1.c 
> b/gcc/testsuite/gcc.dg/warn-abs-1.c
> index 1c487270042..c016ff620c4 100644
> --- a/gcc/testsuite/gcc.dg/warn-abs-1.c
> +++ b/gcc/testsuite/gcc.dg/warn-abs-1.c
> @@ -43,7 +43,7 @@ void
>  tst_float_size (double *pd, long double *pld)
>  {
>*pd = fabsf (*pd);   /* { dg-warning "may cause truncation of value" } */
> -  *pld = fabs (*pld);  /* { dg-warning "may cause truncation of value" } */
> +  *pld = fabs (*pld);  /* { dg-warning "may cause truncation of value" "fabs 
> trunc" { target { large_long_double } } } */
>*pld = fabs ((double) *pld);
>  }
>
> @@ -57,7 +57,7 @@ void tst_notcomplex (int *pi, long *pl, long double *pld)
>  void tst_cplx_size (complex double *pcd, complex long double *pcld)
>  {
>*pcd = cabsf (*pcd);   /* { dg-warning "may cause truncation of value" } */
> -  *pcld = cabs (*pcld);  /* { dg-warning "may cause truncation of value" } */
> +  *pcld = cabs (*pcld);  /* { dg-warning "may cause truncation of value" 
> "cabs trunc" { target { large_long_double } } } */
>*pcld = cabs ((complex double) *pcld);
>  }
>
> --
> 2.19.0
>


Re: [PR 87339, testsuite] Fix failure of gcc.dg/warn-abs-1.c on some targets

2018-10-10 Thread Martin Jambor
Hi,

On Wed, Oct 10 2018, Christophe Lyon wrote:
> On 10/10/2018 13:17, Martin Jambor wrote:
>> Hi,
>>
>> On Wed, Sep 26 2018, Joseph Myers wrote:
>>> On Wed, 26 Sep 2018, Martin Jambor wrote:
>>>
 I see, I guess the easiest is to skip the test on targets that do not
 really have long double, although if someone thinks that is too
 restrictive, I can also split the test again and move long double bits
 to a separate test.
>>> You should be able to use
>>>
>>> { dg-warning "warning regex" "test name" { target { large_long_double } } }
>>>
>>> to make the expectation of a warning conditional without making the whole
>>> test conditional.
>> I hoped that Christophe would try this out because I do not have an easy
>> access to a problematic architecture, but I can at least confirm that
>> the following still passes on x86_64-linux (and should also pass on
>> archs without long double, if I understood Joseph well).
>
> I did: https://gcc.gnu.org/ml/gcc-patches/2018-09/msg01713.html
> Sorry if I wasn't explicit enough

Oh, sorry, I somehow completely missed that.  Thanks for testing then.

>> @@ -57,7 +57,7 @@ void tst_notcomplex (int *pi, long *pl, long double *pld)
>>   void tst_cplx_size (complex double *pcd, complex long double *pcld)
>>   {
>> *pcd = cabsf (*pcd);   /* { dg-warning "may cause truncation of value" } 
>> */
>> -  *pcld = cabs (*pcld);  /* { dg-warning "may cause truncation of value" } 
>> */
>> +  *pcld = cabs (*pcld);  /* { /* { dg-warning "may cause truncation of 
>> value" "cabs trunc" { target {
>
> OK for me, except that you have an extra '/*' in the line above.
>

Silly me, the fixed patch is below.  OK for trunk?

Martin


2018-10-10  Martin Jambor  

testsuite/
* gcc.dg/warn-abs-1.c: Guard tests assuming size of long double is
greater that the size of double by target large_long double.
---
 gcc/testsuite/gcc.dg/warn-abs-1.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/warn-abs-1.c 
b/gcc/testsuite/gcc.dg/warn-abs-1.c
index 1c487270042..c016ff620c4 100644
--- a/gcc/testsuite/gcc.dg/warn-abs-1.c
+++ b/gcc/testsuite/gcc.dg/warn-abs-1.c
@@ -43,7 +43,7 @@ void
 tst_float_size (double *pd, long double *pld)
 {
   *pd = fabsf (*pd);   /* { dg-warning "may cause truncation of value" } */
-  *pld = fabs (*pld);  /* { dg-warning "may cause truncation of value" } */
+  *pld = fabs (*pld);  /* { dg-warning "may cause truncation of value" "fabs 
trunc" { target { large_long_double } } } */
   *pld = fabs ((double) *pld);
 }
 
@@ -57,7 +57,7 @@ void tst_notcomplex (int *pi, long *pl, long double *pld)
 void tst_cplx_size (complex double *pcd, complex long double *pcld)
 {
   *pcd = cabsf (*pcd);   /* { dg-warning "may cause truncation of value" } */
-  *pcld = cabs (*pcld);  /* { dg-warning "may cause truncation of value" } */
+  *pcld = cabs (*pcld);  /* { dg-warning "may cause truncation of value" "cabs 
trunc" { target { large_long_double } } } */
   *pcld = cabs ((complex double) *pcld);
 }
 
-- 
2.19.0



Re: [PR 87339, testsuite] Fix failure of gcc.dg/warn-abs-1.c on some targets

2018-10-10 Thread Christophe Lyon

On 10/10/2018 13:17, Martin Jambor wrote:

Hi,

On Wed, Sep 26 2018, Joseph Myers wrote:

On Wed, 26 Sep 2018, Martin Jambor wrote:


I see, I guess the easiest is to skip the test on targets that do not
really have long double, although if someone thinks that is too
restrictive, I can also split the test again and move long double bits
to a separate test.

You should be able to use

{ dg-warning "warning regex" "test name" { target { large_long_double } } }

to make the expectation of a warning conditional without making the whole
test conditional.

I hoped that Christophe would try this out because I do not have an easy
access to a problematic architecture, but I can at least confirm that
the following still passes on x86_64-linux (and should also pass on
archs without long double, if I understood Joseph well).


I did: https://gcc.gnu.org/ml/gcc-patches/2018-09/msg01713.html
Sorry if I wasn't explicit enough


OK for trunk?

Thanks,

Martin


2018-10-10  Martin Jambor  

testsuite/
* gcc.dg/warn-abs-1.c: Guard tests assuming size of long double is
greater that the size of double by target large_long double.
---
  gcc/testsuite/gcc.dg/warn-abs-1.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/warn-abs-1.c 
b/gcc/testsuite/gcc.dg/warn-abs-1.c
index 1c487270042..3e8aa72d243 100644
--- a/gcc/testsuite/gcc.dg/warn-abs-1.c
+++ b/gcc/testsuite/gcc.dg/warn-abs-1.c
@@ -43,7 +43,7 @@ void
  tst_float_size (double *pd, long double *pld)
  {
*pd = fabsf (*pd);   /* { dg-warning "may cause truncation of value" } */
-  *pld = fabs (*pld);  /* { dg-warning "may cause truncation of value" } */
+  *pld = fabs (*pld);  /* { dg-warning "may cause truncation of value" "fabs 
trunc" { target { large_long_double } } } */
*pld = fabs ((double) *pld);
  }
  
@@ -57,7 +57,7 @@ void tst_notcomplex (int *pi, long *pl, long double *pld)

  void tst_cplx_size (complex double *pcd, complex long double *pcld)
  {
*pcd = cabsf (*pcd);   /* { dg-warning "may cause truncation of value" } */
-  *pcld = cabs (*pcld);  /* { dg-warning "may cause truncation of value" } */
+  *pcld = cabs (*pcld);  /* { /* { dg-warning "may cause truncation of value" "cabs 
trunc" { target {


OK for me, except that you have an extra '/*' in the line above.

Christophe


large_long_double } } } */
*pcld = cabs ((complex double) *pcld);
  }
  





Re: LTO dump tool

2018-10-10 Thread Martin Liška
On 10/4/18 3:37 PM, Hrishikesh Kulkarni wrote:
> Hi,
> 
> Please find the patch for LTO dump tool attached herewith.
> 
> Regards,
> 
> Hrishikesh
> 

Hello.

Thank you for working on that as GSoC student and I hope we can get the patch
into GCC 9.1 release. However I have first bunch of comments what would be
nice to address:

- please rebase the patch as there are some changes in dumpfile.c that conflict
with your patch
- you smashed quite some whitespaces, particularly you replaced '\t' with '  ' 
at places like this:

@@ -2438,7 +214,7 @@ stream_out (char *temp_filename, lto_symtab_encoder_t 
encoder,
   int i;
   do_stream_out (temp_filename, encoder, part);
   for (i = 0; i < nruns; i++)
-   wait_for_child ();
+  wait_for_child ();
 }
   asm_nodes_output = true;
 #else

and very many other places

- you came up with gcc/lto/lto-common.c - it would be more readable if you do 
no-op patch
that will do the refactoring and then second part will implement the lto-dump 
functionality
on top of it

- I see some compilation errors:

g++ -fno-PIE -c   -g -O2 -DIN_GCC -fno-exceptions -fno-rtti 
-fasynchronous-unwind-tables -W -Wall -Wno-narrowing -Wwrite-strings 
-Wcast-qual -Wmissing-format-attribute -Woverloaded-virtual -pedantic 
-Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fno-common  
-DHAVE_CONFIG_H -I. -Ilto -I/home/marxin/Programming/gcc/gcc 
-I/home/marxin/Programming/gcc/gcc/lto 
-I/home/marxin/Programming/gcc/gcc/../include 
-I/home/marxin/Programming/gcc/gcc/../libcpp/include  
-I/home/marxin/Programming/gcc/gcc/../libdecnumber 
-I/home/marxin/Programming/gcc/gcc/../libdecnumber/bid -I../libdecnumber 
-I/home/marxin/Programming/gcc/gcc/../libbacktrace   -o lto/lto-dump.o -MT 
lto/lto-dump.o -MMD -MP -MF lto/.deps/lto-dump.TPo 
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c: In member function ‘virtual 
void symbol_entry::dump()’:
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c:64:13: warning: '0' flag 
ignored with precision and ‘%u’ gnu_printf format [-Wformat=]
 printf ("%s  %s  %0.4zu  %s  ", type_name, visibility, sz, name);
 ^~
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c: In function ‘int 
size_compare(const void*, const void*)’:
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c:123:41: warning: cast from type 
‘const void*’ to type ‘symbol_entry**’ casts away qualifiers [-Wcast-qual]
   symbol_entry *e1 = *(symbol_entry **) a;
 ^
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c:124:41: warning: cast from type 
‘const void*’ to type ‘symbol_entry**’ casts away qualifiers [-Wcast-qual]
   symbol_entry *e2 = *(symbol_entry **) b;
 ^
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c: In function ‘int 
name_compare(const void*, const void*)’:
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c:133:41: warning: cast from type 
‘const void*’ to type ‘symbol_entry**’ casts away qualifiers [-Wcast-qual]
   symbol_entry *e1 = *(symbol_entry **) a;
 ^
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c:134:41: warning: cast from type 
‘const void*’ to type ‘symbol_entry**’ casts away qualifiers [-Wcast-qual]
   symbol_entry *e2 = *(symbol_entry **) b;
 ^
In file included from /home/marxin/Programming/gcc/gcc/lto/lto-dump.c:32:
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c: In function ‘void 
dump_symbol()’:
/home/marxin/Programming/gcc/gcc/cgraph.h:2665:4: warning: this ‘for’ clause 
does not guard... [-Wmisleading-indentation]
for ((node) = symtab->first_symbol (); (node); (node) = (node)->next)
^~~
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c:215:3: note: in expansion of 
macro ‘FOR_EACH_SYMBOL’
   FOR_EACH_SYMBOL (node)
   ^~~
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c:222:5: note: ...this statement, 
but the latter is misleadingly indented as if it were guarded by the ‘for’
 if (!flag)
 ^~
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c: In function ‘void lto_main()’:
/home/marxin/Programming/gcc/gcc/lto/lto-dump.c:296:13: error: cannot convert 
‘bool’ to ‘timer*’ in assignment
   g_timer = false;
 ^

Thanks,
Martin


Re: [PATCHv2] Handle not explicitly zero terminated strings in merge sections

2018-10-10 Thread Rainer Orth
Hi Eric,

>> Which version exactly (pkg list entire) of Solaris 11 are you running?
>> I'm using gas 2.31 and /bin/ld on Solaris 11.4 resp. 11.5 Beta, where
>> Bernd's patch in PR bootstrap/87551 fixed the remaining regressions.
>
> Solaris 11.3 with Gas 2.30.

I could now reproduce the regressions on Solaris 11.3 SRU 35.6 (the
latest and last 11.3 update), e.g.

+FAIL: gfortran.dg/allocatable_function_5.f90   -O1  execution test


Program received signal SIGBUS: Access to an undefined portion of a memory 
object.

Backtrace for this error:

Thread 2 received signal SIGSEGV, Segmentation fault.
[Switching to Thread 1 (LWP 1)]
0x00010fe0 in foo (_carg=12, carg=..., .__result=0x215d4 , 
__result=)
at 
/vol/gcc/src/hg/trunk/local/gcc/testsuite/gfortran.dg/allocatable_function_5.f90:41
41  res = carg(1:3)
(gdb) where
#0  0x00010fe0 in foo (_carg=12, carg=..., .__result=0x215d4 , 
__result=)
at 
/vol/gcc/src/hg/trunk/local/gcc/testsuite/gfortran.dg/allocatable_function_5.f90:41
#1  MAIN__ ()
at 
/vol/gcc/src/hg/trunk/local/gcc/testsuite/gfortran.dg/allocatable_function_5.f90:22

1: x/i $pc
=> 0x10fe0 : lduh  [ %g1 + 0x3a9 ], %g1
(gdb) p/x $g1
$1 = 0x10800

(gdb) x/7i MAIN__
   0x10fc8 :save  %sp, -104, %sp
   0x10fcc :  call  0x213c4 
   0x10fd0 :  mov  3, %o0
   0x10fd4 : mov  %o0, %i5
   0x10fd8 : sethi  %hi(0x10800), %g1
   0x10fdc : or  %g1, 0x3a9, %g2 ! 0x10ba9
=> 0x10fe0 : lduh  [ %g1 + 0x3a9 ], %g1

(gdb) x/s 0x10800+0x3a9
0x10ba9:'foo calling \000'

Looking at the .rodata.str1.4 section, I see

$ objdump -s -j .rodata.str1.8 allocatable_function_5.exe

allocatable_function_5.exe: file format elf32-sparc-sol2

Contents of section .rodata.str1.8:
 10ba8 6d666f6f 2063616c 6c696e67 2000  mfoo calling ...
 10bb8 666f6f00  6c687300   foo.lhs.

This string table compression can be disabled with ld -z nocomprstrtab:

   -z nocompstrtab

   Disables the compression of ELF string  tables,  and  comment  sec-
   tions. By default, string compression is applied to SHT_STRTAB sec-
   tions, to SHT_PROGBITS  sections  that  have  their  SHF_MERGE  and
   SHF_STRINGS section flags set, and to comment sections.

This isn't necessary on Solaris 11.4, and Solaris 11.3/x86 isn't
affected as well.  I'm still determining what the best course of action
is: disable string merging support before Solaris 11.4 or enable the
workaround above instead.

sparc-sun-solaris2.11 and i386-pc-solaris2.11 bootstraps with
LD_OPTIONS='-z nocompstrtab' are currently running to check if this
fixes all regressions.

Rainer

-- 
-
Rainer Orth, Center for Biotechnology, Bielefeld University


Re: [PATCH] GCOV: introduce --json-format.

2018-10-10 Thread Martin Liška
Hi.

I'm sending updated version of the patch. I made a research and it looks that
actually any significant consumer of GCOV does not use intermediate format:

https://github.com/gcovr/gcovr/issues/282
https://github.com/linux-test-project/lcov/issues/43
https://github.com/mozilla/grcov/issues/55

That said I made following changes:
- I removed current int. format and replaced that with JSON format
- documentation for the format is enhanced
- JSON files are generated by default gzipped

Patch survives gcov.exp tests.

Martin
>From 94ea33a43e93aa76fdfe2b3b672589342296c2fb Mon Sep 17 00:00:00 2001
From: marxin 
Date: Wed, 26 Sep 2018 16:13:25 +0200
Subject: [PATCH] GCOV: introduce --json-format.

gcc/ChangeLog:

2018-10-10  Martin Liska  

	* Makefile.in: Make dependency to json.o.
	* doc/gcov.texi: Document new JSON format, remove
	old intermediate format documentation.
	* gcov.c (struct function_info): Come up with m_name and
	m_demangled_name.
	(function_info::function_info): Initialize it.
	(function_info::~function_info): Release it.
	(main): Rename flag_intermediate_format to flag_json_format.
	(print_usage): Describe --json-format.
	(process_args): Set flag_json_format.
	(output_intermediate_line): Remove.
	(output_intermediate_json_line): Likewise.
	(get_gcov_intermediate_filename): Return new extension
	".gcov.json.gz".
	(output_intermediate_file): Implement JSON emission.
	(output_json_intermediate_file): Implement JSON emission.
	(generate_results): Use ::get_name for function name.
	Handle JSON output file.
	(read_graph_file): Use ::get_name instead of cplus_demangle.
	(read_count_file): Likewise.
	(solve_flow_graph): Likewise.
	(add_line_counts): Likewise.
	(accumulate_line_counts): Use new flag_json_format.
	(output_function_details): Use ::get_name instead of cplus_demangle.
	(output_lines): Likewise.
	* json.cc (test_writing_literals): Add new tests.
	* json.h (class literal): Add new boolean constructor.

gcc/testsuite/ChangeLog:

2018-10-10  Martin Liska  

	* g++.dg/gcov/gcov-8.C: Do not check intermediate format.
	* lib/gcov.exp: Remove legacy verify-intermediate.
---
 gcc/Makefile.in|   7 +-
 gcc/doc/gcov.texi  | 193 +
 gcc/gcov.c | 260 +
 gcc/json.cc|   3 +
 gcc/json.h |   3 +
 gcc/testsuite/g++.dg/gcov/gcov-8.C |   4 +-
 gcc/testsuite/lib/gcov.exp |  55 --
 7 files changed, 294 insertions(+), 231 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 116ed6ea8a5..908aa90c285 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2910,10 +2910,13 @@ s-iov: build/gcov-iov$(build_exeext) $(BASEVER) $(DEVPHASE)
 	$(SHELL) $(srcdir)/../move-if-change tmp-gcov-iov.h gcov-iov.h
 	$(STAMP) s-iov
 
-GCOV_OBJS = gcov.o
+# gcov.o needs $(ZLIBINC) added to the include flags.
+CFLAGS-gcov.o += $(ZLIBINC)
+
+GCOV_OBJS = gcov.o json.o
 gcov$(exeext): $(GCOV_OBJS) $(LIBDEPS)
 	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_OBJS) \
-		hash-table.o ggc-none.o $(LIBS) -o $@
+		hash-table.o ggc-none.o $(LIBS) $(ZLIB) -o $@
 GCOV_DUMP_OBJS = gcov-dump.o
 gcov-dump$(exeext): $(GCOV_DUMP_OBJS) $(LIBDEPS)
 	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) $(GCOV_DUMP_OBJS) \
diff --git a/gcc/doc/gcov.texi b/gcc/doc/gcov.texi
index 3b1b38aebfa..8046fd78e35 100644
--- a/gcc/doc/gcov.texi
+++ b/gcc/doc/gcov.texi
@@ -124,7 +124,7 @@ gcov [@option{-v}|@option{--version}] [@option{-h}|@option{--help}]
  [@option{-c}|@option{--branch-counts}]
  [@option{-d}|@option{--display-progress}]
  [@option{-f}|@option{--function-summaries}]
- [@option{-i}|@option{--intermediate-format}]
+ [@option{-i}|@option{--json-format}]
  [@option{-j}|@option{--human-readable}]
  [@option{-k}|@option{--use-colors}]
  [@option{-l}|@option{--long-file-names}]
@@ -181,79 +181,142 @@ Display help about using @command{gcov} (on the standard output), and
 exit without doing any further processing.
 
 @item -i
-@itemx --intermediate-format
-Output gcov file in an easy-to-parse intermediate text format that can
-be used by @command{lcov} or other tools. The output is a single
-@file{.gcov} file per @file{.gcda} file. No source code is required.
+@itemx --json-format
+Output gcov file in an easy-to-parse JSON intermediate format
+which does not require source code for generation.  The JSON
+file is compressed with gzip compression algorithm
+and the files have @file{.gcov.json.gz} extension.
 
-The format of the intermediate @file{.gcov} file is plain text with
-one entry per line
+Structure of the JSON is following:
 
 @smallexample
-version:@var{gcc_version}
-cwd:@var{working_directory}
-file:@var{source_file_name}
-function:@var{start_line_number},@var{end_line_number},@var{execution_count},@var{function_name}
-lcount:@var{line number},@var{execution_count},@var{has_unexecuted_block}
-branch:@var{line_number},@var{branch_coverage_type}
-

Re: C++ PATCH to implement P1064R0, Virtual Function Calls in Constant Expressions (v4)

2018-10-10 Thread Jakub Jelinek
On Mon, Oct 08, 2018 at 03:36:18PM +0200, Andreas Schwab wrote:
> This still doesn't fix the tests.

Sure, one needs to add the constexpr virtual calls for ia64 as I said in the
mail.

Jakub


[gomp5] Fix task reduction VLA handling

2018-10-10 Thread Jakub Jelinek
Hi!

This patch adds testcases to cover the case when C/C++ array task reductions
are used with VLAs, either whole VLAs or array sections from them.

Tested on x86_64-linux, committed to gomp-5_0-branch.

2018-10-10  Jakub Jelinek  

* omp-low.c (lower_rec_input_clauses): Handle VLAs properly.
(lower_omp_task_reductions): Likewise.
* gimplify.c (enum omp_region_type): Add ORT_TASKGROUP.
(gimple_add_tmp_var, omp_firstprivatize_variable, omp_notice_variable,
omp_is_private, omp_check_private, gimplify_omp_depend): Handle
ORT_TASKGROUP like ORT_WORKSHARE.
(omp_add_variable): Don't add private/firstprivate for VLAs in
ORT_TASKGROUP.
(gimplify_expr) : Move handling into a separate
case, make sure to scan omp clauses before gimplifying body.

* testsuite/libgomp.c-c++-common/task-reduction-5.c (size_t): New
typedef.
(bar): Use it instead of __SIZE_TYPE__ directly.
(foo): Likewise.  Use (~(size_t) 0) instead of __SIZE_MAX__.
* testsuite/libgomp.c/task-reduction-1.c: New test.
* testsuite/libgomp.c++/task-reduction-7.C: New test.

--- gcc/omp-low.c.jj2018-10-09 14:19:54.672380754 +0200
+++ gcc/omp-low.c   2018-10-09 17:56:27.620900824 +0200
@@ -3909,7 +3909,10 @@ lower_rec_input_clauses (tree clauses, g
  if (TREE_CODE (orig_var) == INDIRECT_REF)
x = build_simple_mem_ref (x);
  else if (TREE_CODE (orig_var) == ADDR_EXPR)
-   x = build_fold_addr_expr (x);
+   {
+ if (var == TREE_OPERAND (orig_var, 0))
+   x = build_fold_addr_expr (x);
+   }
  bias = fold_convert (sizetype, bias);
  x = fold_convert (ptr_type_node, x);
  x = fold_build2_loc (clause_loc, POINTER_PLUS_EXPR,
@@ -6798,6 +6801,7 @@ lower_omp_task_reductions (omp_context *
var = TREE_OPERAND (var, 0);
  else if (TREE_CODE (var) == INDIRECT_REF)
var = TREE_OPERAND (var, 0);
+ tree orig_var = var;
  if (is_variable_sized (var))
{
  gcc_assert (DECL_HAS_VALUE_EXPR_P (var));
@@ -6807,7 +6811,9 @@ lower_omp_task_reductions (omp_context *
  gcc_assert (DECL_P (var));
}
  t = ref = maybe_lookup_decl_in_outer_ctx (var, ctx);
- if (TREE_CODE (v) == ADDR_EXPR)
+ if (orig_var != var)
+   gcc_assert (TREE_CODE (v) == ADDR_EXPR);
+ else if (TREE_CODE (v) == ADDR_EXPR)
t = build_fold_addr_expr (t);
  else if (TREE_CODE (v) == INDIRECT_REF)
t = build_fold_indirect_ref (t);
--- gcc/gimplify.c.jj   2018-10-09 14:13:25.243928507 +0200
+++ gcc/gimplify.c  2018-10-10 11:55:27.444973925 +0200
@@ -122,6 +122,7 @@ enum gimplify_omp_var_data
 enum omp_region_type
 {
   ORT_WORKSHARE = 0x00,
+  ORT_TASKGROUP = 0x01,
   ORT_SIMD = 0x04,
 
   ORT_PARALLEL = 0x08,
@@ -759,6 +760,7 @@ gimple_add_tmp_var (tree tmp)
  struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
  while (ctx
 && (ctx->region_type == ORT_WORKSHARE
+|| ctx->region_type == ORT_TASKGROUP
 || ctx->region_type == ORT_SIMD
 || ctx->region_type == ORT_ACC))
ctx = ctx->outer_context;
@@ -6674,6 +6676,7 @@ omp_firstprivatize_variable (struct gimp
omp_add_variable (ctx, decl, GOVD_MAP | GOVD_MAP_TO_ONLY);
}
   else if (ctx->region_type != ORT_WORKSHARE
+  && ctx->region_type != ORT_TASKGROUP
   && ctx->region_type != ORT_SIMD
   && ctx->region_type != ORT_ACC
   && !(ctx->region_type & ORT_TARGET_DATA))
@@ -6787,7 +6790,7 @@ omp_add_variable (struct gimplify_omp_ct
 replacement is private, else FIRSTPRIVATE since we'll need the
 address of the original variable either for SHARED, or for the
 copy into or out of the context.  */
-  if (!(flags & GOVD_LOCAL))
+  if (!(flags & GOVD_LOCAL) && ctx->region_type != ORT_TASKGROUP)
{
  if (flags & GOVD_MAP)
nflags = GOVD_MAP | GOVD_MAP_TO_ONLY | GOVD_EXPLICIT;
@@ -7316,6 +7319,7 @@ omp_notice_variable (struct gimplify_omp
   if (n == NULL)
 {
   if (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_TASKGROUP
  || ctx->region_type == ORT_SIMD
  || ctx->region_type == ORT_ACC
  || (ctx->region_type & ORT_TARGET_DATA) != 0)
@@ -7437,6 +7441,7 @@ omp_is_private (struct gimplify_omp_ctx
 }
 
   if (ctx->region_type != ORT_WORKSHARE
+  && ctx->region_type != ORT_TASKGROUP
   && ctx->region_type != ORT_SIMD
   && ctx->region_type != ORT_ACC)
 return false;
@@ -7494,6 +7499,7 @@ omp_check_private (struct gimplify_omp_c
}
  

Re: [PR 87339, testsuite] Fix failure of gcc.dg/warn-abs-1.c on some targets

2018-10-10 Thread Martin Jambor
Hi,

On Wed, Sep 26 2018, Joseph Myers wrote:
> On Wed, 26 Sep 2018, Martin Jambor wrote:
>
>> I see, I guess the easiest is to skip the test on targets that do not
>> really have long double, although if someone thinks that is too
>> restrictive, I can also split the test again and move long double bits
>> to a separate test.
>
> You should be able to use
>
> { dg-warning "warning regex" "test name" { target { large_long_double } } }
>
> to make the expectation of a warning conditional without making the whole 
> test conditional.

I hoped that Christophe would try this out because I do not have an easy
access to a problematic architecture, but I can at least confirm that
the following still passes on x86_64-linux (and should also pass on
archs without long double, if I understood Joseph well).

OK for trunk?

Thanks,

Martin


2018-10-10  Martin Jambor  

testsuite/
* gcc.dg/warn-abs-1.c: Guard tests assuming size of long double is
greater that the size of double by target large_long double.
---
 gcc/testsuite/gcc.dg/warn-abs-1.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/warn-abs-1.c 
b/gcc/testsuite/gcc.dg/warn-abs-1.c
index 1c487270042..3e8aa72d243 100644
--- a/gcc/testsuite/gcc.dg/warn-abs-1.c
+++ b/gcc/testsuite/gcc.dg/warn-abs-1.c
@@ -43,7 +43,7 @@ void
 tst_float_size (double *pd, long double *pld)
 {
   *pd = fabsf (*pd);   /* { dg-warning "may cause truncation of value" } */
-  *pld = fabs (*pld);  /* { dg-warning "may cause truncation of value" } */
+  *pld = fabs (*pld);  /* { dg-warning "may cause truncation of value" "fabs 
trunc" { target { large_long_double } } } */
   *pld = fabs ((double) *pld);
 }
 
@@ -57,7 +57,7 @@ void tst_notcomplex (int *pi, long *pl, long double *pld)
 void tst_cplx_size (complex double *pcd, complex long double *pcld)
 {
   *pcd = cabsf (*pcd);   /* { dg-warning "may cause truncation of value" } */
-  *pcld = cabs (*pcld);  /* { dg-warning "may cause truncation of value" } */
+  *pcld = cabs (*pcld);  /* { /* { dg-warning "may cause truncation of value" 
"cabs trunc" { target { large_long_double } } } */
   *pcld = cabs ((complex double) *pcld);
 }
 
-- 
2.19.0



Re: [PATCH] Remove dead functions and fix VMS target by moving back some functions.

2018-10-10 Thread Martin Jambor
Hi,

On Wed, Oct 10 2018, Martin Liška wrote:
> On 10/9/18 10:34 PM, Martin Jambor wrote:
>> On Tue, Oct 09 2018, Martin Liška wrote:
>>> * ipa-cp.c (ipcp_vr_lattice::meet_with): Likewise.
>> 
>> Interesting, I believe that a class representing a lattice should have a
>> meet function with its own type.
>
> I've just tried to put gcc_unreachable there, but can't find anything that
> would trigger an ICE.

Well, I was not saying it is not unused, I was just wondering how that
happened.  And after having another look, the answer is that the caller
needs to decide which data to meet according to the return value of
ipa_vr_operation_and_type_effects and so the call to
ipa_vr_operation_and_type_effects cannot be nicely moved into the meet
function, even though that's where seems to belong.

So I guess removing this meet overload is OK, even though strange.

Martin


Re: [patch] new API for value_range

2018-10-10 Thread Richard Biener
On Tue, Oct 9, 2018 at 6:23 PM Aldy Hernandez  wrote:
>
> I'm assuming the silence on the RFC means nobody is viscerally opposed
> to it, so here goes the actual implementation ;-).
>
> FWI: https://gcc.gnu.org/ml/gcc-patches/2018-10/msg00157.html
>
> My aim is no change to the current functionality, but there are some
> things that changed slightly (with no appreciable change in
> bootstrapability or tests).
>
> 1.  Primarily, we were building value_ranges by modifying them in-flight
> with no regards to the validity of the resulting range.  By enforcing
> the API, I noticed we periodically built VR_VARYING / VR_UNDEFINED, but
> left the equivalence bits uncleared.  This comment in the original
> header file indicates that this is invalid behavior:
>
>/* Set of SSA names whose value ranges are equivalent to this one.
>   This set is only valid when TYPE is VR_RANGE or VR_ANTI_RANGE.  */
>
> The API now enforces this upon construction.
>
> 2. I also saw us setting min/max when VARYING or UNDEFINED was set.
> This is invalid.  Although these values were being ignored, the API now
> enforces this.
>
> 3. I saw one case in set_value_range_with_overflow() were we were
> building an invalid range with swapped ranges, where we were silently
> depending on somebody further up the call chain to swap them for us.
> I've fixed this at creation.
>
> 4. There is one assert in ipcp_vr_lattice which I hope to remove, but
> left as proof that the original VR_UNDEFINED set was not necessary, as
> it is now done by default on an empty constructor:
>
> -  void init () { m_vr.type = VR_UNDEFINED; }
> +  void init () { gcc_assert (m_vr.undefined_p ()); }
>
> One last note.  The file tree-vrp.c already has a cripple API of sorts
> in the form of functions (set_value_range_to_varying, etc).  I have
> tried to keep those functions available, by calling the API under the
> covers, but would be okay in removing them altogether as a follow-up.
>
> Please refer to the RFC wrt the min/max/vrtype accessors, as well as the
> new tree type field.
>
> I am quoting the class declaration below to make it easy to review at a
> high level.
>
> Tested on x86-64 Linux.  All languages, including Ada and Go.
>
> OK for trunk?

Reviewing in patch order.

> Aldy
>
> class GTY((for_user)) value_range
> {
>   public:
>value_range ();
>value_range (tree type);
>value_range (value_range_type, tree type, tree, tree, bitmap = NULL);
>bool operator== (const value_range &) const;
>bool operator!= (const value_range &) const;
>void intersect (const value_range *);
>void union_ (const value_range *);

with trailing underscore?  seriously?

>/* Like operator== but ignore equivalence bitmap.  */
>bool ignore_equivs_equal_p (const value_range &) const;
>/* Like a operator= but update equivalence bitmap efficiently.  */
>void copy_with_equiv_update (const value_range *);
>
>/* Types of value ranges.  */
>bool undefined_p () const;
>bool varying_p () const;
>bool symbolic_p () const;
>bool numeric_p () const;
>void set_undefined (tree = NULL);
>void set_varying (tree = NULL);

I'd appreciate comments on those predicates, esp. as you
replace positive tests by negative ones like in

   /* If we found any usable VR, set the VR to ssa_name and create a
  PUSH old value in the stack with the old VR.  */
-  if (vr.type == VR_RANGE || vr.type == VR_ANTI_RANGE)
+  if (!vr.undefined_p () && !vr.varying_p ())
 {

I'd also spell numeric_p as constant_p or drop it alltogether
since !symbolic_p should imply it given varying_p and undefined_p
are just some special-cases of "numeric_p" (full and empty range).

That said, for the time being I'd use non_symbolic_range_or_anti_range_p
instead of numeric_p () (seeing that you maybe want to hide the fact
that we have anti-ranges?)

-  value_range vr = VR_INITIALIZER;
+  value_range vr (TREE_TYPE (name));

so you basically forgo with the fact that empty ranges are universal?
I don't like it too much that we have to invent a type here.  Why enforce this
and not allow/force type == NULL_TREE for empty ranges?

One could argue VARYING is also universal to some extent and useful
only with context, so similar argument applies to your change forcing
a type for set_value_range_to_varying.

-  value_range vr = VR_INITIALIZER;
+  value_range vr;

oh, so you do have a default constructor.

>
>/* Equivalence bitmap methods.  */
>bitmap equiv () const;
>void set_equiv (bitmap);

Err, I think we've settled on _not_ wrapping all member accesses
with get/set methods, didn't we?  I personally dislike that very much.

>void equiv_free ();
>void equiv_copy (const value_range *);
>void equiv_clear ();
>void equiv_and (const value_range *);
>void equiv_ior (const value_range *);

Likewise I find this useless abstraction.  It's even questionable
if _free/_clear/_copy are good APIs here.  This should be all
hidden in 

Re: [PATCH] Remove dead functions and fix VMS target by moving back some functions.

2018-10-10 Thread Martin Liška
On 10/9/18 10:34 PM, Martin Jambor wrote:
> On Tue, Oct 09 2018, Martin Liška wrote:
>> Hi.
>>
>> Utilizing rtags' --find-dead-functions I'm suggesting a removal of part
>> of the functions reported with the script. I built all cross compilers
>> defined in contrib/config-list.mk and I fixed VMS targets that I broke
>> in previous removal.
>>
>> If the folks are happy with the removal, I can probably continue with that
>> at some point in stage3 or so.
>>
>> Ready for trunk?
>> Thanks,
>> Martin
>> From f69d866da42a46783ab57181692583d2ecf30c49 Mon Sep 17 00:00:00 2001
>> From: marxin 
>> Date: Fri, 5 Oct 2018 16:59:07 +0200
>> Subject: [PATCH] Remove dead functions and fix VMS target by moving back some
>>  functions.
>>
>> gcc/ChangeLog:
>>
>> 2018-10-09  Martin Liska  
>>
>>  * attribs.c (register_attribute): Remove unused functions.
>>  * cfganal.c (control_dependences::clear_control_dependence_bitmap): 
>> Likewise.
>>  (bitmap_union_of_succs): Likewise.
>>  * cfganal.h (bitmap_union_of_succs): Likewise.
>>  * cfgloop.c (loop_exits_to_bb_p): Likewise.
>>  * cfgloop.h (loop_exits_to_bb_p): Likewise.
>>  * cgraph.h (compute_call_stmt_bb_frequency): Likewise.
>>  * cgraphbuild.c (compute_call_stmt_bb_frequency): Likewise.
>>  * cselib.c (cselib_dummy_expand_value_rtx_cb): Likewise.
>>  * cselib.h (cselib_dummy_expand_value_rtx_cb): Likewise.
>>  * df-core.c (df_reg_defined): Likewise.
>>  (df_reg_used): Likewise.
>>  * df-scan.c (df_hard_reg_used_count): Likewise.
>>  * df.h (df_reg_defined): Likewise.
>>  (df_reg_used): Likewise.
>>  (df_hard_reg_used_count): Likewise.
>>  * dojump.c (init_pending_stack_adjust): Likewise.
>>  * dojump.h (init_pending_stack_adjust): Likewise.
>>  * dwarf2out.c (add_AT_vms_delta): Move function back after
>>  removal.
>>  (dwarf2out_set_demangle_name_func): REmove unused functions.
>>  * dwarf2out.h (dwarf2out_set_demangle_name_func): Likewise.
>>  * emit-rtl.c (emit_jump_insn_before_noloc): Likewise.
>>  (emit_call_insn_before_noloc): Likewise.
>>  (emit_barrier_before): Likewise.
>>  (emit_call_insn_after_noloc): Likewise.
>>  (emit_call_insn_after_setloc): Likewise.
>>  (emit_jump_insn_before_setloc): Likewise.
>>  (emit_call_insn_before_setloc): Likewise.
>>  (emit_call_insn_before): Likewise.
>>  * except.c (remove_eh_handler): Likewise.
>>  (get_eh_region_from_rtx): Likewise.
>>  * except.h (remove_eh_handler): Likewise.
>>  (get_eh_region_from_rtx): Likewise.
>>  * fold-const.c (div_if_zero_remainder): Likewise.
>>  (fold_unary_to_constant): Likewise.
>>  * fold-const.h (fold_unary_to_constant): Likewise.
>>  (div_if_zero_remainder): Likewise.
>>  * function.c (get_hard_reg_initial_reg): Likewise.
>>  (get_last_funcdef_no): Likewise.
>>  * function.h (get_hard_reg_initial_reg): Likewise.
>>  (get_last_funcdef_no): Likewise.
>>  * ggc-common.c (ggc_cleared_alloc_htab_ignore_args): Likewise.
>>  (ggc_cleared_alloc_ptr_array_two_args): Likewise.
>>  (ggc_splay_alloc): Likewise.
>>  (ggc_splay_dont_free): Likewise.
>>  * gimple-expr.c (is_gimple_address): Likewise.
>>  * gimple-expr.h (is_gimple_address): Likewise.
>>  * gimple-iterator.c (gsi_for_phi): Likewise.
>>  * gimple-iterator.h (gsi_for_phi): Likewise.
>>  * gimple-ssa-sprintf.c (struct format_result): Likewise.
>>  (format_result::operator+=): Likewise.
>>  (struct directive): Likewise.
>>  * gimple-ssa-warn-alloca.c (struct alloca_type_and_limit): Likewise.
>>  * gimple.c (gimple_unsigned_type): Likewise.
>>  (gimple_call_builtin_p): Likewise.
>>  * gimple.h (gimple_unsigned_type): Likewise.
>>  (gimple_call_builtin_p): Likewise.
>>  * gimplify.c (gimple_current_bind_expr): Likewise.
>>  * gimplify.h (gimple_current_bind_expr): Likewise.
>>  * haifa-sched.c (haifa_classify_insn): Likewise.
>>  * hsa-common.c (hsa_add_kernel_dependency): Likewise.
>>  (hsa_brig_function_name): Likewise.
>>  * hsa-common.h (hsa_add_kernel_dependency): Likewise.
>>  (hsa_brig_function_name): Likewise.
>>  * ipa-cp.c (ipcp_vr_lattice::meet_with): Likewise.
> 
> Interesting, I believe that a class representing a lattice should have a
> meet function with its own type.

I've just tried to put gcc_unreachable there, but can't find anything that
would trigger an ICE.

I also run tests on x86_64-linux-gnu (with removed ipcp_vr_lattice::meet_with)
and it looks fine. I'm adding updated version of the patch where I moved back
register_attribute, it's used in attribute_plugin test.

Martin

In this case it would mean moving the
> call to ipa_vr_operation_and_type_effects from the caller into the
> method to clearly describe the semantics.  But perhaps it does not
> matter if we do not have the overload in the meantime.
> 
>>  * ipa-devirt.c (vtable_pointer_value_to_binfo): 

Re: [PATCH] Fix __builtin_ia32_rdpmc (PR target/87550)

2018-10-10 Thread Uros Bizjak
On Wed, Oct 10, 2018 at 11:09 AM Jakub Jelinek  wrote:
>
> Hi!
>
> The following testcase shows that we incorrectly handle __builtin_ia32_rdpmc
> as a const function, so we e.g. CSE it.  The problem is that all bdesc_args
> functions are registered using def_builtin_const.  The patch fixes this by
> moving it to the bdesc_special_args category, which is registered with
> def_builtin, similarly to e.g. rdtsc builtin.  The expansion is handled
> specially before we decide whether to call args or special_args expansion,
> and doesn't fall through, so from that POV it doesn't really matter which
> category it is.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2018-10-10  Jakub Jelinek  
>
> PR target/87550
> * config/i386/i386-builtin.def (IX86_BUILTIN_RDPMC): Move from args 
> set
> to special_args set.
>
> * gcc.target/i386/pr87550.c: New test.

OK.

Thanks,
Uros.

> --- gcc/config/i386/i386-builtin.def.jj 2018-06-13 10:05:54.816128362 +0200
> +++ gcc/config/i386/i386-builtin.def2018-10-09 09:28:10.199072944 +0200
> @@ -90,6 +90,7 @@ BDESC_END (PCMPISTR, SPECIAL_ARGS)
>  BDESC_FIRST (special_args, SPECIAL_ARGS,
> 0, CODE_FOR_nothing, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, 
> UNKNOWN, (int) UINT64_FTYPE_VOID)
>  BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, 
> UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED)
> +BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, 
> UNKNOWN, (int) UINT64_FTYPE_INT)
>  BDESC (0, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, 
> UNKNOWN, (int) VOID_FTYPE_VOID)
>
>  /* 80387 (for use internally for atomic compound assignment).  */
> @@ -427,7 +428,6 @@ BDESC_END (SPECIAL_ARGS, ARGS)
>  BDESC_FIRST (args, ARGS,
> 0, CODE_FOR_bsr, "__builtin_ia32_bsrsi", IX86_BUILTIN_BSRSI, UNKNOWN, 
> (int) INT_FTYPE_INT)
>  BDESC (OPTION_MASK_ISA_64BIT, CODE_FOR_bsr_rex64, "__builtin_ia32_bsrdi", 
> IX86_BUILTIN_BSRDI, UNKNOWN, (int) INT64_FTYPE_INT64)
> -BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, 
> UNKNOWN, (int) UINT64_FTYPE_INT)
>  BDESC (0, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", IX86_BUILTIN_ROLQI, 
> UNKNOWN, (int) UINT8_FTYPE_UINT8_INT)
>  BDESC (0, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", IX86_BUILTIN_ROLHI, 
> UNKNOWN, (int) UINT16_FTYPE_UINT16_INT)
>  BDESC (0, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", IX86_BUILTIN_RORQI, 
> UNKNOWN, (int) UINT8_FTYPE_UINT8_INT)
> --- gcc/testsuite/gcc.target/i386/pr87550.c.jj  2018-10-09 09:36:33.470600220 
> +0200
> +++ gcc/testsuite/gcc.target/i386/pr87550.c 2018-10-09 09:37:30.384642051 
> +0200
> @@ -0,0 +1,21 @@
> +/* PR target/87550 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2" } */
> +
> +#include 
> +
> +int
> +foo (int x)
> +{
> +  return __rdtsc () + __rdtsc ();
> +}
> +
> +/* { dg-final { scan-assembler-times "\trdtsc\[\n\r]" 2 } } */
> +
> +int
> +bar (int x)
> +{
> +  return __rdpmc (0) + __rdpmc (0);
> +}
> +
> +/* { dg-final { scan-assembler-times "\trdpmc\[\n\r]" 2 } } */
>
> Jakub


[C++ PATCH] Fix up bitfield handling in typeid (PR c++/87547)

2018-10-10 Thread Jakub Jelinek
Hi!

typeid of an expression that is a bitfield right now returns various weird
results, depending on what exact type ignoring precision we choose for the
bitfield.  Haven't found exact wording in the standard that would back this
out though.  clang++ agrees with the patched g++ though.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-10-10  Jakub Jelinek  

PR c++/87547
* rtti.c (get_tinfo_decl_dynamic): Use unlowered_expr_type instead
of TREE_TYPE.

* g++.dg/rtti/typeid12.C: New test.

--- gcc/cp/rtti.c.jj2018-08-27 17:50:43.782489578 +0200
+++ gcc/cp/rtti.c   2018-10-09 10:52:42.348604424 +0200
@@ -273,7 +273,7 @@ get_tinfo_decl_dynamic (tree exp, tsubst
   exp = resolve_nondeduced_context (exp, complain);
 
   /* peel back references, so they match.  */
-  type = non_reference (TREE_TYPE (exp));
+  type = non_reference (unlowered_expr_type (exp));
 
   /* Peel off cv qualifiers.  */
   type = TYPE_MAIN_VARIANT (type);
--- gcc/testsuite/g++.dg/rtti/typeid12.C.jj 2018-10-09 10:42:19.580094220 
+0200
+++ gcc/testsuite/g++.dg/rtti/typeid12.C2018-10-09 10:42:04.105354872 
+0200
@@ -0,0 +1,16 @@
+// PR c++/87547
+// { dg-do run }
+
+#include 
+
+struct S { unsigned int a : 4; unsigned int b : 12; int c; unsigned long d : 
8; } s;
+
+int
+main ()
+{
+  if (typeid (s.a) != typeid (unsigned int)
+  || typeid (s.b) != typeid (unsigned int)
+  || typeid (s.c) != typeid (int)
+  || typeid (s.d) != typeid (unsigned long))
+__builtin_abort ();
+}

Jakub


Re: [PATCH, i386]: Do not depend "C" constraint on TARGET_SSE

2018-10-10 Thread Uros Bizjak
On Wed, Oct 10, 2018 at 10:48 AM Jakub Jelinek  wrote:
>
> On Fri, Oct 05, 2018 at 06:49:58PM +0200, Uros Bizjak wrote:
> > This constraint is used in move patterns which do not depend on TARGET_SSE.
> >
> > Also, rename "vector_move_operand" to "nonimm_or_0_operand".
> >
> > 2018-10-05  Uros Bizjak  
> >
> > * config/i386/constraints.md ("C"): Do not depend on TARGET_SSE.
> > * config/i386/predicates.md (nonimm_or_0_operand): Rename
> > from vector_move_operand.  Update all uses.
> >
> > Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
> >
> > Committed to mainline SVN.
>
> This seems to have broken a bunch of tests for 32-bit gcc not configured to
> default to -msse/-msse2, guess it should be reproduceable with
> make check-gcc RUNTESTFLAGS='--target_board=unix/-m32/-mno-sse i386.exp'
>
> +FAIL: gcc.target/i386/3dnow-1.c (internal compiler error)
> +FAIL: gcc.target/i386/3dnow-1.c (test for excess errors)
> +FAIL: gcc.target/i386/mmx-8.c (internal compiler error)
> +FAIL: gcc.target/i386/mmx-8.c (test for excess errors)
> +UNRESOLVED: gcc.target/i386/mmx-8.c compilation failed to produce executable
> +FAIL: gcc.target/i386/pr14552.c (internal compiler error)
> +FAIL: gcc.target/i386/pr14552.c (test for excess errors)
> +UNRESOLVED: gcc.target/i386/pr14552.c scan-assembler-not %mm
>
> The ICEs are always similar:
> error: could not split insn
> (insn:TI 7 30 21 2 (set (mem/c:V2SF (plus:SI (reg/f:SI 7 sp)
> (const_int 8 [0x8])) [0  S8 A64])
> (const_vector:V2SF [
> (const_double:SF 0.0 [0x0.0p+0])
> (const_double:SF 0.0 [0x0.0p+0])
> ])) "/home/jakub/src/gcc/obj27/gcc/include/mm3dnow.h":172:39 835 
> {*movv2sf_internal}
>  (nil))

The patch for PR87573 [1] should fix all these ICEs.

[1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87573#c2

Uros.


[PATCH] Fix __builtin_ia32_rdpmc (PR target/87550)

2018-10-10 Thread Jakub Jelinek
Hi!

The following testcase shows that we incorrectly handle __builtin_ia32_rdpmc
as a const function, so we e.g. CSE it.  The problem is that all bdesc_args
functions are registered using def_builtin_const.  The patch fixes this by
moving it to the bdesc_special_args category, which is registered with
def_builtin, similarly to e.g. rdtsc builtin.  The expansion is handled
specially before we decide whether to call args or special_args expansion,
and doesn't fall through, so from that POV it doesn't really matter which
category it is.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-10-10  Jakub Jelinek  

PR target/87550
* config/i386/i386-builtin.def (IX86_BUILTIN_RDPMC): Move from args set
to special_args set.

* gcc.target/i386/pr87550.c: New test.

--- gcc/config/i386/i386-builtin.def.jj 2018-06-13 10:05:54.816128362 +0200
+++ gcc/config/i386/i386-builtin.def2018-10-09 09:28:10.199072944 +0200
@@ -90,6 +90,7 @@ BDESC_END (PCMPISTR, SPECIAL_ARGS)
 BDESC_FIRST (special_args, SPECIAL_ARGS,
0, CODE_FOR_nothing, "__builtin_ia32_rdtsc", IX86_BUILTIN_RDTSC, 
UNKNOWN, (int) UINT64_FTYPE_VOID)
 BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdtscp", IX86_BUILTIN_RDTSCP, 
UNKNOWN, (int) UINT64_FTYPE_PUNSIGNED)
+BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, 
UNKNOWN, (int) UINT64_FTYPE_INT)
 BDESC (0, CODE_FOR_pause, "__builtin_ia32_pause", IX86_BUILTIN_PAUSE, UNKNOWN, 
(int) VOID_FTYPE_VOID)
 
 /* 80387 (for use internally for atomic compound assignment).  */
@@ -427,7 +428,6 @@ BDESC_END (SPECIAL_ARGS, ARGS)
 BDESC_FIRST (args, ARGS,
0, CODE_FOR_bsr, "__builtin_ia32_bsrsi", IX86_BUILTIN_BSRSI, UNKNOWN, 
(int) INT_FTYPE_INT)
 BDESC (OPTION_MASK_ISA_64BIT, CODE_FOR_bsr_rex64, "__builtin_ia32_bsrdi", 
IX86_BUILTIN_BSRDI, UNKNOWN, (int) INT64_FTYPE_INT64)
-BDESC (0, CODE_FOR_nothing, "__builtin_ia32_rdpmc", IX86_BUILTIN_RDPMC, 
UNKNOWN, (int) UINT64_FTYPE_INT)
 BDESC (0, CODE_FOR_rotlqi3, "__builtin_ia32_rolqi", IX86_BUILTIN_ROLQI, 
UNKNOWN, (int) UINT8_FTYPE_UINT8_INT)
 BDESC (0, CODE_FOR_rotlhi3, "__builtin_ia32_rolhi", IX86_BUILTIN_ROLHI, 
UNKNOWN, (int) UINT16_FTYPE_UINT16_INT)
 BDESC (0, CODE_FOR_rotrqi3, "__builtin_ia32_rorqi", IX86_BUILTIN_RORQI, 
UNKNOWN, (int) UINT8_FTYPE_UINT8_INT)
--- gcc/testsuite/gcc.target/i386/pr87550.c.jj  2018-10-09 09:36:33.470600220 
+0200
+++ gcc/testsuite/gcc.target/i386/pr87550.c 2018-10-09 09:37:30.384642051 
+0200
@@ -0,0 +1,21 @@
+/* PR target/87550 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+#include 
+
+int
+foo (int x)
+{
+  return __rdtsc () + __rdtsc ();
+}
+
+/* { dg-final { scan-assembler-times "\trdtsc\[\n\r]" 2 } } */
+
+int
+bar (int x)
+{
+  return __rdpmc (0) + __rdpmc (0);
+}
+
+/* { dg-final { scan-assembler-times "\trdpmc\[\n\r]" 2 } } */

Jakub


Re: Don't ICE on vectors of enums (PR 87286)

2018-10-10 Thread Jakub Jelinek
On Fri, Oct 05, 2018 at 01:48:24PM +0100, Richard Sandiford wrote:
> We've traditionally allowed vectors of enums (not sure if that's
> deliberate) but vector_types_compatible_elements_p checked for
> INTEGER_TYPE rather than INTEGRAL_TYPE_P.
> 
> Tested on aarch64-linux-gnu.  OK to install?
> 
> Richard
> 
> 
> 2018-10-05  Richard Sandiford  
> 
> gcc/c-family/
>   PR c/87286
>   * c-common.c (vector_types_compatible_elements_p): Use
>   INTEGRAL_TYPE_P instead of checking only for INTEGER_TYPE.
> 
> gcc/testsuite/
>   PR c/87286
>   * gcc.dg/pr87286.c: New test.

This testcase fails on i686-linux (unless configured to default to -msse2):
Executing on host: /home/jakub/src/gcc/obj27/gcc/xgcc 
-B/home/jakub/src/gcc/obj27/gcc/ 
/home/jakub/src/gcc/gcc/testsuite/gcc.dg/pr87286.c
-fno-diagnostics-show-caret -fno-diagnostics-show-line-numbers 
-fdiagnostics-color=never-ansi -pedantic-errors -S -o pr87286.s(timeout 
= 300)
spawn -ignore SIGHUP /home/jakub/src/gcc/obj27/gcc/xgcc 
-B/home/jakub/src/gcc/obj27/gcc/ 
/home/jakub/src/gcc/gcc/testsuite/gcc.dg/pr87286.c -fno-diagnostics-show-caret 
-fno-diagnostics-show-line-numbers -fdiagnostics-color=never -ansi 
-pedantic-errors -S -o pr87286.s
/home/jakub/src/gcc/gcc/testsuite/gcc.dg/pr87286.c: In function 'add':
/home/jakub/src/gcc/gcc/testsuite/gcc.dg/pr87286.c:3:1: warning: SSE vector 
return without SSE enabled changes the ABI [-Wpsabi]
/home/jakub/src/gcc/gcc/testsuite/gcc.dg/pr87286.c:3:9: note: The ABI for 
passing parameters with 16-byte alignment has changed in GCC 4.6
/home/jakub/src/gcc/gcc/testsuite/gcc.dg/pr87286.c:3:9: warning: SSE vector 
argument without SSE enabled changes the ABI [-Wpsabi]
FAIL: gcc.dg/pr87286.c (test for excess errors)
Excess errors:
/home/jakub/src/gcc/gcc/testsuite/gcc.dg/pr87286.c:3:1: warning: SSE vector 
return without SSE enabled changes the ABI [-Wpsabi]
/home/jakub/src/gcc/gcc/testsuite/gcc.dg/pr87286.c:3:9: warning: SSE vector 
argument without SSE enabled changes the ABI [-Wpsabi]

Fixed thusly, committed as obvious:

2018-10-10  Jakub Jelinek  

PR c/87286
* gcc.dg/pr87286.c: Add -Wno-psabi to dg-options.

--- gcc/testsuite/gcc.dg/pr87286.c.jj   2018-10-08 15:18:28.923990456 +0200
+++ gcc/testsuite/gcc.dg/pr87286.c  2018-10-10 10:59:15.111698976 +0200
@@ -1,3 +1,4 @@
+/* { dg-options "-Wno-psabi" } */
 enum foo { F };
 typedef enum foo vec_foo __attribute__((vector_size (16)));
 vec_foo add (vec_foo x, vec_foo y) { return x + y; }


Jakub


Re: [PATCH, i386]: Do not depend "C" constraint on TARGET_SSE

2018-10-10 Thread Jakub Jelinek
On Fri, Oct 05, 2018 at 06:49:58PM +0200, Uros Bizjak wrote:
> This constraint is used in move patterns which do not depend on TARGET_SSE.
> 
> Also, rename "vector_move_operand" to "nonimm_or_0_operand".
> 
> 2018-10-05  Uros Bizjak  
> 
> * config/i386/constraints.md ("C"): Do not depend on TARGET_SSE.
> * config/i386/predicates.md (nonimm_or_0_operand): Rename
> from vector_move_operand.  Update all uses.
> 
> Bootstrapped and regression tested on x86_64-linux-gnu {,-m32}.
> 
> Committed to mainline SVN.

This seems to have broken a bunch of tests for 32-bit gcc not configured to
default to -msse/-msse2, guess it should be reproduceable with
make check-gcc RUNTESTFLAGS='--target_board=unix/-m32/-mno-sse i386.exp'

+FAIL: gcc.target/i386/3dnow-1.c (internal compiler error)
+FAIL: gcc.target/i386/3dnow-1.c (test for excess errors)
+FAIL: gcc.target/i386/mmx-8.c (internal compiler error)
+FAIL: gcc.target/i386/mmx-8.c (test for excess errors)
+UNRESOLVED: gcc.target/i386/mmx-8.c compilation failed to produce executable
+FAIL: gcc.target/i386/pr14552.c (internal compiler error)
+FAIL: gcc.target/i386/pr14552.c (test for excess errors)
+UNRESOLVED: gcc.target/i386/pr14552.c scan-assembler-not %mm

The ICEs are always similar:
error: could not split insn
(insn:TI 7 30 21 2 (set (mem/c:V2SF (plus:SI (reg/f:SI 7 sp)
(const_int 8 [0x8])) [0  S8 A64])
(const_vector:V2SF [
(const_double:SF 0.0 [0x0.0p+0])
(const_double:SF 0.0 [0x0.0p+0])
])) "/home/jakub/src/gcc/obj27/gcc/include/mm3dnow.h":172:39 835 
{*movv2sf_internal}
 (nil))

Jakub


[PATCH 5/6] [ARC] Refurbish and improve prologue/epilogue functions.

2018-10-10 Thread Claudiu Zissulescu
Reimplement how prologue and epilogue is emitted to accomodate
enter/leave instructions, as well as improving the size of the
existing techinques.

The following modifications are added:

- millicode thunk calls can be now selected regardless of the
  optimization level. However they are enabled for size optimizations
  by default.  Also, the millicode optimization is turned off when we
  compile for long jumps.

- the compiler is able to use enter/leave instructions for prologue
  and epilogue. As these instructions are not ABI compatible we gurad
  them under a switch (i.e., -mcode-density-frame). When this option
  is on, the compiler will try emitting enter/leave instructions, if
  not, then millicode thunk calls (if enabled), and latter the regular
  push/pop instructions.

- The prologue/epilogue is now optimized to use pointer walks, hence
  improving the chance to have push_s/pop_s instructions emitted. It
  also tries to combine the stack adjustments with load/store
  operations.

gcc/
x-xx-xx  Claudiu Zissulescu  

* common/config/arc/arc-common.c (arc_option_optimization_table):
Millicode optimization is default on for size optimizations.
* config/arc/arc-protos.h (arc_check_multi): New function.
* config/arc/arc.c (RTX_OK_FOR_OFFSET_P): Rearange.
(arc_override_options): Disable millicode when long calls option
is on.
(arc_frame_info): Change it from int to bool.
(arc_compute_frame_size): Clean up.
(arc_save_restore): Remove.
(frame_save_reg): New function.
(frame_restore_reg): Likewise.
(arc_enter_leave_p): Likewise.
(arc_save_callee_saves): Likewise.
(arc_restore_callee_saves): Likewise.
(arc_save_callee_enter): Likewise.
(arc_restore_callee_leave): Likewise.
(arc_save_callee_milli): Likewise.
(arc_restore_callee_milli): Likewise.
(arc_expand_prologue): Reimplement to emit enter/leave
instructions.
(arc_expand_epilogue): Likewise.
(arc_check_multi): New function.
* config/arc/arc.md (push_multi_fp): New pattern.
(push_multi_fp_blink): Likewise.
(pop_multi_fp): Likewise.
(pop_multi_fp_blink): Likewise.
(pop_multi_fp_ret): Likewise.
(pop_multi_fp_blink_ret): Likewise.
* config/arc/arc.opt (mmillicode): Update option.
(mcode-density-frame): New option.
* config/arc/predicates.md (push_multi_operand): New predicate.
(pop_multi_operand): Likewise.
* doc/invoke.texi (ARC): Update ARC options information.

gcc/testsuite
x-xx-xx  Claudiu Zissulescu  

* gcc.target/arc/firq-1.c: Update test.
* gcc.target/arc/firq-3.c: Likewise.
* gcc.target/arc/firq-4.c: Likewise.
* gcc.target/arc/interrupt-6.c: Likewise.
---
 gcc/common/config/arc/arc-common.c |1 +
 gcc/config/arc/arc-protos.h|1 +
 gcc/config/arc/arc.c   | 1266 +---
 gcc/config/arc/arc.md  |  172 +++
 gcc/config/arc/arc.opt |   10 +-
 gcc/config/arc/predicates.md   |   12 +
 gcc/doc/invoke.texi|   18 +-
 gcc/testsuite/gcc.target/arc/firq-1.c  |8 +-
 gcc/testsuite/gcc.target/arc/firq-3.c  |   14 +-
 gcc/testsuite/gcc.target/arc/firq-4.c  |   12 +-
 gcc/testsuite/gcc.target/arc/interrupt-6.c |2 +-
 11 files changed, 1054 insertions(+), 462 deletions(-)

diff --git a/gcc/common/config/arc/arc-common.c 
b/gcc/common/config/arc/arc-common.c
index 578431a279d..2872388de2c 100644
--- a/gcc/common/config/arc/arc-common.c
+++ b/gcc/common/config/arc/arc-common.c
@@ -59,6 +59,7 @@ static const struct default_options 
arc_option_optimization_table[] =
 { OPT_LEVELS_SIZE, OPT_mq_class, NULL, 1 },
 { OPT_LEVELS_SIZE, OPT_mcase_vector_pcrel, NULL, 1 },
 { OPT_LEVELS_SIZE, OPT_msize_level_, NULL, 3 },
+{ OPT_LEVELS_SIZE, OPT_mmillicode, NULL, 1 },
 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
 { OPT_LEVELS_3_PLUS_SPEED_ONLY, OPT_msize_level_, NULL, 0 },
 { OPT_LEVELS_3_PLUS_SPEED_ONLY, OPT_malign_call, NULL, 1 },
diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index 55f8ed4c643..6450b6a014e 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -47,6 +47,7 @@ extern unsigned int arc_compute_function_type (struct 
function *);
 extern bool arc_is_uncached_mem_p (rtx);
 extern bool arc_lra_p (void);
 extern bool gen_operands_ldd_std (rtx *operands, bool load, bool commute);
+extern bool arc_check_multi (rtx, bool);
 #endif /* RTX_CODE */
 
 extern unsigned int arc_compute_frame_size (int);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 9bc69e9fbc9..ab7735d6b38 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -89,12 +89,12 @@ HARD_REG_SET overrideregs;
 
 /* ??? Loads can handle any constant, 

[PATCH 2/6] [ARC] Cleanup TLS implementation.

2018-10-10 Thread Claudiu Zissulescu
Cleanup TLS implementation and add a number of tests.

gcc/
2018-07-25  Claudiu Zissulescu  

* config/arc/arc.c (arc_get_tp): Remove function.
(arc_emit_call_tls_get_addr): Likewise.
(arc_call_tls_get_addr): New function.
(arc_legitimize_tls_address): Make use of arc_call_tls_get_addr.
* config/arc/arc.md (tls_load_tp_soft): Remove.
(tls_gd_get_addr): Likewise.

testsuite/
2018-07-25  Claudiu Zissulescu  

* gcc.target/arc/tls-gd.c: New file.
* gcc.target/arc/tls-ie.c: Likewise.
* gcc.target/arc/tls-ld.c: Likewise.
* gcc.target/arc/tls-le.c: Likewise.
---
 gcc/config/arc/arc.c  | 95 +++
 gcc/config/arc/arc.md | 21 --
 gcc/testsuite/gcc.target/arc/tls-1.c  |  2 +-
 gcc/testsuite/gcc.target/arc/tls-gd.c | 17 +
 gcc/testsuite/gcc.target/arc/tls-ie.c | 17 +
 gcc/testsuite/gcc.target/arc/tls-ld.c | 18 +
 gcc/testsuite/gcc.target/arc/tls-le.c | 16 +
 7 files changed, 106 insertions(+), 80 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/tls-gd.c
 create mode 100644 gcc/testsuite/gcc.target/arc/tls-ie.c
 create mode 100644 gcc/testsuite/gcc.target/arc/tls-ld.c
 create mode 100644 gcc/testsuite/gcc.target/arc/tls-le.c

diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index de4c7433c1b..56f566795ff 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -5559,51 +5559,30 @@ arc_raw_symbolic_reference_mentioned_p (rtx op, bool 
skip_local)
   return false;
 }
 
-/* Get the thread pointer.  */
+/* Emit a call to __tls_get_addr.  TI is the argument to this function.
+   RET is an RTX for the return value location.  The entire insn sequence
+   is returned.  */
+static GTY(()) rtx arc_tls_symbol;
 
 static rtx
-arc_get_tp (void)
+arc_call_tls_get_addr (rtx ti)
 {
-   /* If arc_tp_regno has been set, we can use that hard register
-  directly as a base register.  */
-  if (arc_tp_regno != -1)
-return gen_rtx_REG (Pmode, arc_tp_regno);
-
-  /* Otherwise, call __read_tp.  Copy the result to a pseudo to avoid
- conflicts with function arguments / results.  */
-  rtx reg = gen_reg_rtx (Pmode);
-  emit_insn (gen_tls_load_tp_soft ());
-  emit_move_insn (reg, gen_rtx_REG (Pmode, R0_REG));
-  return reg;
-}
-
-/* Helper to be used by TLS Global dynamic model.  */
-
-static rtx
-arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv)
-{
-  rtx r0 = gen_rtx_REG (Pmode, R0_REG);
-  rtx call_fusage = NULL_RTX;
-
-  start_sequence ();
-
-  rtx x = arc_unspec_offset (sym, reloc);
-  emit_move_insn (r0, x);
-  use_reg (_fusage, r0);
+  rtx arg = gen_rtx_REG (Pmode, R0_REG);
+  rtx ret = gen_rtx_REG (Pmode, R0_REG);
+  rtx fn;
+  rtx_insn *insn;
 
-  gcc_assert (reloc == UNSPEC_TLS_GD);
-  rtx call_insn = emit_call_insn (gen_tls_gd_get_addr (sym));
-  /* Should we set RTL_CONST_CALL_P?  We read memory, but not in a
- way that the application should care.  */
-  RTL_PURE_CALL_P (call_insn) = 1;
-  add_function_usage_to (call_insn, call_fusage);
+  if (!arc_tls_symbol)
+arc_tls_symbol = init_one_libfunc ("__tls_get_addr");
 
-  rtx_insn *insns = get_insns ();
-  end_sequence ();
+  emit_move_insn (arg, ti);
+  fn = gen_rtx_MEM (SImode, arc_tls_symbol);
+  insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
+  RTL_CONST_CALL_P (insn) = 1;
+  use_reg (_INSN_FUNCTION_USAGE (insn), ret);
+  use_reg (_INSN_FUNCTION_USAGE (insn), arg);
 
-  rtx dest = gen_reg_rtx (Pmode);
-  emit_libcall_block (insns, dest, r0, eqv);
-  return dest;
+  return ret;
 }
 
 #define DTPOFF_ZERO_SYM ".tdata"
@@ -5614,16 +5593,26 @@ arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv)
 static rtx
 arc_legitimize_tls_address (rtx addr, enum tls_model model)
 {
+  rtx tmp;
+
   if (!flag_pic && model == TLS_MODEL_LOCAL_DYNAMIC)
 model = TLS_MODEL_LOCAL_EXEC;
 
+
+  /* The TP pointer needs to be set.  */
+  gcc_assert (arc_tp_regno != -1);
+
   switch (model)
 {
+case TLS_MODEL_GLOBAL_DYNAMIC:
+  tmp = gen_reg_rtx (Pmode);
+  emit_move_insn (tmp, arc_unspec_offset (addr, UNSPEC_TLS_GD));
+  return arc_call_tls_get_addr (tmp);
+
 case TLS_MODEL_LOCAL_DYNAMIC:
   rtx base;
   tree decl;
   const char *base_name;
-  rtvec v;
 
   decl = SYMBOL_REF_DECL (addr);
   base_name = DTPOFF_ZERO_SYM;
@@ -5631,31 +5620,21 @@ arc_legitimize_tls_address (rtx addr, enum tls_model 
model)
base_name = ".tbss";
 
   base = gen_rtx_SYMBOL_REF (Pmode, base_name);
-  if (strcmp (base_name, DTPOFF_ZERO_SYM) == 0)
-   {
- if (!flag_pic)
-   goto local_exec;
- v = gen_rtvec (1, addr);
-   }
-  else
-   v = gen_rtvec (2, addr, base);
-  addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_TLS_OFF);
-  addr = gen_rtx_CONST (Pmode, addr);
-  base = arc_legitimize_tls_address (base, TLS_MODEL_GLOBAL_DYNAMIC);
-  return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), addr);
-

[PATCH 6/6] [ARC] Handle store cacheline hazard.

2018-10-10 Thread Claudiu Zissulescu
Handle store cacheline hazard for A700 cpus by inserting two NOP_S
between ST ST LD or their logical equivalent (like ST ST NOP_S NOP_S
J_L.D LD)

gcc/
2016-08-01  Claudiu Zissulescu  

* config/arc/arc-arch.h (ARC_TUNE_ARC7XX): New tune value.
* config/arc/arc.c (arc_active_insn): New function.
(check_store_cacheline_hazard): Likewise.
(workaround_arc_anomaly): Use check_store_cacheline_hazard.
(arc_override_options): Disable delay slot scheduler for older
A7.
(arc_store_addr_hazard_p): New implementation, old one renamed to
...
(arc_store_addr_hazard_internal_p): Renamed.
(arc_reorg): Don't combine into brcc instructions which are part
of hardware hazard solution.
* config/arc/arc.md (attr tune): Consider new arc7xx tune value.
(tune_arc700): Likewise.
* config/arc/arc.opt (arc7xx): New tune value.
* config/arc/arc700.md: Improve A7 scheduler.
---
 gcc/config/arc/arc-arch.h |   1 +
 gcc/config/arc/arc.c  | 142 --
 gcc/config/arc/arc.md |   8 ++-
 gcc/config/arc/arc.opt|   3 +
 gcc/config/arc/arc700.md  |  18 +
 5 files changed, 132 insertions(+), 40 deletions(-)

diff --git a/gcc/config/arc/arc-arch.h b/gcc/config/arc/arc-arch.h
index 859af0684b8..ad540607e55 100644
--- a/gcc/config/arc/arc-arch.h
+++ b/gcc/config/arc/arc-arch.h
@@ -71,6 +71,7 @@ enum arc_tune_attr
   {
 ARC_TUNE_NONE,
 ARC_TUNE_ARC600,
+ARC_TUNE_ARC7XX,
 ARC_TUNE_ARC700_4_2_STD,
 ARC_TUNE_ARC700_4_2_XMAC,
 ARC_TUNE_CORE_3,
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index ab7735d6b38..90454928379 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -1308,6 +1308,10 @@ arc_override_options (void)
   if (TARGET_LONG_CALLS_SET)
 target_flags &= ~MASK_MILLICODE_THUNK_SET;
 
+  /* A7 has an issue with delay slots.  */
+  if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX))
+flag_delayed_branch = 0;
+
   /* These need to be done at start up.  It's convenient to do them here.  */
   arc_init ();
 }
@@ -7529,11 +7533,91 @@ arc_invalid_within_doloop (const rtx_insn *insn)
   return NULL;
 }
 
+static rtx_insn *
+arc_active_insn (rtx_insn *insn)
+{
+  rtx_insn *nxt = next_active_insn (insn);
+
+  if (nxt && GET_CODE (PATTERN (nxt)) == ASM_INPUT)
+nxt = next_active_insn (nxt);
+  return nxt;
+}
+
+/* Search for a sequence made out of two stores and a given number of
+   loads, insert a nop if required.  */
+
+static void
+check_store_cacheline_hazard (void)
+{
+  rtx_insn *insn, *succ0, *insn1;
+  bool found = false;
+
+  for (insn = get_insns (); insn; insn = arc_active_insn (insn))
+{
+  succ0 = arc_active_insn (insn);
+
+  if (!succ0)
+   return;
+
+  if (!single_set (insn) || !single_set (succ0))
+   continue;
+
+  if ((get_attr_type (insn) != TYPE_STORE)
+ || (get_attr_type (succ0) != TYPE_STORE))
+   continue;
+
+  /* Found at least two consecutive stores.  Goto the end of the
+store sequence.  */
+  for (insn1 = succ0; insn1; insn1 = arc_active_insn (insn1))
+   if (!single_set (insn1) || get_attr_type (insn1) != TYPE_STORE)
+ break;
+
+  /* Now, check the next two instructions for the following cases:
+ 1. next instruction is a LD => insert 2 nops between store
+   sequence and load.
+2. next-next instruction is a LD => inset 1 nop after the store
+   sequence.  */
+  if (insn1 && single_set (insn1)
+ && (get_attr_type (insn1) == TYPE_LOAD))
+   {
+ found = true;
+ emit_insn_before (gen_nopv (), insn1);
+ emit_insn_before (gen_nopv (), insn1);
+   }
+  else
+   {
+ if (insn1 && (get_attr_type (insn1) == TYPE_COMPARE))
+   {
+ /* REG_SAVE_NOTE is used by Haifa scheduler, we are in
+reorg, so it is safe to reuse it for avoiding the
+current compare insn to be part of a BRcc
+optimization.  */
+ add_reg_note (insn1, REG_SAVE_NOTE, GEN_INT (3));
+   }
+ insn1 = arc_active_insn (insn1);
+ if (insn1 && single_set (insn1)
+ && (get_attr_type (insn1) == TYPE_LOAD))
+   {
+ found = true;
+ emit_insn_before (gen_nopv (), insn1);
+   }
+   }
+
+  insn = insn1;
+  if (found)
+   {
+ /* warning (0, "Potential lockup sequence found, patching"); */
+ found = false;
+   }
+}
+}
+
 /* Return true if a load instruction (CONSUMER) uses the same address as a
store instruction (PRODUCER).  This function is used to avoid st/ld
address hazard in ARC700 cores.  */
-bool
-arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
+
+static bool
+arc_store_addr_hazard_internal_p (rtx_insn* producer, rtx_insn* consumer)
 {
   rtx in_set, out_set;
   rtx out_addr, in_addr;

[PATCH 3/6] [ARC] Add BI/BIH instruction support.

2018-10-10 Thread Claudiu Zissulescu
Use BI/BIH instruction to implement casesi pattern. Only ARC V2.

gcc/
2018-03-21  Claudiu Zissulescu  

* config/arc/arc.c (arc_override_options): Remove
TARGET_COMPACT_CASESI.
* config/arc/arc.h (ASM_OUTPUT_ADDR_DIFF_ELT): Update.
(CASE_VECTOR_MODE): Likewise.
(CASE_VECTOR_PC_RELATIVE): Likewise.
(CASE_VECTOR_SHORTEN_MODE): Likewise.
(CASE_VECTOR_SHORTEN_MODE1): Delete.
(ADDR_VEC_ALIGN): Update.
(ASM_OUTPUT_CASE_LABEL): Undefine.
(ASM_OUTPUT_BEFORE_CASE_LABEL): Undefine.
(TARGET_BI_BIH): Define.
(DEFAULT_BRANCH_INDEX): Likewise.
* config/arc/arc.md (casesi): Rework to accept BI/BIH
instructions, remove compact_casesi use case.
(casesi_compact_jump): Remove.
(casesi_dispatch): New pattern.
* config/arc/arc.opt: Add mbranch-index option. Deprecate
compact_casesi option.
* doc/invoke.texi: Document mbranch-index option.

gcc/testsuite
Claudiu Zissulescu  

* gcc.target/arc/jumptable.c: New test.
---
 gcc/config/arc/arc.c |  19 --
 gcc/config/arc/arc.h | 106 ++-
 gcc/config/arc/arc.md| 218 +++
 gcc/config/arc/arc.opt   |   6 +-
 gcc/doc/invoke.texi  |   9 +-
 gcc/testsuite/gcc.target/arc/jumptable.c |  34 
 6 files changed, 171 insertions(+), 221 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/jumptable.c

diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 56f566795ff..18dd0de6af7 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -1291,33 +1291,14 @@ arc_override_options (void)
   if (arc_size_opt_level == 3)
 optimize_size = 1;
 
-  /* Compact casesi is not a valid option for ARCv2 family.  */
-  if (TARGET_V2)
-{
-  if (TARGET_COMPACT_CASESI)
-   {
- warning (OPT_mcompact_casesi,
-  "compact-casesi is not applicable to ARCv2");
- TARGET_COMPACT_CASESI = 0;
-   }
-}
-  else if (optimize_size == 1
-  && !global_options_set.x_TARGET_COMPACT_CASESI)
-TARGET_COMPACT_CASESI = 1;
-
   if (flag_pic)
 target_flags |= MASK_NO_SDATA_SET;
 
   if (flag_no_common == 255)
 flag_no_common = !TARGET_NO_SDATA_SET;
 
-  /* TARGET_COMPACT_CASESI needs the "q" register class.  */
   if (TARGET_MIXED_CODE)
 TARGET_Q_CLASS = 1;
-  if (!TARGET_Q_CLASS)
-TARGET_COMPACT_CASESI = 0;
-  if (TARGET_COMPACT_CASESI)
-TARGET_CASE_VECTOR_PC_RELATIVE = 1;
 
   /* Check for small data option */
   if (!global_options_set.x_g_switch_value && !TARGET_NO_SDATA_SET)
diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index dd78a6bbbd1..cb48b85d6e7 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -1264,25 +1264,39 @@ do {
\
 } while (0)
 
 /* This is how to output an element of a case-vector that is relative.  */
-#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
-do {   \
-  char label[30];  \
-  ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE); \
-  switch (GET_MODE (BODY)) \
-{  \
-case E_QImode: fprintf (FILE, "\t.byte "); break;  \
-case E_HImode: fprintf (FILE, "\t.hword "); break; \
-case E_SImode: fprintf (FILE, "\t.word "); break;  \
-default: gcc_unreachable ();   \
-}  \
-  assemble_name (FILE, label); \
-  fprintf (FILE, "-"); \
-  ASM_GENERATE_INTERNAL_LABEL (label, "L", REL);   \
-  assemble_name (FILE, label); \
-  if (TARGET_COMPACT_CASESI)   \
-fprintf (FILE, " + %d", 4 + arc_get_unalign ());   \
-  fprintf(FILE, "\n");  \
-} while (0)
+#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL)   \
+  do { \
+char label[30];\
+ASM_GENERATE_INTERNAL_LABEL (label, "L", VALUE);   \
+if (!TARGET_BI_BIH)\
+  {\
+   switch (GET_MODE (BODY))\
+ { \
+ case E_QImode: fprintf (FILE, "\t.byte "); break; \
+ case E_HImode: fprintf (FILE, "\t.hword "); break;\
+ case E_SImode: fprintf (FILE, "\t.word "); break; \
+ default: gcc_unreachable ();  \
+ } \
+   assemble_name (FILE, label); 

[PATCH 0/6] ARC updates

2018-10-10 Thread Claudiu Zissulescu
Hi Andrew,

Please find a number of patches that are adding more features to arc backend 
(BI/BIH instructions, peephole rules, enter/leave instructions) or fixes 
exising issues (store hazards, tls implementation, library calls).

Please let me know if you have any question,
Claudiu


Claudiu Zissulescu (6):
  [ARC] Remove non standard funcions calls.
  [ARC] Cleanup TLS implementation.
  [ARC] Add BI/BIH instruction support.
  [ARC] Add peephole rules to combine store/loads into double
store/loads
  [ARC] Refurbish and improve prologue/epilogue functions.
  [ARC] Handle store cacheline hazard.

 gcc/common/config/arc/arc-common.c|1 +
 gcc/config/arc/arc-arch.h |1 +
 gcc/config/arc/arc-protos.h   |2 +
 gcc/config/arc/arc.c  | 1701 +++--
 gcc/config/arc/arc.h  |  106 +-
 gcc/config/arc/arc.md |  644 +++
 gcc/config/arc/arc.opt|   19 +-
 gcc/config/arc/arc700.md  |   18 +-
 gcc/config/arc/predicates.md  |   12 +
 gcc/doc/invoke.texi   |   27 +-
 gcc/testsuite/gcc.target/arc/firq-1.c |8 +-
 gcc/testsuite/gcc.target/arc/firq-3.c |   14 +-
 gcc/testsuite/gcc.target/arc/firq-4.c |   12 +-
 gcc/testsuite/gcc.target/arc/interrupt-6.c|2 +-
 gcc/testsuite/gcc.target/arc/jumptable.c  |   34 +
 .../gcc.target/arc/mulsi3_highpart-2.c|5 +-
 gcc/testsuite/gcc.target/arc/tls-1.c  |2 +-
 gcc/testsuite/gcc.target/arc/tls-gd.c |   17 +
 gcc/testsuite/gcc.target/arc/tls-ie.c |   17 +
 gcc/testsuite/gcc.target/arc/tls-ld.c |   18 +
 gcc/testsuite/gcc.target/arc/tls-le.c |   16 +
 libgcc/config/arc/lib1funcs.S |   54 +
 libgcc/config/arc/t-arc   |2 +-
 23 files changed, 1769 insertions(+), 963 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/jumptable.c
 create mode 100644 gcc/testsuite/gcc.target/arc/tls-gd.c
 create mode 100644 gcc/testsuite/gcc.target/arc/tls-ie.c
 create mode 100644 gcc/testsuite/gcc.target/arc/tls-ld.c
 create mode 100644 gcc/testsuite/gcc.target/arc/tls-le.c

-- 
2.17.1



[PATCH 1/6] [ARC] Remove non standard funcions calls.

2018-10-10 Thread Claudiu Zissulescu
Replace all custom "library" calls with compiler known patterns.

gcc/
-xx-xx  Claudiu Zissulescu  

* config/arc/arc.md (mulsi3): Remove call to mulsi_600_lib.
(mulsi3_600_lib): Remove pattern.
(umulsi3_highpart_600_lib_le): Likewise.
(umulsi3_highpart): Remove call to umulsi3_highpart_600_lib_le.
(umulsidi3): Remove call to umulsidi3_600_lib.
(umulsidi3_600_lib): Remove pattern.
(peephole2): Remove peephole using the above deprecated patterns.

testsuite/
-xx-xx  Claudiu Zissulescu  

* gcc.target/arc/mulsi3_highpart-2.c: Update test.

libgcc/
-xx-xx  Claudiu Zissulescu  

* config/arc/lib1funcs.S (_muldi3): New function.
* config/arc/t-arc (LIB1ASMFUNCS): Add _muldi3.
---
 gcc/config/arc/arc.md | 158 ++
 .../gcc.target/arc/mulsi3_highpart-2.c|   5 +-
 libgcc/config/arc/lib1funcs.S |  54 ++
 libgcc/config/arc/t-arc   |   2 +-
 4 files changed, 67 insertions(+), 152 deletions(-)

diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index 42ca820b91d..d73289a20c4 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -2076,44 +2076,21 @@ archs4x, archs4xd, archs4xd_slow"
 ;; SI <- SI * SI
 
 (define_expand "mulsi3"
- [(set (match_operand:SI 0 "nonimmediate_operand""")
+ [(set (match_operand:SI 0 "register_operand""")
(mult:SI (match_operand:SI 1 "register_operand"  "")
 (match_operand:SI 2 "nonmemory_operand" "")))]
-  ""
+  "TARGET_ANY_MPY"
 {
-  if (TARGET_MPY)
-{
-  if (!register_operand (operands[0], SImode))
-   {
- rtx result = gen_reg_rtx (SImode);
-
- emit_insn (gen_mulsi3 (result, operands[1], operands[2]));
- emit_move_insn (operands[0], result);
- DONE;
-   }
-}
-  else if (TARGET_MUL64_SET)
+  if (TARGET_MUL64_SET)
 {
- rtx tmp = gen_reg_rtx (SImode);
- emit_insn (gen_mulsi64 (tmp, operands[1], operands[2]));
- emit_move_insn (operands[0], tmp);
+ emit_insn (gen_mulsi64 (operands[0], operands[1], operands[2]));
  DONE;
 }
   else if (TARGET_MULMAC_32BY16_SET)
 {
- rtx tmp = gen_reg_rtx (SImode);
- emit_insn (gen_mulsi32x16 (tmp, operands[1], operands[2]));
- emit_move_insn (operands[0], tmp);
+ emit_insn (gen_mulsi32x16 (operands[0], operands[1], operands[2]));
  DONE;
 }
-  else
-{
-  emit_move_insn (gen_rtx_REG (SImode, R0_REG), operands[1]);
-  emit_move_insn (gen_rtx_REG (SImode, R1_REG), operands[2]);
-  emit_insn (gen_mulsi3_600_lib ());
-  emit_move_insn (operands[0], gen_rtx_REG (SImode, R0_REG));
-  DONE;
-}
 })
 
 (define_insn_and_split "mulsi32x16"
@@ -2229,27 +2206,6 @@ archs4x, archs4xd, archs4xd_slow"
(set_attr "predicable" "yes,yes,no,yes")
(set_attr "cond" "canuse,canuse,canuse_limm,canuse")])
 
-; If we compile without an mul option enabled, but link with libraries
-; for a mul option, we'll see clobbers of multiplier output registers.
-; There is also an implementation using norm that clobbers the loop registers.
-(define_insn "mulsi3_600_lib"
-  [(set (reg:SI R0_REG)
-   (mult:SI (reg:SI R0_REG) (reg:SI R1_REG)))
-   (clobber (reg:SI RETURN_ADDR_REGNUM))
-   (clobber (reg:SI R1_REG))
-   (clobber (reg:SI R2_REG))
-   (clobber (reg:SI R3_REG))
-   (clobber (reg:DI MUL64_OUT_REG))
-   (clobber (reg:SI LP_COUNT))
-   (clobber (reg:SI LP_START))
-   (clobber (reg:SI LP_END))
-   (clobber (reg:CC CC_REG))]
-  "!TARGET_ANY_MPY
-   && SFUNC_CHECK_PREDICABLE"
-  "*return arc_output_libcall (\"__mulsi3\");"
-  [(set_attr "is_sfunc" "yes")
-   (set_attr "predicable" "yes")])
-
 (define_insn_and_split "mulsidi_600"
   [(set (match_operand:DI 0 "register_operand"   
"=c, c,c,  c")
(mult:DI (sign_extend:DI (match_operand:SI 1 "register_operand"  
"%Rcq#q, c,c,  c"))
@@ -2504,48 +2460,6 @@ archs4x, archs4xd, archs4xd_slow"
(set_attr "predicable" "yes,no,yes,no")
(set_attr "cond" "canuse,nocond,canuse,nocond")])
 
-; Implementations include additional labels for umulsidi3, so we got all
-; the same clobbers - plus one for the result low part.  */
-(define_insn "umulsi3_highpart_600_lib_le"
-  [(set (reg:SI R1_REG)
-   (truncate:SI
-(lshiftrt:DI
- (mult:DI (zero_extend:DI (reg:SI R0_REG))
-  (zero_extend:DI (reg:SI R1_REG)))
- (const_int 32
-   (clobber (reg:SI RETURN_ADDR_REGNUM))
-   (clobber (reg:SI R0_REG))
-   (clobber (reg:DI R2_REG))
-   (clobber (reg:SI R12_REG))
-   (clobber (reg:DI MUL64_OUT_REG))
-   (clobber (reg:CC CC_REG))]
-  "!TARGET_BIG_ENDIAN
-   && !TARGET_ANY_MPY
-   && SFUNC_CHECK_PREDICABLE"
-  "*return arc_output_libcall (\"__umulsi3_highpart\");"
-  [(set_attr "is_sfunc" "yes")
-   (set_attr "predicable" "yes")])
-
-(define_insn "umulsi3_highpart_600_lib_be"
-  [(set (reg:SI R0_REG)
-   

[PATCH 4/6] [ARC] Add peephole rules to combine store/loads into double store/loads

2018-10-10 Thread Claudiu Zissulescu
Simple peephole rules which combines multiple ld/st instructions into
64-bit load/store instructions. It only works for architectures which
are having double load/store option on.

gcc/
Claudiu Zissulescu  

* config/arc/arc-protos.h (gen_operands_ldd_std): Add.
* config/arc/arc.c (operands_ok_ldd_std): New function.
(mem_ok_for_ldd_std): Likewise.
(gen_operands_ldd_std): Likewise.
* config/arc/arc.md: Add peephole2 rules for std/ldd.
---
 gcc/config/arc/arc-protos.h |   1 +
 gcc/config/arc/arc.c| 163 
 gcc/config/arc/arc.md   |  67 +++
 3 files changed, 231 insertions(+)

diff --git a/gcc/config/arc/arc-protos.h b/gcc/config/arc/arc-protos.h
index 24bea6e1efb..55f8ed4c643 100644
--- a/gcc/config/arc/arc-protos.h
+++ b/gcc/config/arc/arc-protos.h
@@ -46,6 +46,7 @@ extern int arc_return_address_register (unsigned int);
 extern unsigned int arc_compute_function_type (struct function *);
 extern bool arc_is_uncached_mem_p (rtx);
 extern bool arc_lra_p (void);
+extern bool gen_operands_ldd_std (rtx *operands, bool load, bool commute);
 #endif /* RTX_CODE */
 
 extern unsigned int arc_compute_frame_size (int);
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 18dd0de6af7..9bc69e9fbc9 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -10803,6 +10803,169 @@ arc_cannot_substitute_mem_equiv_p (rtx)
   return true;
 }
 
+/* Checks whether the operands are valid for use in an LDD/STD
+   instruction. Assumes that RT, RT2, and RN are REG.  This is
+   guaranteed by the patterns. Assumes that the address in the base
+   register RN is word aligned. Pattern guarantees that both memory
+   accesses use the same base register, the offsets are constants
+   within the range, and the gap between the offsets is 4.  If preload
+   complete then check that registers are legal.  WBACK indicates
+   whether address is updated. */
+
+static bool
+operands_ok_ldd_std (rtx rt, rtx rt2, rtx rn ATTRIBUTE_UNUSED,
+   HOST_WIDE_INT offset)
+{
+  unsigned int t, t2;
+
+  if (!reload_completed)
+return true;
+
+  if (!(SMALL_INT_RANGE (offset, (GET_MODE_SIZE (DImode) - 1) & -4,
+(offset & (GET_MODE_SIZE (DImode) - 1) & 3
+ ? 0 : -(-GET_MODE_SIZE (DImode) | -4) >> 1
+return false;
+
+  t = REGNO (rt);
+  t2 = REGNO (rt2);
+
+  if ((t2 == 63)
+  || (t % 2 != 0)  /* First destination register is not even.  */
+  || (t2 != t + 1))
+  return false;
+
+  return true;
+}
+
+/* Helper for gen_operands_ldd_std.  Returns true iff the memory
+   operand MEM's address contains an immediate offset from the base
+   register and has no side effects, in which case it sets BASE and
+   OFFSET accordingly. */
+
+static bool
+mem_ok_for_ldd_std (rtx mem, rtx *base, rtx *offset)
+{
+  rtx addr;
+
+  gcc_assert (base != NULL && offset != NULL);
+
+  /* TODO: Handle more general memory operand patterns, such as
+ PRE_DEC and PRE_INC.  */
+
+  if (side_effects_p (mem))
+return false;
+
+  /* Can't deal with subregs.  */
+  if (GET_CODE (mem) == SUBREG)
+return false;
+
+  gcc_assert (MEM_P (mem));
+
+  *offset = const0_rtx;
+
+  addr = XEXP (mem, 0);
+
+  /* If addr isn't valid for DImode, then we can't handle it.  */
+  if (!arc_legitimate_address_p (DImode, addr,
+   reload_in_progress || reload_completed))
+return false;
+
+  if (REG_P (addr))
+{
+  *base = addr;
+  return true;
+}
+  else if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS)
+{
+  *base = XEXP (addr, 0);
+  *offset = XEXP (addr, 1);
+  return (REG_P (*base) && CONST_INT_P (*offset));
+}
+
+  return false;
+}
+
+/* Called from peephole2 to replace two word-size accesses with a
+   single LDD/STD instruction. Returns true iff we can generate a new
+   instruction sequence.  That is, both accesses use the same base
+   register and the gap between constant offsets is 4. OPERANDS are
+   the operands found by the peephole matcher; OPERANDS[0,1] are
+   register operands, and OPERANDS[2,3] are the corresponding memory
+   operands.  LOAD indicates whether the access is load or store.  */
+
+bool
+gen_operands_ldd_std (rtx *operands, bool load, bool commute)
+{
+  int i, gap;
+  HOST_WIDE_INT offsets[2], offset;
+  int nops = 2;
+  rtx cur_base, cur_offset, tmp;
+  rtx base = NULL_RTX;
+
+  /* Check that the memory references are immediate offsets from the
+ same base register.  Extract the base register, the destination
+ registers, and the corresponding memory offsets.  */
+  for (i = 0; i < nops; i++)
+{
+  if (!mem_ok_for_ldd_std (operands[nops+i], _base, _offset))
+   return false;
+
+  if (i == 0)
+   base = cur_base;
+  else if (REGNO (base) != REGNO (cur_base))
+   return false;
+
+  offsets[i] = INTVAL (cur_offset);
+  if